# Errors
URL: https://docs.munito.ai/errors

The Munito AI API returns errors in the body format of the API that you call: the OpenAI error body on Chat Completions and Responses, the Anthropic error body on Messages, and an RFC 9457 problem document on OCR.
Retry `429` (except a spend limit), `502` and `503` after the `Retry-After` time. Fix the request for each other `4xx`.

## Error bodies [#error-bodies]

| API                  | Paths                                                                 | Body                                                                                             |
| -------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| OpenAI               | `/chat/completions`, `/responses`, `/audio/transcriptions`, `/models` | `{"error": {"message", "type", "param", "code"}}`                                                |
| Anthropic            | `/messages`, `/messages/count_tokens`                                 | `{"type": "error", "error": {"type", "message"}, "request_id"}`                                  |
| Munito AI (RFC 9457) | `/ocr`, and a path outside these APIs                                 | `{"type", "title", "status", "instance", "detail", "request_id"}`, as `application/problem+json` |

The same invalid key on each API:

```json
{ "error": { "message": "Invalid API key", "type": "invalid_request_error", "param": null, "code": "invalid_api_key" } }
```

```json
{
  "type": "error",
  "error": { "type": "authentication_error", "message": "Invalid API key" },
  "request_id": "01a165c1-e56d-7204-a1fc-9e2d2a3a7d8f"
}
```

```json
{
  "type": "about:blank",
  "title": "Unauthorized",
  "status": 401,
  "instance": "/inference/v1/ocr",
  "detail": "Invalid API key",
  "request_id": "01a165c1-e767-7e9e-9e97-25481f5db3bd"
}
```

Each answer names its request id: the `x-request-id` header on the OpenAI and OCR APIs, and the `request-id` header on Messages. Give it to Support when you ask about a request.
The OpenAI and Anthropic APIs answer a request that fails validation with `400`. The OCR API answers `422`.

## Error catalog [#error-catalog]

