Every endpoint of the Foxello integration API - the API behind the Zapier app, the n8n node, and your own HTTP steps. For setting up integrations and connecting your tool, see Zapier and n8n.
Basics
Base URL: https://api.foxello.com/api/v1
Authentication: send the integration's connection key with every request:
Authorization: Bearer fxk_...
Create a connection key under Integrations in the sidebar (Owners and Admins). A key only reaches the workflows that selected its integration as their import method or export destination.
Format: requests and responses are JSON unless noted. Dates are ISO 8601 in UTC, for example 2026-10-12T10:00:00.000Z.
Rate limit: 300 requests per minute per connection key. Above that, the API answers 429 with a Retry-After header (seconds to wait).
Plans: the integration API is available on every plan. Excel results (format=xlsx) need the Growth or Scale plan.
Errors
Errors are returned with an HTTP status and a JSON body:
{
"message": "Invalid or revoked connection key.",
"code": "API-KEY-02",
"status": 401
}
Errors every endpoint can return:
401API-KEY-01- no connection key was sent.401API-KEY-02- the connection key is invalid, regenerated, or its integration was removed.403API-PLAN-01- integrations are not available for the account's subscription.429SEC-RATE-01- rate limit reached. Retry after theRetry-Afterseconds.
Endpoint-specific errors are listed with each endpoint.
Connection
Test the connection
GET /me
Returns the account and integration the connection key belongs to.
Response 200:
{
"accountId": "6a1f2763e4b82c58360f9700",
"accountName": "Acme Logistics",
"integration": {
"id": "6a1f2763e4b82c58360f9701",
"name": "Accounts payable Zaps",
"type": "zapier"
}
}
integration.type is zapier or n8n.
Workflows
List workflows
GET /workflows
Lists the workflows connected to this integration.
Query parameters:
purpose(optional) -importreturns workflows that accept documents from this integration;exportreturns workflows that send their results to it. Leave it out to get both.
Response 200:
[
{
"id": "6a1f2763e4b82c58360f9702",
"name": "Invoices",
"acceptsDocuments": true,
"sendsResults": true
}
]
acceptsDocuments- documents can be sent to this workflow with this connection key.sendsResults- this workflow's results are sent to this integration.
List the fields a workflow extracts
GET /workflows/{workflowId}/fields
The fields each document type of the workflow returns, in the same docType / attribute structure as a document's fields. Use it to map fields before any document has been processed.
Response 200:
{
"workflowId": "6a1f2763e4b82c58360f9702",
"docTypes": [
{
"docType": "invoice",
"fields": [
{
"attribute": "InvoiceTotal",
"type": "currency",
"description": "Total amount due",
"example": "1,250.00",
"fields": []
},
{
"attribute": "Items",
"type": "array",
"fields": [
{ "attribute": "Description", "type": "string", "fields": [] },
{ "attribute": "Amount", "type": "currency", "fields": [] }
]
}
]
}
]
}
fieldsinside a field holds its sub-fields, for example the columns of a line-item table.descriptionandexampleare present when the workflow defines them.docTypesis empty when the workflow only reads text.
Errors:
404WF-NF-01- the workflow does not exist or is not connected to this integration.
Sending documents
Supported file types are PDF, JPG, JPEG, and PNG, unless the workflow allows fewer. The file type is checked from the file's content, not only its name.
Send a document
POST /workflows/{workflowId}/documents
Sends one document to the workflow for processing. Send either:
- a file as
multipart/form-datain the fieldfile- up to 5 MB, or - JSON
{ "url": "https://..." }- Foxello downloads the file from the link, up to 100 MB. Redirects are followed. The link must be a public address.
For files over 5 MB that you have as bytes rather than a link, use the upload URL flow.
Headers:
Idempotency-Key(optional) - a unique value per document, 1 to 255 visible ASCII characters without spaces, for example your run or record ID. Sending the same key again within 24 hours returns the document created by the first request instead of creating a second one. A key belongs to one workflow.
Response 202: the new document. Processing continues in the background.
{
"id": "6a1f2763e4b82c58360f9703",
"name": "invoice-1042.pdf",
"status": "pending",
"workflowId": "6a1f2763e4b82c58360f9702",
"workflowName": "Invoices",
"pageCount": 0,
"confidenceScore": 0,
"createdAt": "2026-10-12T10:00:00.000Z",
"updatedAt": "2026-10-12T10:00:00.000Z"
}
Errors:
400API-FILE-01- no file and no URL was sent.400API-FILE-02- the file type is not allowed for this workflow.400API-FILE-03- the URL is invalid or not allowed.400API-FILE-04- the file could not be downloaded from the URL.400API-FILE-05- the file type could not be recognized from its content.400API-UPLOAD-03- the workflow does not accept documents from this integration.400API-UPLOAD-04- theIdempotency-Keyheader is invalid.400API-UPLOAD-05- theIdempotency-Keywas already used for another workflow.404WF-NF-01- the workflow does not exist.409API-UPLOAD-06- a request with the sameIdempotency-Keyis still being received. Retry in a minute.413FILE-UP-SIZE-01- the file is larger than the limit.
Upload a large file
Three steps for files up to 100 MB that you have as bytes.
1. Request an upload URL
POST /workflows/{workflowId}/documents/uploads
Body:
{
"fileName": "contract-scan.pdf",
"fileSize": 48234112
}
fileName- the file name with its extension, up to 255 characters.fileSize- the exact file size in bytes.
Response 201:
{
"uploadId": "6a1f2763e4b82c58360f9704",
"uploadUrl": "https://...",
"method": "PUT",
"headers": { "Content-Length": "48234112" },
"expiresAt": "2026-10-12T10:15:00.000Z"
}
Errors: 400 API-FILE-02, 400 API-UPLOAD-03, 404 WF-NF-01, 413 FILE-UP-SIZE-01 - as above.
2. Upload the bytes
Send the file with an HTTP PUT to uploadUrl, with the returned headers, before expiresAt (15 minutes). Do not send the Authorization header to this URL.
3. Finish the upload
POST /workflows/{workflowId}/documents/uploads/{uploadId}/complete
No body. Starts processing the document.
Response 202: the new document, as in Send a document.
Errors:
400API-UPLOAD-02- the file was not uploaded, or its size does not matchfileSize.404API-UPLOAD-01- the upload does not exist or has expired. Request a new upload URL.
Documents
The document object
{
"id": "6a1f2763e4b82c58360f9703",
"name": "invoice-1042.pdf",
"status": "approved",
"workflowId": "6a1f2763e4b82c58360f9702",
"workflowName": "Invoices",
"pageCount": 2,
"confidenceScore": 0.94,
"createdAt": "2026-10-12T10:00:00.000Z",
"updatedAt": "2026-10-12T10:00:30.000Z",
"fields": {
"fields": [
{
"docType": "invoice",
"fields": [
{
"attribute": "InvoiceId",
"text": "INV-1042",
"type": "string",
"confidence": 0.98,
"fields": []
},
{
"attribute": "Items",
"text": "",
"type": "array",
"fields": [
{ "attribute": "Description", "text": "Packing boxes", "row": 1, "fields": [] },
{ "attribute": "Amount", "text": "250.00", "row": 1, "fields": [] }
]
}
]
}
]
}
}
status-pending,running,paused,processed,awaiting_approval,review,rejected,approved,exported, orfailed. See File statuses.confidenceScore- overall confidence from0to1.fields- the extracted results, present once processing has finished. One entry per document type found, each with its fields:attribute- the field name, as listed by the fields endpoint.text- the value as it appears in the document.value- a normalized value where available, for example a date as2022-10-21or an amount as{ "amount": 17, "currencyCode": "EUR" }.confidence- the field's confidence from0to1.fields- sub-fields. Line-item columns carry arownumber; values with the samerowbelong to one line.- Fields can also carry the position of the value on the page (
zone,words).
List documents
GET /documents
Documents of the workflows connected to this integration, newest first.
Query parameters:
workflowId(optional) - only documents of this workflow.status(optional) -completed,needs_review,failed, orprocessing.limit(optional) - 1 to 50, default 10.
Response 200: an array of document objects.
Errors:
400- an invalidworkflowId,status, orlimit.
Get a document
GET /documents/{documentId}
Response 200: a document object, with fields once processing has finished.
Errors:
404FILE-NF-01- the document does not exist or is not in a connected workflow.
Download the results as a file
GET /documents/{documentId}/results?format=csv
The extracted results of a finished document as a file download.
Query parameters:
format(required) -json,csv, orxlsx(Excel - Growth and Scale plans).
Response 200: the file, with Content-Type application/json, text/csv, or application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, and a Content-Disposition file name such as invoice-1042-results.csv.
Errors:
400-formatis missing or not one of the three.403API-RESULTS-02- the format is not included in the account's plan.404FILE-NF-01- the document does not exist or is not in a connected workflow.409API-RESULTS-01- the results are not ready yet. Wait until the document has finished processing and, if the workflow requires it, has been approved.
Get a link to the original file
GET /documents/{documentId}/original
Response 200:
{
"url": "https://...",
"expiresAt": "2026-10-12T11:00:00.000Z"
}
url downloads the original uploaded file and works for one hour. Do not send the Authorization header to it.
Errors:
404FILE-NF-01- the document does not exist or is not in a connected workflow.
Event subscriptions
Subscribe a URL to receive document events as they happen. The event payload, signature headers, and delivery rules are described in Zapier and n8n - Events.
Subscribe
POST /webhooks
Body:
{
"targetUrl": "https://hooks.example.com/foxello",
"event": "document.completed",
"workflowId": "6a1f2763e4b82c58360f9702"
}
targetUrl- a publichttpsaddress on the standard port (443).event-document.completed,document.needs_review,document.approved, ordocument.failed.workflowId(optional) - only events of this workflow. Leave it out to receive events of every workflow that sends results to this integration.
Response 201:
{
"id": "6a1f2763e4b82c58360f9705",
"event": "document.completed",
"workflowId": "6a1f2763e4b82c58360f9702",
"status": "active",
"createdAt": "2026-10-12T10:00:00.000Z",
"secret": "whsec_..."
}
secret signs every delivery of this subscription. It is returned only here - store it.
Errors:
400WEBHOOK-02- the URL is not allowed.400WEBHOOK-03- the account already has 200 active subscriptions.400- the workflow does not send results to this integration, or the body is invalid.
Get a subscription
GET /webhooks/{subscriptionId}
Response 200:
{
"id": "6a1f2763e4b82c58360f9705",
"event": "document.completed",
"workflowId": "6a1f2763e4b82c58360f9702",
"status": "active",
"createdAt": "2026-10-12T10:00:00.000Z"
}
status is active, or disabled after repeated failed deliveries.
Errors:
404WEBHOOK-01- the subscription does not exist.
Unsubscribe
DELETE /webhooks/{subscriptionId}
Response 200:
{ "deleted": true }
Errors:
404WEBHOOK-01- the subscription does not exist.
A receiver can also unsubscribe by answering a delivery with 410 Gone.