API documentation
Errors and limits
Plan upload capacity, automatic profile thresholds, retries, credits, and error handling.
Error envelope
Every API response includes X-Request-ID. Error bodies include a human-readable message, a machine-readable code, and the request ID you can use for support.
{
"message": "The uploaded file is not supported.",
"code": "validation_failed",
"request_id": "req_01jv2f4v3m8x8r7a1p9d0k2m7q",
"errors": {
"file": ["The file must be a supported document type."]
}
}
HTTP status codes
Handle status codes by category first, then branch on the response code when you need specific client behavior.
| Status | Meaning | Client action |
|---|---|---|
401 | Missing or invalid API token. | Create or rotate an account token in the app. |
402 | Extraction mode only: insufficient credits. The document is returned with status blocked. | Top up credits or enable auto top-up, then retry the extraction upload. Thumbnail mode does not use extraction credits. |
403 | The token cannot access the resource or lacks the required ability. | Use a token from the correct account with the required access. |
404 | The resource does not exist or is outside the account. | Check the ID and account context. |
409 | The same Idempotency-Key is still processing or was reused with a different payload, including a different processing mode. | Wait for the original request or use a new key for a different upload. |
422 | The request did not pass validation. | Fix field errors and submit again. |
429 | Token, account, user, IP, or sandbox limit exceeded. | Wait for the full Retry-After period. When retrying an upload, keep the same Idempotency-Key. |
Credit blocking
Live extraction-mode uploads reserve one credit before extraction work is queued. This still applies when allow_ai_processing=false, because that field disables AI only. If the account has no available credits, exdata returns 402, marks the document as blocked, and does not dispatch extraction jobs.
processing_mode=thumbnail does not reserve or spend an extraction credit, trigger auto top-up, or create an extraction run. A live thumbnail upload can therefore return 201 when the account has zero extraction credits.
A blocked extraction document keeps the uploaded document record and debugging context. Resolve credits, then retry the upload with a new idempotency key if you want to process it.
Rate limits
API requests are limited across several time windows. Authenticated requests can be limited by API token or workspace, test-mode uploads can also be limited by user, and anonymous routes can be limited by IP address. A request must remain within every policy that applies to it.
Upload capacity
Live and test-mode uploads use the workspace's effective profile. Every upload must remain within all five limits in its profile.
| Profile | Per API token | Across the workspace |
|---|---|---|
restricted |
30 / minute 300 / hour |
60 / minute 600 / hour 1,000 / day |
standard |
120 / minute 1,500 / hour |
240 / minute 3,000 / hour 25,000 / day |
trusted |
240 / minute 5,000 / hour |
480 / minute 10,000 / hour 100,000 / day |
high_volume |
600 / minute 20,000 / hour |
1,200 / minute 40,000 / hour 500,000 / day |
enterprise |
1,200 / minute 60,000 / hour |
2,400 / minute 120,000 / hour 2,000,000 / day |
standard is the current default production profile. restricted is the configured safety profile used while a workspace requires review. enterprise capacity is approved manually for contract-specific workloads. Every workspace member can see the workspace's effective profile and current upload capacity on the API tokens page.
Automatic profile thresholds
trusted and high_volume are evaluated automatically. The workspace must meet every requirement in the target row and have no active payment, security, or abuse review.
| Next profile | Verified paid credits | Paid credits consumed | Workspace age | First verified payment age |
|---|---|---|---|---|
trusted |
≥ 100 | ≥ 50 | ≥ 1 day | ≥ 1 day |
high_volume |
≥ 2,000 | ≥ 1,000 | ≥ 14 days | ≥ 7 days |
Verified paid credits come from completed paid top-ups that remain valid. Refunded, disputed, or revoked purchases stop counting. Paid credits consumed counts usage backed by those purchases after trial, promotional, and other non-paid credits have been consumed.
Relevant payment and credit activity queues a profile check, and recurring reconciliation scans run every five minutes. The minimum gap between routine evaluations is currently 5 minutes. Once every requirement is met and the workspace is in good standing, the new limits apply immediately after the next eligible evaluation. This is normally within a few minutes.
A review can pause an increase or temporarily apply the configured safety profile, restricted. Invalidated paid usage can also reduce an automatic profile. Enterprise capacity is reviewed manually; contact support when the published high-volume profile does not cover your workload.
Other API limits
Reads, deletes, test-mode uploads, and anonymous x402 routes use these additional limits. Test-mode uploads must satisfy both their upload profile and the daily sandbox limits.
| Request | Token limit | Workspace limit | Additional limit |
|---|---|---|---|
| Authenticated reads | 300 / minute | 1,000 / minute | — |
| Document deletes | 60 / minute | 300 / minute | — |
| Test-mode uploads | 10 / day | 25 / day | 50 / user / day |
| Anonymous x402 uploads | — | — | 20 / IP / minute |
| Anonymous x402 status checks | — | — | 120 / IP / minute |
Response headers
A rate-limited response uses status 429. The headers identify the policy that rejected the request and when it can be retried.
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Maximum requests allowed by the reported policy. |
X-RateLimit-Remaining | Requests remaining in the reported window. This is 0 when the request is rejected. |
Retry-After | Number of seconds to wait before retrying. Treat this value as authoritative. |
X-RateLimit-Reset | Unix timestamp in seconds when the reported window resets. |
X-RateLimit-Profile | Effective account profile. It may be absent for anonymous IP-scoped limits. |
X-RateLimit-Scope | Policy scope: token, account, user, or ip. |
X-RateLimit-Window | Policy window: minute, hour, or day. |
Responses with code rate_limited repeat these details as rate_limit_profile, rate_limit_scope, rate_limit_window, rate_limit_limit, and retry_after in the JSON body. Test-mode daily limits use code test_mode_limit_exceeded, include their account, user, and token limits, and include the same retry_after delay as the Retry-After header.
Delay the queue job for at least Retry-After seconds. Retry the same logical upload with the same Idempotency-Key, file, form fields, and processing mode so a network retry cannot create duplicate processing or charges.