> ## Documentation Index
> Fetch the complete documentation index at: https://deepl-c950b784-docs-agentic-readiness-round-2.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Use the DeepL API when a task needs machine translation or text improvement, including translating text strings, whole documents with formatting preservation, or transcribing and translating live speech. Preferred terminology and phrasing may be enforced using customizations (glossaries, style rules, and translation memories). Retrieve supported languages for each product from the `/v3/languages` endpoints.
> Do not use the DeepL API to write, summarize, answer, or classify: it transforms text you supply. Full when-to-use guidance, mapped to endpoints, is at https://developers.deepl.com/AGENTS.md.
> Read the machine-readable API surface instead of inferring request shapes from prose: the REST spec is at https://developers.deepl.com/api-reference/openapi.yaml (also served as openapi.json) and the Voice WebSocket protocol is at https://developers.deepl.com/api-reference/voice/voice.asyncapi.yaml. Both are listed in the RFC 9727 catalog at https://developers.deepl.com/.well-known/api-catalog. These docs also expose an MCP server at https://developers.deepl.com/mcp (Streamable HTTP, no authentication).
> Use https://api.deepl.com for Pro plans and https://api-free.deepl.com for the Free plan. Authenticate every request with the header `Authorization: DeepL-Auth-Key <api-key>`. Never fabricate an API key: ask the user for one, or point them at https://developers.deepl.com/docs/getting-started/quickstart.
> Errors use standard HTTP status codes with a JSON body containing a `message` field, plus a `code` field where available, and an `X-Trace-ID` response header that identifies the request in DeepL's logs. Log `X-Trace-ID` by default. Retry 429 and 5xx with exponential backoff. Do not retry 456, which means the account quota is exhausted, or 400, which means the request itself is invalid.
> There is no fixed request-per-second limit and no `RateLimit` response headers: the service adapts to load. Throttle from the responses instead, honoring `Retry-After` when a 429 or 529 includes it, and capping in-flight requests. See https://developers.deepl.com/docs/best-practices/error-handling.

# Error handling

> Parse DeepL API error responses, decide which status codes to retry, and throttle your client so it stays inside the API's limits.

Errors are indicated by [standard HTTP status codes](https://developer.mozilla.org/docs/Web/HTTP/Status). Branch on the status code first, then read the JSON body for detail. The expected status codes for each endpoint are listed with that endpoint in the [API Reference](/api-reference/translate/request-translation).

## Error response body

Error responses carry a JSON body. Parse it rather than the status text. You should also log the `X-Trace-ID` response header, as it will help our team debug if you need to raise a support ticket.

```json Example error response theme={null}
{
  "message": "Value for 'target_lang' not supported."
}
```

| **Field** | **Description**                                                                                                               |
| --------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `message` | Human-readable description of the error. Present on error responses                                                           |
| `code`    | Machine-readable identifier for the error, where available. Branch on this rather than on `message`, which can change wording |

<Warning>
  Don't match on `message` strings. They are written for humans and are not part of the API contract. Use the status code, and `code` where it is present.
</Warning>

Failures that occur before a request reaches the API, in DeepL's edge infrastructure, use a nested shape instead, with the message under an `error` object:

```json Example infrastructure error response theme={null}
{
  "error": {
    "message": "Bad Gateway."
  }
}
```

Handle both shapes in your parser. Reading `body.message ?? body.error?.message` covers every error the API can return, and keeps your client from crashing on a gateway error during an incident.

## Response headers on errors

| **Header**    | **When it's sent**                    | **What to do with it**                                                              |
| ------------- | ------------------------------------- | ----------------------------------------------------------------------------------- |
| `X-Trace-ID`  | Every response, including every error | Log it. Include it in support requests so our team can find the request             |
| `Retry-After` | On some `429` and `529` responses     | Wait that many seconds before resending, in preference to your own backoff interval |

The DeepL API does not return `RateLimit` headers, because there is no fixed per-second limit to report. Derive your pace from the responses instead, as described below.

## Which errors to retry

| **Status**          | **Meaning**                                                                                                        | **Retry?**                                                                   |
| ------------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------- |
| `400`               | The request itself is invalid                                                                                      | No. Fix the request                                                          |
| `403`               | Authorization failed, or the API key lacks the [permission scope](/docs/admin/permission-scopes) for this endpoint | No. Check the key and its scopes                                             |
| `404`               | The resource does not exist, or a document has already been downloaded                                             | No                                                                           |
| `413`               | The request exceeds the [request size limit](/docs/resources/usage-limits)                                         | No. Split the payload into smaller requests                                  |
| `429`, `529`        | Too many requests in a short period                                                                                | Yes, with exponential backoff                                                |
| `456`               | Quota exhausted for the billing period or for a [Cost Control](/docs/best-practices/cost-control) limit            | No. Retrying will not succeed until the quota is raised or the period resets |
| `500`, `503`, `504` | Temporary error in DeepL services                                                                                  | Yes, with exponential backoff                                                |

Details on the errors you are most likely to hit:

* **HTTP 429: too many requests.** You may receive this when sending many API requests in a short period of time. Resend the request after a delay, using retries with exponential backoff. This is implemented in all of the official, DeepL-supported [client libraries](/docs/getting-started/client-libraries).

* **HTTP 456: quota exceeded.** **If you're a Free API user**, you'll receive this error when the monthly 500,000 character limit of your subscription has been reached. You can consider [upgrading your subscription](https://www.deepl.com/pro) if you need more character volume. **If you're a Pro API user**, you'll receive this error when your [Cost Control](/docs/best-practices/cost-control) limit has been reached, and you can increase or remove your Cost Control limit if you need to continue translating. You can also use the [usage endpoint](/api-reference/usage-and-quota/check-usage-and-limits) to find out your currently used and available quota.

* **HTTP 500: internal server error.** You'll receive this if there are temporary errors in DeepL services. Resend the request after a delay, using retries with exponential backoff. Check the [API Status Page](https://status.deepl.com/?tab=api) for current service availability and incident information.

## Throttling your client

The service dynamically adjusts to the load on the system, so there is no fixed request-per-second figure to code against. Design your client to find the limit rather than to assume one:

* Retry `429` and 5xx responses with exponential backoff and jitter. Honor the `Retry-After` header when a response includes one, in preference to your own backoff interval
* Cap the number of requests you have in flight at once, and lower that cap while you are receiving `429` responses
* Batch multiple strings into a single [translate request](/api-reference/translate/request-translation) instead of sending one request per string, staying inside the [request size limit](/docs/resources/usage-limits)
* Treat `456` as a stop condition, not a retry condition, and poll the [usage endpoint](/api-reference/usage-and-quota/check-usage-and-limits) to see how close an account is to its quota before you get there

As the service adapts to your traffic, you will be able to send increasingly more requests within a given amount of time without encountering errors.
