Ошибки и лимиты
На этой странице
Ошибки бывают двух видов. Наши — когда запрос остановили мы: ключ, баланс, лимиты, модель. Ошибки провайдера приходят как есть, в формате его протокола: Claude Code и Codex узнают их и сами повторяют запрос, когда это имеет смысл.
Если нужен не справочник, а разбор по симптому — «пришёл 401, что делать», — смотри «Решение проблем».
Формат#
Наша ошибка — JSON в форме, которую разбирают клиенты и Anthropic, и OpenAI. Смотри на error.code: HTTP-статус у разных причин бывает общий.
{
"type": "error",
"error": {
"type": "rate_limit_error",
"code": "rate_limit_exceeded",
"message": "key rate limit exceeded"
}
}Заголовок x-should-retry говорит, есть ли смысл повторять: true или false. Когда ждать нужно определённое время, рядом стоит retry-after в секундах. Если заголовок и колонка «Повторять» в таблице ниже расходятся, верь заголовку: у одного кода бывают разные причины. Ответы 401 invalid_api_key и 503 authentication_unavailable приходят без этого заголовка.
Два отказа приходят не в этой форме, а коротким текстом, без JSON и без error.code: 429 лимита по IP-адресу (с заголовком retry-after) и 413 для запроса, у которого заявленный в Content-Length размер тела больше 32 МБ. Оба описаны в лимитах сервиса.
Коды#
| HTTP | Код | Что случилось | Что делать | Повторять |
|---|---|---|---|---|
| 400 | invalid_request_body | Тело запроса не читается как JSON-объект. | Проверь JSON и заголовок Content-Type. | нет |
| 400 | model_required | В запросе нет поля model или оно пустое. | Укажи имя модели. | нет |
| 400 | duplicate_model | Поле model встречается на верхнем уровне тела больше одного раза. | Оставь одно поле model. | нет |
| 400 | model_not_available | Такой модели нет в нашем списке или её нет на этом протоколе. | Возьми имя из GET /v1/models для своего протокола. | нет |
| 400 | request_too_large | Один запрос по оценке больше всего минутного лимита токенов ключа. | Сократи запрос или увеличь лимит токенов ключа в кабинете; ожидание не поможет. | нет |
| 400 | invalid_surface | В GET /v1/models передано неизвестное значение surface. | Допустимы chat, responses и anthropic. | нет |
| 401 | invalid_api_key | Ключа нет, он скопирован не целиком или отозван. | Проверь заголовок с ключом или создай новый ключ в кабинете. | нет |
| 402 | insufficient_balance | На балансе не хватает денег на резерв под запрос. | Пополни баланс или уменьши max_tokens; повторять до этого бесполезно. | нет |
| 403 | model_not_allowed | Ключу разрешены не все модели, и этой среди них нет. | Возьми разрешённую модель или добавь эту в список моделей ключа в кабинете. | нет |
| 408 | request_timeout | Тело запроса читалось слишком долго. | Повтори запрос. | да |
| 413 | request_too_large | Тело запроса больше 32 МБ. | Сократи историю или вложения. | нет |
| 429 | rate_limit_exceeded | Исчерпан лимит ключа на запросы или токены в минуту. | Подожди столько секунд, сколько сказано в retry-after. | да |
| 429 | concurrent_requests | По ключу уже идёт предельное число одновременных запросов: 4. | Повтори через секунду или раздели нагрузку по ключам. | да |
| 429 | monthly_limit_exceeded | Исчерпан месячный лимит расходов ключа. | Дождись следующего месяца или увеличь месячный лимит ключа в кабинете. | нет |
| 502 | upstream_unavailable | Провайдер модели не ответил. | Повтори запрос позже, если x-should-retry не говорит false. Деньги не списаны. | да |
| 502 | upstream_auth_failed | Провайдер отклонил наш доступ. Это сбой на нашей стороне, а не твоего ключа. | Напиши в поддержку. Деньги не списаны. | нет |
| 503 | at_capacity | Сервис перегружен: слишком много запросов одновременно. | Повтори через несколько секунд по retry-after. | да |
| 503 | authentication_unavailable | Мы не смогли проверить ключ. Сам ключ при этом в порядке. | Повтори запрос; новый ключ не нужен. | да |
| 503 | billing_unavailable | Мы не смогли зарезервировать деньги под запрос. | Повтори запрос, если x-should-retry не говорит false. Деньги не списаны. | да |
| 503 | pricing_unavailable | У модели на этом протоколе не настроена цена. | Возьми другую модель и напиши в поддержку. | нет |
| 503 | global_limit_exceeded | Исчерпан месячный бюджет всего сервиса. | Напиши в поддержку; баланс не тронут. | нет |
| 504 | upstream_timeout | Провайдер не уложился в 30 минут. | Повтори запрос; длинные ответы запрашивай стримом. | да |
Код request_too_large приходит с двумя статусами: 413 — тело больше допустимого размера, 400 — запрос больше минутного лимита токенов ключа. В форме JSON ответ 413 приходит, когда размер тела заранее не объявлен (chunked); обычный запрос с Content-Length получит 413 текстом.
Ошибку 524 отдаёт не наш API, а Cloudflare перед ним: запрос без стрима ждал ответа дольше примерно двух минут. Длинные ответы запрашивай стримом — справочник API.
Коды в журнале запросов#
Запрос, который мы отклонили до отправки провайдеру — 401, 402, 403, наши 400 и 429, — в журнал кабинета не попадает и ничего не стоит. Запросы, дошедшие до провайдера, в журнале есть все, с HTTP-статусом и кодом ошибки. Кроме кодов из таблицы выше там встречаются:
| Код | Что случилось |
|---|---|
upstream_error | Провайдер ответил ошибкой. Клиент получил её как есть; запрос не оплачен. |
upstream_error_body | Провайдер ответил статусом 200, но с ошибкой в теле. Клиент получил её со статусом 400 или 502; запрос не оплачен. |
upstream_stream_error | Стрим начался со статусом 200, но провайдер прислал в нём ошибку раньше текста или закончил его, не прислав ничего. Статус ответа уже не изменить, поэтому код виден только здесь; запрос не оплачен. |
upstream_read_error | Ответ провайдера без стрима оборвался, пока мы его читали. Клиент получил 502; запрос не оплачен. |
settle_failed | Ответ доставлен, но списание не прошло — сбой на нашей стороне. Резерв возвращён, запрос не оплачен. |
client_closed_request | Клиент закрыл соединение раньше конца ответа. Строка идёт как отменённая; оплачено то, что модель успела сгенерировать. |
Ошибкой в статистике считается только сбой на нашей стороне: ответ 5xx или оборванный стрим. Строки с ответом 4xx видны в журнале со своим статусом, но в счётчик ошибок не входят.
Лимиты ключа#
У ключа могут быть:
- запросы в минуту (
rpm) — сверх лимита ключ отвечает 429rate_limit_exceeded; - токены в минуту (
tpm) — считаются входные токены по оценке: размер тела запроса в байтах, делённый на 4. Сверх лимита — тот же 429; запрос, который один больше всего лимита, — 400request_too_large; - месячный лимит расходов в долларах — когда резерв под запрос в него не помещается, ключ отвечает 429
monthly_limit_exceededдо начала следующего месяца; - список разрешённых моделей — остальные получают 403
model_not_allowedи не видны ключу вGET /v1/models.
Лимиты задаются при создании ключа на странице «Ключи» и меняются там же в любой момент: сам ключ остаётся прежним, а новые значения действуют со следующего запроса. Запрос, который уже выполняется, доработает со старыми лимитами. Отдельный ключ на каждый инструмент или проект — простой способ знать, кто сколько тратит. Подробнее — в разделе «Ключи и лимиты».
Лимиты сервиса#
Они действуют на любой ключ, какие бы лимиты у него ни стояли:
- не больше 120 запросов и 2 000 000 токенов в минуту на ключ — действует меньшее из этого потолка и лимита самого ключа;
- с одного IP-адреса — не больше 60 запросов в минуту, 300 за пять минут и 1 200 в час на каждый адрес API (
/v1/messages,/v1/chat/completionsи остальные считаются отдельно), сколько бы ключей ни было. С одной машины этот лимит строже лимита ключа. Сверх него приходит 429 текстом, без JSON, с заголовкомretry-after; - не больше 4 одновременных запросов на ключ — следующий получит 429
concurrent_requests; - тело запроса — до 32 МБ, иначе 413: текстом, если размер объявлен в Content-Length, и с кодом
request_too_large, если нет; - один запрос — не дольше 30 минут;
- не больше 20 активных ключей на аккаунт — создание следующего вернёт 409; отозванные ключи не считаются.