> ## Documentation Index
> Fetch the complete documentation index at: https://docs.parserouter.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> The status codes ParseRouter returns and how to handle them.

ParseRouter uses standard HTTP status codes. A `2xx` status means success; `4xx` means a problem with the request you can fix; `5xx` means a problem on our side that's usually safe to retry.

## Error format

Every error response has the same JSON shape:

```json theme={null}
{
  "detail": "Document has 142 pages; the maximum is 100 pages per document."
}
```

The `detail` field is a human-readable description of what went wrong.

## Status codes

| Status | Meaning                                                              |
| ------ | -------------------------------------------------------------------- |
| `400`  | The uploaded file is not a valid PDF or image.                       |
| `401`  | The API key is missing, malformed, invalid, or revoked.              |
| `402`  | Not enough credits to parse the document.                            |
| `413`  | The document exceeds the 100-page limit.                             |
| `422`  | The request is malformed — for example, the `file` field is missing. |
| `429`  | Rate limit exceeded (10 requests per minute per organization).       |
| `503`  | The parsing backend is temporarily overloaded or unavailable.        |

## Handling errors

### Don't retry — fix the request

`400`, `401`, `402`, `413`, and `422` indicate something about the request that won't change on retry. Resolve the underlying cause instead:

* **`400`** — confirm the file is a supported, uncorrupted PDF or image.
* **`401`** — send a valid `Authorization: Bearer sk-pr-...` header.
* **`402`** — [top up your credits](/billing).
* **`413`** — split the document into files of 100 pages or fewer.
* **`422`** — check you're sending `multipart/form-data` with a `file` field.

### Safe to retry

`429` and `503` are temporary. Both include a `Retry-After` header (in seconds) indicating how long to wait before trying again:

* **`429`** — you're sending requests too quickly. Wait for `Retry-After`, then retry. Add exponential backoff for production traffic.
* **`503`** — the backend is briefly saturated. Wait for `Retry-After` and retry. No credits are charged for a `503`.

<Note>
  Failed requests never consume credits — you're only charged when a parse succeeds with a `200`.
</Note>
