Lovely RouterДокументация
Получить ключ
Справочник API

Ошибки

Все HTTP-статусы, которые возвращает Lovely Router, тело ошибки для каждого формата API, а также когда и как повторять запросы.

Lovely Router использует стандартные HTTP-коды статуса. 2xx означает успех, 4xx — запрос нужно изменить (или пополнить баланс аккаунта), а 5xx или 429 — временную проблему, при которой стоит повторить запрос. Тело объясняет причину в формате вызванного вами API, поэтому официальные SDK выбрасывают привычные исключения.

Коды статуса#

СтатусЗначениеТипичные причиныПовторять?
400Bad requestТело не является корректным JSON. Модель отклонила параметр, например max_tokens выше её предела. Во входных данных инструмента нет обязательного поля. Неизвестный x-lovely-group.Нет. Исправьте запрос.
401UnauthenticatedКлюч отсутствует, содержит опечатку, отозван или просроченНет. Проверьте ключ.
402Payment requiredБаланс $0. Ключ достиг лимита расходов. Баланса не хватает на максимальную стоимость запуска.После пополнения баланса или повышения лимита
403ForbiddenМодели нет в списке разрешённых для ключаНет
404Not foundНеизвестный id модели, модель не предлагается в этом формате API, неизвестный эндпоинт, инструмент или запускНет
405Method not allowedНеверный HTTP-метод на эндпоинте хранилища секретов или файлов браузераНет
409ConflictОтвет запуску браузера, который не ждёт этого ответа или уже завершился. Достигнут лимит хранилища файлов.Нет. Проверьте состояние запуска.
413Payload too largeПромпт слишком велик для модели. Входные данные инструмента больше 50 КБ. Файл больше 10 МБ.Нет. Уменьшите размер.
422UnprocessableМодель отклонила содержимое запросаНет
429Too many requestsЛимит запросов или параллелизма ключа, занятая ёмкость модели, уже идут 10 запусков, лимит планировщикаДа, после retry-after
500Internal errorНепредвиденная ошибка в Lovely RouterДа, с задержкой
502Bad gatewayМодель дала сбой на каждом опробованном канале. Инструмент не смог запуститься (плата не взимается).Да, с задержкой
503Service unavailableИнструмент данных или браузерный агент временно недоступенДа, с задержкой

Любые другие 5xx обрабатывайте как 502. Ошибки запросов, отклонённых до обращения к модели (400 для невалидного JSON, 401, 402, 403, 404 для неизвестной модели и 429 из-за лимита ключа), никогда не тарифицируются.

Тела ошибок эндпоинтов моделей#

Эндпоинты моделей возвращают ошибки в формате вызванного API. На каждой вкладке ниже — одна и та же ошибка 401.

{"type": "error", "error": {"type": "authentication_error", "message": "Invalid or revoked API key"}}

type ошибки (Anthropic и OpenAI) или status (Gemini) для каждого кода:

СтатусAnthropic error.typeOpenAI error.type и error.codeGemini error.status
400invalid_request_errorinvalid_request_errorINVALID_ARGUMENT
401authentication_errorauthentication_errorUNAUTHENTICATED
402billing_errorinsufficient_quotaRESOURCE_EXHAUSTED
403permission_errorpermission_deniedPERMISSION_DENIED
404not_found_errornot_found_error, или not_found для неизвестного эндпоинтаNOT_FOUND
413, 422invalid_request_errorinvalid_request_errorINVALID_ARGUMENT
429rate_limit_errorrate_limit_exceededRESOURCE_EXHAUSTED
500api_errorapi_errorINTERNAL
502, 503api_errorapi_errorUNAVAILABLE
504api_errorapi_errorDEADLINE_EXCEEDED

В телах Gemini error.code всегда равен HTTP-статусу. Ветвитесь по коду статуса, а не по строке status. Ошибки, возникшие до чтения запроса, например для неизвестного эндпоинта или при непредвиденной ошибке шлюза, тоже используют формат вызванного эндпоинта.

Сообщения, которые вы можете увидеть#

СтатусСообщение
400Body must be JSON
400Unknown group 'xyz'
400, 413, 422Собственное пояснение модели, например prompt is too long
401Missing API key, Invalid or revoked API key, This API key has expired
402Insufficient balance. Top up at the dashboard.
402This API key has reached its spend limit.
403This API key is not allowed to use 'gpt-6.1-sol'.
404Model 'gpt-9' is not available. See GET /v1/models.
404Unknown endpoint /v1/embeddings
429This API key has reached its rate or concurrency limit.
429All upstream capacity for this model is busy. Retry shortly.
502The model provider returned an error. Please retry.

Каждый ответ с ошибкой содержит заголовок x-lovely-request-id, в том числе для запросов, отклонённых до обращения к модели (неверный ключ, пустой баланс, неизвестная модель). Укажите его, когда пишете в поддержку.

Тела ошибок инструментов и браузерного агента#

/v1/tools и /v1/browser возвращают все ошибки в одном формате: машиночитаемый type и сообщение, написанное для людей.

