Ошибки и поведение
Что возвращает шлюз, когда что-то не так, как работает поток и в какой момент возможно переключение между поставщиками.
Формат ошибки
Тело ошибки - JSON с объектом error, причина - в error.message. Такой формат понимают стандартные SDK, поэтому ошибки шлюза прилетают в код как обычные ошибки API. Часть системных сообщений пока приходит не по-русски.
{
"error": {
"message": "...",
"type": "...",
"code": "..."
}
}Коды ответа
| Код | Что случилось | Что делать |
|---|---|---|
400 | Запрос не разобран: невалидный JSON, отсутствует или испорчено обязательное поле. | Починить запрос. Повтор без изменений не поможет. |
401 | Ключ не принят: не передан, отозван, просрочен, скопирован не целиком. | Проверить заголовок и сам ключ, при необходимости выпустить новый. |
403 | Запрос отклонён до обращения к модели: не хватает баланса на резерв, модель вне белого списка ключа, адрес вне списка разрешённых IP. | Пополнить баланс или снять ограничение ключа; что именно не сошлось, сказано в теле ответа. |
429 | Превышен лимит частоты запросов по аккаунту. | Повторить с экспоненциальной задержкой, снизить параллельность. |
5xx | Ошибка на стороне поставщика или шлюза, которую не удалось обойти переключением. | Повторить с задержкой: запрос не выполнен и не списан. |
Резерв, списание и нехватка баланса
Перед вызовом шлюз резервирует оценку максимальной стоимости запроса, а после ответа списывает фактическую. Если на резерв не хватает, запрос не уходит к поставщику и сразу возвращается 403 с обычным JSON в теле.
Посреди ответа нехватки баланса не бывает. Проверка целиком предполётная: либо запрос начат и будет обслужен, либо отклонён до обращения к модели.
Ограничения ключа - белый список моделей, срок действия, список разрешённых IP - проверяются там же, до обращения к поставщику. Такой запрос отклоняется, баланс не списывается, а причина названа в теле ответа (Ключи и подключи).
Потоковая передача (SSE)
С "stream": true ответ приходит как text/event-stream: серия событий data: с дельтами и завершающее data: [DONE].
data: {"choices":[{"delta":{"content":"При"}}]}
data: {"choices":[{"delta":{"content":"вет"}}]}
data: [DONE]SDK OpenAI и Anthropic разбирают поток сами - руками парсить события не нужно.
Повторы и переключение поставщиков
Одну модель может обслуживать несколько поставщиков, и шлюз сам пробует следующего, если предыдущий ответил ошибкой: обрыв соединения, 429, 5xx. Клиент этого не видит - он получает один нормальный ответ. Модель при этом не меняется: другой поставщик обслуживает ту же модель, которую вы назвали - Имена моделей.
Если поставщик оборвался в середине потока, поток завершается событием ошибки, а полученная часть остаётся у клиента. Повтор оборвавшегося потока - на стороне клиента, и повторять надо запрос целиком. Списание идёт по фактически обработанным токенам, поэтому оборванный ответ стоит ровно столько, сколько успел отдать.
Что ещё полезно знать
- На
429и5xxповтор уместен, на400,401и403- нет: без изменений результат будет тот же. - Для долгих запросов держите таймаут клиента с запасом: ответ большой модели может идти минуты.
- Текущее состояние шлюза - на странице Статус.