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

# Ошибки

> Один конверт, стабильные коды и идентификатор запроса в каждом ответе.

## Конверт

Каждый сбой, независимо от статуса, — это один JSON-объект:

```json theme={null}
{
  "error": {
    "code": "insufficient_balance",
    "message": "Insufficient balance",
    "request_id": "7f20a5f0-5dde-48cf-94aa-38acbbd218e0"
  }
}
```

* `code` стабилен и рассчитан на машинную обработку. Ветвите логику по нему, а не по `message`.
* `message` — пояснение для человека, оно может меняться.
* `request_id` — UUID запроса. Он также возвращается в заголовке `X-Request-ID` в **каждом** ответе, успешном или нет. Указывайте его, когда сообщаете о проблеме.

На потоковом эндпоинте сбой, случившийся после начала стрима, приходит как событие `error` с теми же тремя полями; см. [Стриминг](/ru/guides/streaming).

## Коды

| HTTP | Код                          | Значение                                                                                                         |
| ---- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| 401  | `invalid_api_key`            | Ключ отсутствует, некорректен, неизвестен, удалён или у него неверный секрет                                     |
| 403  | `agent_mismatch`             | Ключ принадлежит другому агенту                                                                                  |
| 403  | `permission_denied`          | Ключ с `read-only` вызвал эндпоинт чата                                                                          |
| 403  | `agent_disabled`             | Агент выключен. Только эндпоинты чата                                                                            |
| 404  | `agent_not_found`            | Агента больше не существует. Только эндпоинты чата                                                               |
| 404  | `conversation_not_found`     | Неизвестный диалог или диалог не этого ключа                                                                     |
| 402  | `insufficient_balance`       | Баланс владельца не покрывает ответ; ничего не списано                                                           |
| 409  | `idempotency_conflict`       | Тот же `Idempotency-Key` использован с другим телом                                                              |
| 409  | `idempotency_in_progress`    | Исходный запрос ещё выполняется; повторите через `Retry-After` секунд (всегда `2`)                               |
| 409  | `conversation_busy`          | Другое сообщение того же внешнего пользователя сейчас обрабатывается; повторите через `Retry-After` (всегда `2`) |
| 422  | `validation_error`           | Некорректное тело, заголовок, дата, лимит или курсор                                                             |
| 429  | `rate_limit_exceeded`        | Окно ключа исчерпано; см. [Лимиты запросов](/ru/guides/rate-limits)                                              |
| 503  | `api_rate_limit_unavailable` | Ограничитель недоступен; запрос отклонён, а не обслужен без учёта. Повторите через `Retry-After` (всегда `5`)    |
| 503  | `service_unavailable`        | Недоступен бэкенд, от которого зависит API; повторите через `Retry-After` (всегда `2`)                           |
| 500  | `internal_error`             | Непредвиденный сбой; укажите `request_id`                                                                        |

`agent_not_found` и `agent_disabled` проверяются только в `POST …/chat` и `POST …/chat/stream`. Два `GET`-эндпоинта не смотрят на состояние агента: ключ выключенного агента всё ещё может получить список его диалогов и прочитать сообщения.

## Что повторять

<AccordionGroup>
  <Accordion title="Повторить через Retry-After с тем же Idempotency-Key">
    `idempotency_in_progress`, `conversation_busy`, `rate_limit_exceeded`, `api_rate_limit_unavailable`, `service_unavailable`. Повторное использование ключа гарантирует, что вы никогда не заплатите дважды за одно сообщение.
  </Accordion>

  <Accordion title="Сначала исправить запрос">
    `validation_error` (прочитайте `message`; в нём названо проблемное поле), `idempotency_conflict` (используйте новый ключ для нового тела), `permission_denied` (используйте ключ с `full`), `agent_mismatch` (используйте агента, которому принадлежит ключ).
  </Accordion>

  <Accordion title="Не повторять автоматически">
    `invalid_api_key` (ключ удалён или секрет неверен), `agent_disabled`, `agent_not_found`, `insufficient_balance` (сначала пополните баланс). Цикл повторов на этих кодах только сжигает лимит запросов.
  </Accordion>

  <Accordion title="Сообщить с идентификатором запроса">
    `internal_error`. Повторите один раз с тем же `Idempotency-Key`: неуспешная запись освобождается, поэтому повтор выполняет запрос заново, а не воспроизводит сохранённый результат. Это ожидаемо, но не гарантирует бесплатность. Если сбой случился после того, как модель уже ответила, повтор создаст новый ответ и новое списание. Если сбой повторяется, пришлите нам `request_id`.
  </Accordion>
</AccordionGroup>

## Замечание о 401

API не различает удалённый ключ и ключ, которого никогда не было: оба — `invalid_api_key`. Если ключ, который раньше работал, начал возвращать 401, проверьте карточку «Доступ по API» в приложении; скорее всего, его обновили или удалили.
