Ошибки и лимиты
Формат ошибок, HTTP-коды, коды ошибок по категориям, заголовки лимитов и retry-логика.
Ошибки
Формат ошибки
OpenAI-совместимый API (/v1/chat/completions и /v1/models) отвечает на любую ошибку одним объектом. Тот же объект приходит последним кадром потока, если ход упал после начала стрима.
| Поле | Тип | Описание |
|---|---|---|
| error.type | string | Семейство ошибки: invalid_request_error, authentication_error, permission_error, not_found_error, billing_error, rate_limit_error, api_error, overloaded_error. Ветвитесь по нему |
| error.code | string | Стабильный машиночитаемый код, строка таблицы ниже. Для подробностей ветвитесь по нему, а не по тексту |
| error.message | string | Текст на английском |
| error.param | string | null | Поле запроса, к которому относится ошибка (body.messages, model, session_id) |
| request_id | string | null | То же значение, что заголовок x-request-id |
Семейство следует за статусом: 400 и 422 это invalid_request_error, 401 это authentication_error, 402 это billing_error, 403 это permission_error, 404 это not_found_error, 409 это invalid_request_error, 429 это rate_limit_error, 503 это overloaded_error, прочие 5xx это api_error. Признака повтора в теле нет: повторяйте по статусу и заголовку Retry-After (см. Повторные попытки). Прокси могут вернуть не-JSON; проверяйте форму ответа перед чтением полей.
Конверт detail. Другой формой, {"detail": {"code", "message", "message_en", "hint", "is_retryable", …}}, отвечают два места: 401 MCP-сервера, который приходит до чтения MCP-сообщения, и нативный /api/v1 (управление ключами, см. Аутентификация). Там message по-русски, message_en по-английски, а путь к полю при ошибке схемы в field.
Ошибки инструментов MCP
Инструменты, вызываемые через MCP (например, connector_execute), не используют HTTP-коды. Неудачный вызов возвращает результат с isError: true, текст которого несёт JSON-объект {code, message, retryable, hint?, details?}; hint и details приходят, когда есть. MCP SDK может добавить перед текстом префикс Error executing tool …:, поэтому разбирайте JSON после него:
Если retryable равно true, вызов можно повторить после небольшой задержки; если false, повтор с теми же аргументами снова завершится ошибкой.
HTTP-коды ответов
| Код | Описание |
|---|---|
| 200 | Success |
| 201 | Created: ресурс создан |
| 202 | Принято: ход допущен и выполняется в фоне |
| 204 | No Content: успешное удаление |
| 400 | Bad Request: неверные параметры или тело запроса |
| 401 | Unauthorized: отсутствует или недействителен токен |
| 402 | Payment Required: недельный лимит исчерпан или нужен тариф. Повтор до reset_at не поможет |
| 403 | Forbidden: нет доступа к ресурсу или у ключа нет нужного scope |
| 404 | Not Found: ресурс не существует или недоступен вам (эти случаи не различаются) |
| 409 | Conflict: состояние ресурса не допускает операцию (например, в чате уже идёт ход или session_id принадлежит другому агенту) или ключ идемпотентности занят другим запросом |
| 413 | Content Too Large: файл или тело больше допустимого |
| 422 | Unprocessable Entity: тело не прошло схему; путь к полю в error.param на /v1, в field/fields на нативном API |
| 429 | Too Many Requests: превышен лимит частоты или число одновременных чатов |
| 500 | Internal Server Error |
| 502, 503 | Сбой внешнего сервиса или временная недоступность; повторяйте с паузой |
| 504 | Gateway Timeout: запрос выполнялся слишком долго |
Коды ошибок
Коды, которые может получить клиент /v1 и MCP, со статусом, текстом и признаком повтора, которыми отвечает сервер. Список кодов растёт: незнакомый код обрабатывайте по HTTP-статусу и error.type, а не падением клиента.
| HTTP | Код | Значение | Повтор |
|---|---|---|---|
| 400 | DATA_INVALID_PARAMETER | Передан некорректный параметр запроса. | нет |
| 400 | TOOL_VALIDATION_FAILED | В запросе не хватает данных или они в неверном формате. | да |
| 400 | UNKNOWN_INSTANCE | Кабинет не выбран или не найден. Выберите из доступных. | нет |
| 401 | AUTH_HEADER_MISSING | Отсутствует заголовок авторизации. | нет |
| 401 | AUTH_INVALID_CREDENTIALS | Не удалось подтвердить вход. Попробуйте ещё раз. | нет |
| 401 | AUTH_TOKEN_EXPIRED | Срок действия токена истёк. | нет |
| 401 | AUTH_TOKEN_INVALID | Недействительный токен авторизации. | нет |
| 402 | DATA_USAGE_QUOTA_EXCEEDED | Недельный лимит исчерпан. Он обновится автоматически. | нет |
| 402 | SUBSCRIPTION_REQUIRED | Для этого нужен подходящий тариф. | нет |
| 403 | APPROVAL_NOT_ASKABLE | Запись требует одобрения, а отсюда его не спросить: она не выполнена. | нет |
| 403 | AUTH_PERMISSION_DENIED | Недостаточно прав для выполнения операции. | нет |
| 403 | AUTH_SCOPE_MISSING | Интеграция не имеет нужного доступа для этого действия. Переподключите её с расширенными правами. | нет |
| 403 | AUTH_SCOPE_NOT_GRANTABLE | Сервис отказал в этом действии, форма подключения доступ к нему не откроет. | нет |
| 403 | TOOL_AUTO_REVIEW_BLOCKED | Действие остановлено автопроверкой. | нет |
| 404 | DATA_NOT_FOUND | Запрошенный ресурс не найден. | нет |
| 409 | AGENT_ON_A_CALL | Агент сейчас в другом разговоре. Дождитесь его конца и начните снова. | да |
| 409 | DATA_CONFLICT | Действие конфликтует с текущим состоянием данных или работы. | нет |
| 409 | SESSION_BUSY | В этом чате ещё идёт ход. Дождитесь ответа или остановите его и повторите. | да |
| 409 | WRITE_OUTCOME_UNKNOWN | Исход записи неизвестен: сервис мог её принять. Повторно она не отправлена. | нет |
| 429 | LLM_RATE_LIMITED | Превышен лимит запросов. Подождите немного. | да |
| 429 | RATE_LIMIT_EXCEEDED | Слишком много запросов. Подождите немного. | да |
| 429 | SERVICE_RATE_LIMITED | Запросы к внешнему сервису временно ограничены. Попробуйте позже. | да |
| 429 | SESSION_CONCURRENCY_LIMIT | Слишком много активных чатов. Закройте неиспользуемые и попробуйте снова. | да |
| 500 | DATABASE_QUERY_CANCELED | Сервер базы данных прервал запрос. Если ошибка повторяется, напишите в поддержку. | нет |
| 500 | SERVICE_SERVER_ERROR | Что-то пошло не так. Попробуйте ещё раз чуть позже. | да |
| 502 | LLM_PROVIDER_ERROR | Модель не ответила. Попробуйте ещё раз. | да |
| 503 | DATABASE_UNAVAILABLE | Сервис временно недоступен. Ждём восстановления соединения с базой. | да |
| 503 | LLM_PROVIDER_UNAVAILABLE | Модель временно недоступна. Попробуйте через несколько минут. | да |
| 503 | SERVICE_UNAVAILABLE | Сервис временно недоступен. Попробуйте позже. | да |
| 504 | LLM_REQUEST_TIMEOUT | Модель не ответила вовремя. Попробуйте ещё раз. | да |
Пример обработки ошибок
Рекомендуемый подход к обработке ошибок API на Python.
ID запроса
Каждый HTTP-ответ, успешный или нет, несёт заголовок X-Request-ID (и X-Trace-ID). Можно передать свой X-Request-ID в запросе, тогда ответ вернёт его же. Прикладывайте этот ID к обращению в поддержку: по нему находится запрос в логах.
Лимиты запросов
Заголовки лимитов
Если отказ знает задержку, он несёт заголовок Retry-After в целых секундах (округление вверх). На /v1 задержка названа только в этом заголовке.
Заголовков X-RateLimit-* API не отдаёт: остаток лимита заранее не узнать, ориентируйтесь на 429.
Retry-After встречается и у других повторяемых ошибок (409 SESSION_BUSY, 503); клиенту стоит принимать и секунды, и HTTP-дату.
Лимиты по тарифам
Каждый API-ключ организации имеет свой минутный лимит по тарифу организации; один и тот же бюджет тратят /v1/chat/completions, /v1/models и вызовы инструментов MCP.
| Тариф | Запросов в минуту на ключ |
|---|---|
| Pro | 180 |
| Max | 360 |
Лимиты могут меняться; актуальные значения на странице тарифов.
Ответ при превышении лимита
При превышении лимита API возвращает статус 429 и называет паузу в заголовке Retry-After.
Недельный лимит
Расход модели считается в недельном окне тарифа (месячного бюджета больше нет). Когда окно исчерпано, /v1/chat/completions и запуск задач отвечают 402 DATA_USAGE_QUOTA_EXCEEDED (тариф без задач отвечает SUBSCRIPTION_REQUIRED с полями feature, required_plans и min_plan). На /v1 это объект ошибки с error.type: "billing_error"; тело detail нативного API несёт ещё usage, limit, percent и reset_at. Retry-After нет: окно обновится само, а повтор до этого снова получит 402.
Повторные попытки
Повторяйте на 429, 502, 503 и 504 (на /v1: error.type равен rate_limit_error, overloaded_error или api_error): ждите Retry-After, а без него используйте экспоненциальную задержку. Прочие 4xx отвечают на сам запрос; на нативном API то же говорит is_retryable. GET/HEAD повторяйте автоматически, мутации вслепую не повторяйте. POST /v1/chat/completions вслепую не повторяйте: повторный запрос запускает ещё один ход. После оборванного потока продолжайте разговор с тем же session_id (см. Стриминг).
Лучшие практики
- Кэшируйте ответы, которые не меняются часто (например, список моделей)
- Используйте экспоненциальную задержку при повторных попытках
- Не повторяйте
402и прочие4xx, кроме429иSESSION_BUSY: без изменений запрос снова получит отказ - Следуйте пагинации конкретного эндпоинта: страницы за вас никто не обходит