JSON
{"error": {"type": "insufficient_quota", "message": "Insufficient balance: this run can cost up to $0.3000 (100 results). Lower max_results or top up."}}
Статусerror.typeПримеры
400invalid_request_errorMissing required input: query. See GET /v1/tools/{id}., "start_url" must be an http(s) URL
401authentication_errorMissing, invalid or revoked API key, This API key has expired
402insufficient_quotaБаланса не хватает на максимальную стоимость запуска, или будет превышен лимит расходов ключа
404not_foundUnknown tool 'x'. Find one with POST /v1/tools/discover., No such run
405invalid_request_errorНеверный метод на эндпоинте хранилища секретов или файлов
409invalid_request_errorThis run is not waiting for a reply, This run has finished
413invalid_request_errorInput too large, Files are limited to 10 MB
429rate_limit_exceededAt most 10 tool runs may be running at once.
500api_errorInternal error
502, 503tool_unavailableThe tool is temporarily unavailable; you were not charged. Try again shortly.

Запуск, который начался, а затем завершился неудачей, не является HTTP-ошибкой. Объект запуска возвращается со status, равным failed, timed_out или stopped, и сообщением в error, а платите вы только за выданные результаты. См. Запуск инструмента.

Ошибки во время потока#

Когда поток уже начался, статус 200 уже отправлен, поэтому ошибки приходят в виде события внутри потока. Сбои до первого токена повторяются на другом канале, так что обычно поток либо завершается успешно, либо сразу падает с обычной HTTP-ошибкой.

Если модель перестаёт присылать данные посреди потока на 3 минуты, Lovely Router завершает поток событием ошибки в формате этого потока:

event: error
data: {"type": "error", "error": {"type": "api_error", "message": "Upstream stopped responding mid-stream"}}

Ошибка, о которой канал сообщает внутри идущего потока, заменяется обобщённым событием в том же формате (для Responses API — событием error вида {"type": "error", "code": "server_error", "message": "…"}), так что исходная формулировка канала до вас не доходит. Занятый или перегруженный канал превращается в overloaded_error у Anthropic, rate_limit_exceeded у OpenAI или RESOURCE_EXHAUSTED у Gemini с сообщением Upstream capacity for this model is busy. Retry shortly.; всё остальное становится api_error (у Gemini UNAVAILABLE) с сообщением The model provider returned an error. Please retry. Повторите запрос с самого начала; уже переданный вывод тарифицируется.

Повтор неудачных запросов#

Lovely Router уже повторяет неудачные запросы к моделям на других каналах, прежде чем вернуть ошибку. Повторяйте и на своей стороне — для случаев, которые он не может поглотить:

  • Повторяйте 429, 500, 502, 503, 504 и сетевые ошибки.
  • Ждите столько, сколько указано в заголовке retry-after, если он есть. Иначе увеличивайте задержку экспоненциально: 1, 2, 4, 8 секунд и так далее, не более 30 секунд, плюс до секунды случайного разброса, чтобы клиенты не повторяли запросы синхронно.
  • Останавливайтесь примерно после пяти попыток и сообщайте об ошибке.
  • Не повторяйте 400, 401, 403, 404, 409, 413 или 422, не изменив запрос. Повторяйте 402 только после пополнения баланса.
  • Не повторяйте вслепую старт запусков. Если у старта запуска инструмента или браузера истёк таймаут, проверьте GET /v1/tools/runs, прежде чем начинать новый. См. Повторы и идемпотентность.

Официальные SDK OpenAI и Anthropic уже дважды повторяют 429 и 5xx с задержкой. Чтобы это изменить, передайте клиенту max_retries (Python) или maxRetries (Node.js). Для обычных HTTP-вызовов используйте помощник вроде этого:

import os
import random
import time

import requests

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


def backoff(attempt, retry_after=None):
    if retry_after:
        return float(retry_after)
    return min(30, 2 ** (attempt - 1)) + random.random()


def post_with_retry(url, payload, max_attempts=5):
    headers = {"Authorization": f"Bearer {os.environ['LOVELY_API_KEY']}"}
    for attempt in range(1, max_attempts + 1):
        try:
            r = requests.post(url, json=payload, headers=headers, timeout=300)
        except (requests.ConnectionError, requests.Timeout):
            if attempt == max_attempts:
                raise
            time.sleep(backoff(attempt))
            continue
        if r.status_code in RETRYABLE and attempt < max_attempts:
            time.sleep(backoff(attempt, r.headers.get("retry-after")))
            continue
        if not r.ok:  # other 4xx, or still failing after the last attempt
            raise RuntimeError(f"{r.status_code}: {r.text[:500]}")
        return r.json()


reply = post_with_retry(
    "https://lovelyrouter.com/v1/chat/completions",
    {"model": "gpt-6.1-sol", "messages": [{"role": "user", "content": "Hello"}]},
)
print(reply["choices"][0]["message"]["content"])

В каждом формате ошибок — Anthropic, OpenAI, Gemini и собственном формате Lovely Router — есть error.message, написанный для людей. Записывайте его в лог вместе с кодом статуса и заголовком x-lovely-request-id.