> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.emtelligent.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.emtelligent.com/_mcp/server.

# Errors

## Error responses

Every error response has the same shape:

```json
{
  "error": {
    "code": "invalid_credentials",
    "message": "invalid credentials",
    "request_id": "req_3b1f0c9e8d7a6b5c"
  }
}
```

Branch on `code`, which is stable. `message` is for people and may change. The
`request_id` is also returned in the `X-Request-Id` header; quote it when
contacting support.

| HTTP | `code`                                                                                                      | Meaning and what to do                                                                 |
| ---- | ----------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| 400  | `invalid_document`, `invalid_questionnaire`, `invalid_questions`, `invalid_json`, `invalid_idempotency_key` | The request is malformed. Fix it before retrying                                       |
| 400  | `invalid_callback_url`, `callback_not_allowed`, `callback_not_configured`                                   | See [Webhooks](/formfill/guides/webhooks)                                              |
| 401  | `invalid_credentials`                                                                                       | The key is missing, unknown, expired or revoked, or lacks the `formfill:process` scope |
| 402  | `organization_suspended`                                                                                    | The organization is suspended or out of credit. See [Billing](/platform/billing)       |
| 404  | `not_found`                                                                                                 | No such job for your organization, or it has expired                                   |
| 409  | `idempotency_conflict`                                                                                      | That `Idempotency-Key` was already used with a different body                          |
| 409  | `not_ready`                                                                                                 | The result was requested before the job finished                                       |
| 409  | `no_result`                                                                                                 | The job failed or was canceled, so there is no result                                  |
| 410  | `result_expired`                                                                                            | The result was already downloaded                                                      |
| 413  | `document_too_large`, `questionnaire_too_large`, `too_many_questions`, `payload_too_large`                  | Over a [limit](/formfill/reference/limits)                                             |
| 422  | `request_validation`                                                                                        | A field has the wrong shape, or is not recognised. The message names the fields        |
| 429  | `rate_limited`                                                                                              | Over a rate or concurrency limit. Wait for the `Retry-After` seconds                   |
| 503  | `temporarily_unavailable`                                                                                   | Retry with backoff                                                                     |

## Failed jobs

A job can fail after it was accepted. Its status is then `failed`, with a code:

```json
{ "id": "job_8f2c1d0e9b7a6c5d4e3f2a1b", "status": "failed",
  "error": { "code": "input_too_large" }, … }
```

| `error.code`                                                                              | Meaning and what to do                                                                                                                                               |
| ----------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `insufficient_credit`                                                                     | The organization does not have enough credit for this job                                                                                                            |
| `input_too_large`                                                                         | The document and the Questionnaire are read together, and together they are too large. Split the document or the Questionnaire and submit the parts as separate jobs |
| `processing_timeout`, `processing_unavailable`, `processing_error`, `billing_unavailable` | A problem on our side. Resubmit, with the same `Idempotency-Key`                                                                                                     |

A job we cancel ourselves, for operational reasons, has status `canceled` and
the code `canceled_by_operator` rather than `failed`. Resubmit it.

A code from the table above can also arrive this way, when the condition is only
detected once processing starts rather than at submission.

New codes may be added. Treat an unrecognised code as a problem on our side.

## Retrying safely

Send an `Idempotency-Key` header, of your choosing, with every submission:

```
Idempotency-Key: order-1234
```

Resubmitting with the same key and the same body returns the original job, with
`200` rather than `202`, instead of creating, and charging for, a second job. The
same key with a different body is rejected with `409 idempotency_conflict`. Keys
are scoped to your organization and remembered for 24 hours.

Retry `429` and `503` responses, and network errors, with exponential backoff.
Do not retry other `4xx` responses unchanged: they will fail the same way.