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

# Error reference

> Complete list of LLM.kiwi API error codes, their causes, safe retry strategies, and fixes for 400, 401, 403, 404, 429, and 5xx HTTP status responses.

Check the HTTP status first, then inspect the response error object for detail.

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

<Note>
  Error messages can change. Use the HTTP status and a stable `code` when available, while keeping a fallback for unknown errors.
</Note>

## Status overview

| Status | Meaning                         | Retry unchanged?   |
| ------ | ------------------------------- | ------------------ |
| `400`  | Invalid request                 | No                 |
| `401`  | Authentication failed           | No                 |
| `403`  | Access denied                   | No                 |
| `404`  | Endpoint or model not found     | No                 |
| `408`  | Request timed out               | Sometimes          |
| `413`  | Request is too large            | No                 |
| `429`  | Rate limit reached              | Yes, after waiting |
| `500`  | Internal server failure         | Yes, limited       |
| `502`  | Upstream response failure       | Yes, limited       |
| `503`  | Service temporarily unavailable | Yes, limited       |
| `504`  | Upstream timeout                | Yes, limited       |

## 400: bad request

The API understood the HTTP request but rejected its data.

Check:

* The body is valid JSON.
* `Content-Type` is `application/json`.
* `model` is present and supported.
* `messages` is a non-empty array.
* Every message has a supported `role` and string `content`.
* Numeric options are within supported ranges.

Do not retry the same body. Correct it first.

## 401: unauthorized

The API key is missing, malformed, invalid, or revoked.

```http theme={null}
Authorization: Bearer sk_kiwi_...
```

Verify the environment variable and `Bearer ` prefix. Do not print the key while debugging. Create a new key if the existing key cannot be recovered or may have leaked.

## 403: forbidden

Authentication succeeded, but the request is not allowed. Check account state, key access, or requested capability. Repeating the request unchanged will not fix it.

## 404: not found

Check for:

* Incorrect hostname
* Missing or duplicated `/v1`
* Misspelled endpoint
* Model ID that is not returned by `GET /v1/models`

## 408 or client timeout

The request did not finish within a time limit. It may be safe to retry a read-like AI request, but your application should still prevent duplicate downstream actions based on multiple responses.

## 413: payload too large

Shorten the input, remove old conversation turns, split documents, or request less output. Retrying the same payload will fail again.

## 429: too many requests

The current request rate or capacity exceeded a limit.

1. Respect a `Retry-After` header when present.
2. Otherwise wait using exponential backoff with jitter.
3. Reduce concurrency.
4. Stop after a limited number of attempts.

Do not rotate through keys to evade rate limits.

## 500, 502, 503, and 504

These usually represent temporary service or upstream model failures. Retry a limited number of times with backoff. If failures continue, show a temporary-unavailable message and allow the user to try later.

## Unknown errors

Applications must have a safe fallback:

* Preserve the HTTP status and request ID for diagnostics.
* Show a user-friendly message without exposing internal details.
* Avoid revealing prompts, stack traces, or keys.
* Do not treat an unknown response as a successful model output.

## Python example

```python theme={null}
from openai import (
    APIConnectionError,
    APIStatusError,
    APITimeoutError,
    RateLimitError,
)

try:
    response = client.chat.completions.create(
        model="auto",
        messages=[{"role": "user", "content": "Hello"}],
        timeout=30,
    )
except RateLimitError:
    print("Too many requests. Please try again shortly.")
except APITimeoutError:
    print("The request took too long. Please try again.")
except APIConnectionError:
    print("Could not reach LLM.kiwi.")
except APIStatusError as error:
    print(f"API error {error.status_code}")
```

This example classifies failures. Add bounded backoff around the temporary cases for a production integration.

<CardGroup cols={2}>
  <Card title="Troubleshooting steps" icon="wrench" href="/troubleshooting">
    Diagnose the root cause interactively.
  </Card>

  <Card title="Limits and backoff" icon="gauge" href="/limits">
    Implement respectful retry behavior.
  </Card>
</CardGroup>
