Ошибки и лимиты запросов

Форматы ответов с ошибками, полная таблица HTTP-кодов, поведение лимитов запросов и рабочая стратегия повторов для Atlas Cloud.

Форматы ответов с ошибками

Atlas Cloud возвращает три разных формата ошибок в зависимости от того, к какой части API вы обращаетесь. Определите формат, прежде чем писать парсер.

Используется эндпоинтами протоколов LLM и эндпоинтами генерации медиа:

{
  "code": 401,
  "msg": "unauthorized",
  "request_id": "…",
  "data": null
}

Каждый ответ содержит заголовок X-Request-ID. Логируйте его — это самый быстрый способ для поддержки отследить конкретный вызов.

HTTP-коды состояния

КодЗначениеЧто делать
400Некорректный запрос: неразбираемое тело, отсутствует model, неверный content type, некорректный заголовок хранения или недопустимый webhook_urlИсправьте запрос. Поле msg называет конкретную проблему
401Аутентификация не пройдена — ключ отсутствует, неизвестен или истёкПроверьте ключ. Учтите, что неверный путь URL тоже возвращает 401, поэтому проверьте и эндпоинт
402Недостаточно средств или исчерпан лимит Coding PlanПополните баланс
403Аккаунту или пользователю не разрешено действие — включая использование ключа Coding Plan на модели, которая его не принимаетПроверьте область ключа или обратитесь в поддержку
404Ресурс не найден. Для моделей это также означает модели, недоступные вашему аккаунтуСверьте ID модели с каталогом
413Тело запроса превышает 50 МБОтправьте URL вместо встроенного Base64 или сначала загрузите файл
429Достигнут лимит запросовСделайте паузу и повторите — см. ниже
451Заблокировано в вашем регионеПовторять бессмысленно
500Внутренняя ошибкаПовторите один раз, затем сообщите с указанием request ID
503Временно недоступноПовторите с отступлением
504Синхронный запрос превысил максимальное время ожиданияПерейдите на асинхронный процесс и используйте опрос

Код 401 не всегда означает, что ключ неверен. Шлюз выполняет аутентификацию до маршрутизации, поэтому опечатка в пути тоже даёт 401, а не 404. Если ключ работает в других местах, сначала проверьте URL.

Коды ошибок на уровне задачи

Когда асинхронная задача завершается неудачей, в data.error_code приходит числовой код платформы, более конкретный, чем HTTP-статус. Например, 1039 означает, что вход был отклонён модерацией контента.

В data.error находится описание для человека. Логируйте оба поля вместе с ID предсказания.

Лимиты запросов

Лимиты действуют на уровне аккаунта и на уровне модели. При превышении возвращается 429.

Эндпоинты LLM и медиа не возвращают X-RateLimit-Limit, X-RateLimit-Remaining или Retry-After. Прочитать остаток квоты из заголовков ответа нельзя — реализуйте отступление на клиенте.

Исключение — биллинговые эндпоинты /public/v1: их ответы 429 действительно содержат Retry-After.

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

Стратегия повторов

Повторяйте при 429, 500, 503 и 504, а также при сетевых сбоях. Не повторяйте 400, 401, 402, 403, 404 и 451 — результат будет тем же.

Запросы на чтение можно повторять свободно. С повторами отправки задач генерации будьте осторожны: запрос, завершившийся по таймауту, мог быть принят, и слепой повтор создаст — и оплатит — вторую задачу. Лучше отправляйте задачи асинхронно и опрашивайте их, чтобы потерянный ответ никогда не означал потерянную задачу.

import time, random, requests

RETRYABLE = {429, 500, 503, 504}

def call_with_retry(url, payload, api_key, max_attempts=4):
    for attempt in range(max_attempts):
        response = requests.post(
            url,
            json=payload,
            headers={"Authorization": f"Bearer {api_key}"},
            timeout=60,
        )
        if response.status_code not in RETRYABLE:
            return response

        if attempt == max_attempts - 1:
            break

        # Экспоненциальное отступление + джиттер, чтобы клиенты не повторяли одновременно
        delay = min(2 ** attempt, 30) * (0.5 + random.random() / 2)
        time.sleep(delay)

    return response

Ошибки при стриминге

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

Потоки также могут содержать SSE-строки-комментарии, начинающиеся с :, как сигналы keep-alive. Это не данные, и их нужно игнорировать — большинство SSE-клиентов делает это за вас, а вот самописные парсеры часто нет.

Как получить помощь

Сообщая о проблеме, укажите:

  • Заголовок X-Request-ID из неудачного ответа
  • ID предсказания, если речь об асинхронной задаче
  • Точный ID модели и время события

Написать нам можно через Поддержку.

Связанные материалы

Last updated on

On this page