Ошибки и лимиты

Формат ошибки

При ошибке API возвращает HTTP-код и JSON в формате OpenAI:

{
  "error": {
    "message": "Insufficient user quota ... (request id: 20261027153012345678)",
    "type": "...",
    "code": "insufficient_user_quota"
  }
}
  • message — описание на английском. В конце обычно стоит request id: по нему поддержка найдёт ваш запрос.
  • code — машиночитаемый код. Есть не у всех ошибок, поэтому ориентируйтесь на HTTP-код и текст.

SDK openai превращает такой ответ в исключение: AuthenticationError (401), PermissionDeniedError (403), RateLimitError (429), InternalServerError (5xx) и т. д.

Коды ответов

Код Текст ошибки (фрагмент) Что случилось Что делать Повторять?
400 invalid ..., context length некорректный запрос: битый JSON, неверный параметр, текст не помещается в контекст модели, модель не поддерживает изображения или инструменты исправьте запрос, сократите текст или историю нет
401 Invalid token, Token not provided ключ не передан, неверный или удалён. Та же ошибка, если исчерпан лимит расходов ключа проверьте ключ и его лимит в разделе «Ключи»; заголовок — Authorization: Bearer sk-... нет
403 insufficient_user_quota на балансе недостаточно денег пополните баланс после пополнения
403 pre_consume_token_quota_failed остатка лимита ключа не хватает на этот запрос создайте ключ с бо́льшим лимитом или сократите запрос нет
429 rate limit, Too many requests слишком много запросов за короткое время или модель временно перегружена повторите с нарастающей паузой (пример ниже) да
500 Internal error сбой на нашей стороне повторите через несколько секунд; если ошибка не уходит — напишите в поддержку с request id да
502 / 504 bad gateway, timeout, upstream provider error модель ответила с ошибкой или не ответила вовремя повторите с паузой; если не помогает — попробуйте другую модель да
503 No available channel for model ... модели с таким ID нет или она временно недоступна сверьте ID со страницей цен: регистр, точки, дефисы. Если ID верный — повторите позже если ID верный

Обратите внимание:

  • Нехватка денег — это 403, а не 402. Отличайте её по коду insufficient_user_quota.
  • 401 не всегда значит неверный ключ. Если ключ работал и перестал, скорее всего закончился его лимит расходов.
  • Ошибка в потоке. При stream: true ошибка может прийти уже после начала ответа, когда HTTP-статус 200. Обрабатывайте ошибки на протяжении всего чтения потока.

Повторы запросов

Запрос, завершившийся ошибкой, не оплачивается, поэтому его можно безопасно повторить. Повторяйте только временные ошибки: 429, 500, 502, 503, 504 и сетевые сбои. Ошибки 400, 401 и 403 повтор не исправит — нужно поменять запрос, ключ или пополнить баланс.

Повторяйте с экспоненциальной задержкой: пауза растёт вдвое после каждой неудачи (1, 2, 4, 8 секунд…), к ней добавляется небольшая случайная добавка, чтобы много клиентов не повторяли запросы одновременно. Если в ответе есть заголовок Retry-After, ждите не меньше указанного числа секунд. Число попыток ограничивайте — например, пятью.

import os
import random
import time

import openai
from openai import OpenAI

client = OpenAI(
    base_url="https://router.1-lab.online/v1",
    api_key=os.environ["ROUTER_API_KEY"],
    max_retries=0,   # повторяем сами
    timeout=120.0,   # секунды
)

RETRY_STATUS = {429, 500, 502, 503, 504}


def chat_with_retry(max_attempts=5, **kwargs):
    for attempt in range(max_attempts):
        try:
            return client.chat.completions.create(**kwargs)
        except openai.APIStatusError as e:
            if e.status_code not in RETRY_STATUS or attempt == max_attempts - 1:
                raise
            retry_after = e.response.headers.get("retry-after")
            delay = float(retry_after) if retry_after and retry_after.isdigit() else 2 ** attempt
        except openai.APIConnectionError:  # сеть, таймаут
            if attempt == max_attempts - 1:
                raise
            delay = 2 ** attempt
        time.sleep(delay + random.uniform(0, 0.5))


resp = chat_with_retry(
    model="openai/gpt-6-luna",
    messages=[{"role": "user", "content": "Привет!"}],
)
print(resp.choices[0].message.content)

SDK openai умеет повторять запросы и сам: по умолчанию делает 2 повтора при 408, 409, 429, 5xx и сетевых ошибках. Их число задаётся параметром max_retries (Python) или maxRetries (TypeScript) при создании клиента.

Таймаут ставьте с запасом: «думающие» модели и длинные ответы могут генерироваться минуту и дольше. Если оборвать соединение раньше, ответ потеряется, а повтор будет новым запросом.

Лимиты

Что Значение
Размер контекста зависит от модели
Длина ответа зависит от модели; задаётся параметром max_tokens
Расход ключа лимит в рублях, задаётся при создании ключа

Если для вашей задачи нужна высокая нагрузка (массовая обработка, много пользователей одновременно), напишите в поддержку заранее.

Что написать в поддержку

Чтобы мы быстро нашли проблему, пришлите в поддержку (kazhaevd@list.ru):

  1. request id из текста ошибки;
  2. время запроса с часовым поясом;
  3. ID модели;
  4. название ключа (не сам ключ!);
  5. текст ошибки целиком.