API import lets your application upload documents directly into a workflow. It is available on Growth and Scale plans.
When to use it
- Your product needs to submit documents automatically
- You want server-side control over upload timing and retries
- You need status polling and download access through the same workflow token
Configure after creation
The Add Workflow wizard only selects API Import. You must generate and store the token after the workflow is created:
- Go to Workflows.
- Find the workflow.
- Open the Actions menu (three dots).
- Click Edit.
- Open the Import tab.
- Confirm Import Method is API Import.
- Click Generate API token.
- Copy and store the token immediately.
- Set Attachment types.
- Click Save Changes.
Production endpoints
Use these production endpoints:
| Endpoint | Method | URL |
|---|---|---|
| Upload | POST |
https://api.foxello.com/api/v1/file/upload |
| Status | GET |
https://api.foxello.com/api/v1/file/status/{fileId} |
| Download | GET |
https://api.foxello.com/api/v1/file/download/{fileId} |
Use the file ID returned by the upload response for status and download calls.
Authentication
Use the generated token with one of these headers:
Authorization: Bearer <token>X-API-Token: <token>
The token belongs to one workflow. Any file uploaded with it is processed by that workflow.
Upload format
There are two ways to send a document to the upload endpoint.
Option 1: Send the file directly
Send files as multipart/form-data with a field named file.
Maximum file size is 5MB per upload.
curl -X POST "https://api.foxello.com/api/v1/file/upload" \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "file=@document.pdf"
Option 2: Send a URL to fetch
If your document is already hosted somewhere reachable over the internet, send its URL instead of the file itself. Use a JSON body with a url field:
curl -X POST "https://api.foxello.com/api/v1/file/upload" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/document.pdf"}'
The file is downloaded and streamed directly into the workflow, so it isn't limited by the multipart upload size. Maximum size is 100MB per upload.
The URL must be a public http or https address with no username/password in it, and must not redirect. URLs pointing at a private, internal, or loopback address are rejected. The URL doesn't need to end in a file extension - the file's type is detected from its content after downloading, not from the URL.
Successful uploads (either option) return 202 Accepted with file metadata. Processing continues in the background.
File type detection
The accepted document types are set in Attachment types on the Import tab. Whether you send a file directly or a URL, the type is determined by reading the file's actual content - never by trusting a filename or a URL's path - so a mislabeled or extension-less file is identified correctly rather than rejected or misprocessed.
Token safety
The token is shown only once when generated.
- Store it in a secure secret store.
- Do not commit it to source control.
- Regenerate it if exposed.
- Update all clients after regenerating, because the previous token is revoked.
Attachment types
Set accepted file types in the Import tab. Uploads with unsupported file types are rejected.
JavaScript example
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
const token = process.env.FOXELLO_API_TOKEN;
const form = new FormData();
form.append('file', fs.createReadStream('document.pdf'), 'document.pdf');
const upload = await axios.post(
'https://api.foxello.com/api/v1/file/upload',
form,
{
headers: {
Authorization: `Bearer ${token}`,
...form.getHeaders(),
},
},
);
const fileId = upload.data.id;
const status = await axios.get(
`https://api.foxello.com/api/v1/file/status/${fileId}`,
{
headers: {
Authorization: `Bearer ${token}`,
},
},
);
console.log(status.data);
To send a URL instead of the file itself, POST a JSON body instead of a form:
const upload = await axios.post(
'https://api.foxello.com/api/v1/file/upload',
{ url: 'https://example.com/document.pdf' },
{
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
},
);
Python example
import os
import requests
token = os.environ["FOXELLO_API_TOKEN"]
with open("document.pdf", "rb") as document:
upload = requests.post(
"https://api.foxello.com/api/v1/file/upload",
headers={"Authorization": f"Bearer {token}"},
files={"file": document},
timeout=60,
)
upload.raise_for_status()
file_id = upload.json()["id"]
status = requests.get(
f"https://api.foxello.com/api/v1/file/status/{file_id}",
headers={"Authorization": f"Bearer {token}"},
timeout=30,
)
status.raise_for_status()
print(status.json())
To send a URL instead of the file itself, POST a JSON body instead of a form:
upload = requests.post(
"https://api.foxello.com/api/v1/file/upload",
headers={"Authorization": f"Bearer {token}"},
json={"url": "https://example.com/document.pdf"},
timeout=30,
)
Download example
Download only after the file reaches processed, approved, or exported status.
curl -X GET "https://api.foxello.com/api/v1/file/download/FILE_ID" \
-H "Authorization: Bearer YOUR_TOKEN" \
--output result
See API Integration for the full upload, status, and download workflow.