For the complete documentation index, see llms.txt. This page is also available as Markdown.

Errors

What each status code means, and which failures are worth retrying.

The API uses conventional HTTP status codes, with two exceptions that matter enough to lead with: some endpoints return 500 for input you got wrong, and GET /generate/{_id} returns 500 for an ID that simply does not exist. Neither is a server fault you should retry.

Status codes

Code
Meaning
Retry?

200

Success. For async submissions this means accepted, not finished

201

Created — returned by POST /generate

202

Accepted — returned by POST /extract for a multi-extraction (documentTypes) request

400

The request body is missing or invalid

No — fix the request

401

Missing, invalid, expired or revoked API key

No — fix the credential

404

No record with that ID

No

500

Usually a genuine server error — but see below

Sometimes

Success codes vary with the request, not only with the endpoint — POST /extract answers 200 for a single document and 202 for a multi-extraction. Accept any 2xx rather than testing for one value.

The 500 responses that are not server errors

Four endpoints return 500 where 400 belongs, when the request body is missing or malformed:

  • POST /extract

  • POST /extract/sync

  • POST /classify

  • POST /classify/sync

Their bulk counterparts (/extract/bulk, /classify/bulk) and both generation endpoints correctly return 400 for the same mistake.

GET /generate/{_id} returns 500 for every input

Not only for unknown IDs. Tested with the exact generationId returned by POST /generate, a hyphen-stripped form, a prefixed form and a nil UUID — all four return:

There is no ID format that succeeds, so the endpoint is currently unusable. The comparable GET /document-extractions/{id} and GET /classifications/{id} both work and return a correct 404 for an unknown ID.

To collect a generated document, use POST /generate/sync — which returns the file directly — or set webhookUrl on the async request and take downloadUrl from the completion payload. See Generate a document.

These are known defects and have been raised. They are documented here because they are the current behaviour, not because they are intended.

Error bodies

Authentication failures return a flat object:

Validation failures return a JSON array of Pydantic validation errors, not an object:

The most useful fields are loc — the path to the offending property — and msg.

A job that fails is not a request that failed

Asynchronous work has two independent outcomes, and conflating them is a common mistake.

HTTP status

Whether the API accepted your call

documentStatus / status

Whether the document processed successfully

POST /extract returning 200 means the job is queued. The document can still end at Failed. Always check the job status when you retrieve the record — see Conventions for the lifecycle and the envelope trap that goes with it.

Retry guidance

Situation
Do

401

Stop. Check the key's expiry and revocation state

400, or a 500 from one of the four endpoints above

Stop. Fix the payload

404

Stop, unless you are racing a just-submitted job

500 elsewhere, or a network timeout

Retry with exponential backoff, and cap the attempts

Job status Failed

Do not resubmit blindly — inspect the record first; a document that cannot be read will fail again

For webhook delivery retries, which follow different rules, see Webhook payloads.

What the spec says about errors

The OpenAPI document describes only 200/201 and 400. It documents no 401 — despite that being reachable on thirteen of fourteen operations — no 404, and no 5xx. POST /generate/sync has no documented responses at all.

The table at the top of this page comes from testing every operation against the live API, not from the spec.

  • Authentication — the cause of most 401s.

  • Conventions — envelopes, the status lifecycle, and the unenforced request rules that cause 400s.

  • Webhook payloads — delivery retries and their own backoff schedule.

Last updated