1. Technical Workflow of the Export Process
The finway Expense Export API operates asynchronously across four consecutive phases:
Trigger Export (POST /v1/exports/expenses): Initiates the export job and immediately returns HTTP status 202 Accepted along with an exportId.
Poll Status (GET /v1/exports/expenses/{exportId}): Periodically checks the job status (pending → processing → done or failed).
Retrieve Download URL (GET /v1/exports/expenses/{exportId}/download): Once the status reaches done, this endpoint returns a temporary signed URL.
Fetch File: Downloads the ZIP archive via the signed URL and extracts the contained CSV file.
2. Authentication & Authorization (HTTP 401 & 403)
HTTP 401 Unauthorized – "You are not authorized"
Cause 1: Missing or incorrect Bearer prefix
The API requires the header format Authorization: Bearer <api-key>. If an integration tool passes only the key without the Bearer prefix or uses a generic header name (e.g., finway Auth: ... or x-api-key: ...), access is denied.
Solution: Select Bearer Auth as the authentication method and provide only the key token. If using Header Auth, the header name must be exactly Authorization and the value formatted as Bearer fwk_live_....
Cause 2: Invalid, expired, or truncated API key
The API key must always start with the prefix fwk_live_. Leading or trailing whitespaces inadvertently copied with the key, or using a revoked/outdated key, will cause this error.
Solution: Navigate to finway → System Settings → API Keys, generate a new key, verify its completeness, and paste it without any whitespace.
HTTP 403 Forbidden – "companyId is not in the API key's allowed set"
Cause: Insufficient workspace/tenant permissions
The API key is valid, but it does not have access permissions for the requested companyId, or the company workspace was deactivated/deleted in finway.
Solution: Verify in which organization/tenant the API key was generated. Ensure the key is explicitly authorized for the companyId passed in the request body.
3. Data Validation & Request Body (HTTP 400 & 422)
HTTP 400 Bad Request – "companyId must be a valid id"
Cause: Invalid ID format
The company ID must contain exactly 24 letters or numbers. Using a different format, such as a number-only ID (e.g. 8529374848), will cause an error.
Solution:
Log in to finway in your browser.
Check the URL in the address bar: [https://app.finway.de/company/](https://app.finway.de/company/)<24-character-ID>/....
Copy the Company ID
HTTP 400 Bad Request – Date Validation (from / to)
Cause: Invalid date format
The fields from and to must follow the ISO 8601 calendar date format (YYYY-MM-DD, e.g., "2026-01-01"). Formats such as DD.MM.YYYY, MM/DD/YYYY, or Unix timestamps are rejected.
Solution: Format all date values to YYYY-MM-DD before initiating the API call.
HTTP 400 Bad Request – Invalid exportId During Polling or Download
Cause: The exportId passed in the path parameter does not match the required 24-character hexadecimal format.
Solution: Make sure you pass the exact exportId returned by the POST
HTTP 422 Unprocessable Entity – "Export size limit exceeded"
Cause: Dataset too large
The requested time frame contains too many expense records for a single export run.
Solution: Split the date range into smaller intervals (e.g., monthly or quarterly instead of a full year) and trigger multiple sequential exports.
4. Missing Data & Not Found Resources (HTTP 404)
HTTP 404 on POST /v1/exports/expenses
Cause 1: The company does not exist within the tenant.
Cause 2: No expenses matching the query criteria exist within the selected timeframe (from to to).
Solution: Verify that receipts exist for the specified performance date (datePurchased) inside the finway web portal. If archived receipts should also be exported, add "includeArchived": true to the request body.
HTTP 404 on GET /v1/exports/expenses/{exportId}
Cause: The exportId does not exist or belongs to another tenant or to a company your key has no access to.
Solution: Verify that the ID is passed unmodified from the initial POST call.
HTTP 404 on GET /v1/exports/expenses/{exportId}/download
Cause: Premature download request
The download endpoint was called while the export job was still in pending or processing status. This error can also occur if the export job has failed, as the file is not available for download in either case.
Solution: Only call the download endpoint after the status endpoint explicitly returns status: "done". Implement a conditional branch (e.g., an IF node in n8n) before proceeding to the download step.
5. Concurrency & Rate Limits (HTTP 429)
HTTP 429 on POST /v1/exports/expenses – Concurrent Export
Cause: Only one export job can be active at a time for a given companyId. Starting a second export while a previous one is still running triggers an HTTP 429 response.
Solution:
Inspect and respect the Retry-After response header.
Ensure automation workflows for the same company run strictly sequentially rather than in parallel.
HTTP 429 on Status or Download Endpoints – Polling Rate Limit
Cause: Polling is limited to a maximum of 1 request per second per tenant (shared across status and download endpoints).
Solution:
Configure your polling interval to at least 5 seconds (e.g., via a Wait node).
If an HTTP 429 error occurs, pause execution for the duration specified in the Retry-After header.
6. Download & File Processing Errors
Download Errors via downloadUrl (S3 / Cloud Storage)
Problem 1: Authorization header sent with file download
If the finway Bearer token is included when requesting the downloadUrl, the cloud storage service will reject the request.
Solution: Execute the download request as a standard GET request without an Authorization header. The signed URL already embeds temporary access credentials.
Problem 2: Expired signed URL
The URL provided by /download has a limited validity period (expiresAt).
Solution: Download the file immediately after retrieving the URL. If delays occur, call the /download endpoint again to generate a fresh URL.
Parsing Error: "Invalid CSV"
Cause: The API does not return raw CSV text at the download URL; it delivers a compressed ZIP archive (finwayExport_<timestamp>.zip) containing the CSV file.
Solution: Pass the downloaded binary data through a decompress/unzip step in your workflow before passing the extracted file to your CSV parser.
7. Asynchronous Processing Failures (Status: Failed)
If the status endpoint returns 200 OK but the response payload contains "status": "failed", the export failed on the server side:
JSON
{j
"exportId": "507f1f77bcf86cd799439012",
"status": "failed",
"createdAt": "2026-06-12T10:00:00.000Z",
"error": "Export failed"
}
Solution:
Log the error field from the JSON response.
Retry the export with a narrower date range.
If the failure persists, contact finway support and provide the exportId along with the timestamp.
8. HTTP Status Code Reference
Status Code | Endpoint | Common Cause | Resolution |
202 Accepted | POST /v1/exports/expenses | Export started successfully. | Store exportId and begin status polling. |
400 Bad Request | All | Invalid parameters (e.g., companyId is not a 24-character hex ID, incorrect date format). | Validate input values against the schema (ISO 8601 date, 24-char hex ObjectId). |
401 Unauthorized | All | Missing header, missing Bearer prefix, or invalid/expired API key. | Verify Authorization: Bearer fwk_live_.... |
403 Forbidden | POST /v1/exports/expenses | API key lacks permission for the specified companyId. | Generate the key in the correct tenant or check company workspace permissions. |
404 Not Found | POST /v1/exports/expenses | No expenses found in the specified timeframe. | Adjust the date filter or set "includeArchived": true. |
404 Not Found | GET .../download | Export is still in progress (pending or processing). | Only call /download once status polling returns done. |
422 Unprocessable Entity | POST /v1/exports/expenses | Export size limit exceeded. | Narrow the date range (e.g., query monthly instead of yearly). |
429 Too Many Requests | POST /v1/exports/expenses | An export is already running for this company. | Wait until the running job finishes (check Retry-After). |
429 Too Many Requests | GET (Status / Download) | Polling rate limit exceeded (> 1 request/second). | Increase polling interval to at least 5 seconds. |