| Status | Message                                                                                      | Cause                                                                                                | Fix                                                                                                           | Retry |
| ------ | -------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ----- |
| `400`  | `The body must be valid JSON.`                                                               | The body does not parse.                                                                             | Send valid JSON.                                                                                              | No    |
| `400`  | `messages must be a non-empty list`                                                          | Chat Completions without `messages`.                                                                 | Send at least one message.                                                                                    | No    |
| `400`  | `max_tokens is required (a positive integer)`                                                | Messages without `max_tokens`.                                                                       | Send `max_tokens`.                                                                                            | No    |
| `400`  | `unknown parameter: 'foo'`                                                                   | A field that the API does not know.                                                                  | Remove the field.                                                                                             | No    |
| `400`  | `'audio' is not supported: audio output is not available; text generation only`              | A field that Munito AI does not support. The text names the field and the reason.                    | Remove the field.                                                                                             | No    |
| `400`  | `temperature exceeds the model limit`                                                        | A sampling value outside the range of the model.                                                     | Use a value in the range on the [model page](https://docs.munito.ai/models).                                              | No    |
| `400`  | `This model's maximum context length is N tokens. Please reduce the length of the messages.` | The prompt and `max_tokens` are larger than the context. Code `context_length_exceeded`.             | Shorten the prompt, or lower `max_tokens`.                                                                    | No    |
| `400`  | `munito-service-tier must be priority, standard, or flex.`                                   | An unknown value in the `munito-service-tier` header.                                                | Send `priority`, `standard` or `flex`.                                                                        | No    |
| `400`  | `service_tier must be auto, default, flex, or priority.`                                     | An unknown value in the `service_tier` field.                                                        | Send one of these values.                                                                                     | No    |
| `401`  | `Missing API key`                                                                            | No key in `Authorization` or `X-API-Key`.                                                            | Send the key.                                                                                                 | No    |
| `401`  | `Invalid API key`                                                                            | The key is wrong or deleted. Code `invalid_api_key`.                                                 | Check the key in the [console](https://console.munito.ai/keys).                                               | No    |
| `402`  | `Paid access is paused while we review a payment. Contact hello@munito.ai.`                  | A payment review.                                                                                    | Contact us.                                                                                                   | No    |
| `403`  | `The priority tier requires a paid usage tier.`                                              | `priority` on the free tier.                                                                         | Add a payment method, or send `standard`. See [Service tiers](https://docs.munito.ai/service-tiers).                      | No    |
| `403`  | `This API key does not have the inference permission.`                                       | The key has no **Inference** permission.                                                             | Create a key with **Inference**.                                                                              | No    |
| `403`  | `Account is suspended`                                                                       | The account is not active.                                                                           | Contact Support in the console.                                                                               | No    |
| `403`  | `Phone verification required`                                                                | The account has no verified phone number.                                                            | Verify your phone in the [console](https://console.munito.ai).                                                | No    |
| `404`  | `The model no/such-model does not exist, or you do not have access to it.`                   | A model id that your key cannot use. Code `model_not_found`.                                         | Use an id from [`GET /models`](https://docs.munito.ai/api/listModels).                                                    | No    |
| `404`  | `No API operation has this path. API paths start with /inference/v1.`                        | A path that does not exist, such as `/embeddings`.                                                   | Check the path in the [API reference](https://docs.munito.ai/api).                                                        | No    |
| `413`  | `request exceeds the maximum size of N bytes`                                                | The request body is too large. Code `request_too_large`.                                             | Send less data, or send large media by URL.                                                                   | No    |
| `413`  | `Document exceeds the configured size limit`                                                 | An OCR document larger than 50 MiB.                                                                  | Split the document.                                                                                           | No    |
| `421`  | `This endpoint cannot serve EUROPE.`                                                         | A regional model id, such as `qwen/qwen3.8-27b@eu`, on the host of another region.                   | Call the host of that region, or the global host.                                                             | No    |
| `421`  | `This workspace stores data in EUROPE. A request that keeps data cannot run in US.`          | OCR or `store: true` on the host of a region that does not hold your data.                           | Use the global host or the host of your data region. See [Regions](https://docs.munito.ai/regions).                       | No    |
| `429`  | `Too Many Requests`, or `Rate limit exceeded and no spare capacity. Retry shortly.`          | Your traffic is above your rate limit, and no spare capacity is free. Code `rate_limit_exceeded`.    | Wait for `Retry-After`. Increase traffic gradually. See [Rate limits](https://docs.munito.ai/rate-limits).                | Yes   |
| `429`  | `The spend limit is reached. Access resumes at ...`                                          | Your organization reached a spend limit. Code `organization_spend_limit_exceeded`. No `Retry-After`. | Raise the limit on the Billing page of the console, or wait for the date.                                     | No    |
| `502`  | `Generation failed before the first token. Retry the request.`                               | The model failed before the answer started.                                                          | Send the request again.                                                                                       | Yes   |
| `503`  | `Service overloaded. Retry shortly.`                                                         | The model has no free capacity now. Code `capacity_exceeded`.                                        | Wait for `Retry-After`. Use the [priority tier](https://docs.munito.ai/service-tiers) or [overflow](https://docs.munito.ai/overflow). | Yes   |
| `503`  | `Service Unavailable`                                                                        | The model cannot serve now. Code `service_unavailable`.                                              | Wait for `Retry-After`.                                                                                       | Yes   |
| `503`  | `Request capacity reached. Retry shortly.`                                                   | The API has too many request bodies in progress. Code `server_busy`.                                 | Wait for `Retry-After`.                                                                                       | Yes   |
| `503`  | `Credentials cannot be verified now. Retry shortly.`                                         | Munito AI cannot check keys now. Your key is not at fault.                                           | Wait for `Retry-After`. Do not rotate the key.                                                                | Yes   |

The Anthropic body gives the type of each status: `invalid_request_error` (400), `authentication_error` (401), `billing_error` (402), `permission_error` (403), `not_found_error` (404), `request_too_large` (413), `rate_limit_error` (429) and `overloaded_error` (503).
The OpenAI body gives `invalid_request_error` for each `4xx`, `rate_limit_error` for `429`, `insufficient_quota` for a spend limit, and `service_unavailable_error` for `503`.

## OCR errors [#ocr-errors]

The OCR API answers with a problem document. Its `type` is a stable URI, such as `https://munito.ai/problems/invalid-request`, so that you can branch on it.

| Status | Message                                                                               | Cause                                                                                             | Fix                                                                               |
| ------ | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| `404`  | (no detail)                                                                           | `GET /ocr/{request_id}` with an id that your workspace does not have.                             | Check the id.                                                                     |
| `410`  | `The result expired or was already retrieved.`                                        | You polled again after you got the full result. Munito AI deletes the result when it delivers it. | Save the result the first time.                                                   |
| `422`  | `This document type is not supported. Send a PDF or an image.`                        | The file is not a PDF or an image.                                                                | Convert the file.                                                                 |
| `422`  | `munito/ocr-fast accepts only PDF documents. Use munito/ocr-auto for this document.`  | An image sent to `munito/ocr-fast`.                                                               | Use `munito/ocr-auto`.                                                            |
| `422`  | `Could not fetch the document from the provided URL. Use a public https URL.`         | The URL is not public, or not `https`.                                                            | Use a public `https` URL, or send base64.                                         |
| `422`  | `Could not fetch the document from the provided URL.`                                 | The fetch of the URL failed.                                                                      | Check that the URL answers, or send base64.                                       |
| `422`  | `Invalid base64 data`                                                                 | The `data` field is not valid base64.                                                             | Encode the raw bytes of the file.                                                 |
| `422`  | `pages [20] are past the last page: the document has 15 pages, numbered from 0`       | A page number past the end. Pages start at 0.                                                     | Use numbers below the page count.                                                 |
| `422`  | `pages: Value error, pages must not repeat a page`                                    | A repeated page number.                                                                           | Send each page one time.                                                          |
| `422`  | `The document could not be processed. Check that it is a valid, supported file type.` | The file is damaged.                                                                              | Check the file.                                                                   |
| `500`  | (no detail)                                                                           | The request failed in Munito AI.                                                                  | Send the request again. If it fails again, contact Support with the `request_id`. |

See [PDF to Markdown](https://docs.munito.ai/pdf-to-markdown) for the OCR fields.

## Retry with backoff [#retry-with-backoff]

The OpenAI and Anthropic SDKs retry `429` and `5xx` answers and follow `Retry-After`. For your own HTTP client, this function retries only the statuses that can succeed later:

```python
# pip install requests
import os
import random
import time

import requests

RETRY = {429, 502, 503}


def post(url: str, body: dict, attempts: int = 5) -> dict:
    headers = {"Authorization": f"Bearer {os.environ['MUNITO_API_KEY']}"}
    for attempt in range(attempts):
        response = requests.post(url, headers=headers, json=body, timeout=900)
        retry_after = response.headers.get("Retry-After")
        if response.status_code not in RETRY or (response.status_code == 429 and retry_after is None):
            response.raise_for_status()
            return response.json()
        wait = float(retry_after) if retry_after else 2**attempt + random.random()
        time.sleep(wait)
    response.raise_for_status()
    return response.json()


print(post(
    "https://api.munito.ai/inference/v1/chat/completions",
    {"model": "qwen/qwen3.8-27b", "messages": [{"role": "user", "content": "Hello!"}], "max_tokens": 2048},
)["choices"][0]["message"]["content"])
```

A `429` without `Retry-After` is a spend limit, and a retry does not help.
