spicyapiДокументация
Справочник
Основное содержимое

Ограничения частоты запросов

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

Ограничение частоты запросов определяет, сколько запросов можно отправить за короткий промежуток времени. При превышении лимита API возвращает 429 («слишком много запросов»), не выполняя операцию, и указывает время ожидания. Это защита от скриптов, вышедших из-под контроля, а не квота на объём генерации.

Краткий обзор ограничений

ОграничениеЗначение по умолчаниюОтвет при достиженииПодробнее
Запросы на аккаунт1000 за 10 секунд для чтения и ещё столько же для записи429 с Retry-Afterниже
Запросы URL для загрузки1000 за 10 секунд429 с Retry-Afterниже
Запрошенные, но ещё не использованные URL для загрузки128 файлов или 1 GiB429, ожидание не поможетниже
Отчёт об использовании30 в минуту; период до 92 дней429 / 400ниже, Оплата
Доступный баланс—40201Оплата
Лимиты расходов ключа (дневной / месячный / за всё время)Отсутствуют, пока вы их не зададите40202Оплата
Дневной / месячный лимит командыОтсутствует40202Оплата
Команды, которыми вы владеете / участники в команде10 / 100409 в консолиКонсоль и команды

Два лимита на аккаунт: чтение и запись

Частота запросов к API — ко всем путям /api/v1/* и совместимым эндпоинтам /v1/* и /v1beta/* — ограничивается на уровне аккаунта, а не ключа. Иначе ограничение можно было бы обойти, создав дополнительные ключи.

Чтение и запись учитываются в двух отдельных корзинах токенов с одинаковыми лимитами. Защитный порог по умолчанию для каждой — 1000 запросов за 10 секунд: примерно 100 RPS (запросов в секунду) при постоянной нагрузке и всплеск до 1000 запросов. Это защита от злоупотреблений и неконтролируемых клиентов, а не низкая квота для обычной платной генерации.

Используется алгоритм корзины токенов, а не счётчик фиксированного временного окна: ёмкость — 1000 токенов, пополнение за 10 секунд (примерно 100 токенов в секунду). Каждый запрос расходует один токен; запас пополняется непрерывно. В отличие от фиксированного окна, такая корзина сглаживает пополнение на границах интервалов.

Чтение и запись расходуют разные лимиты

Чтение — все запросы GET: recordInfo, список jobs, chat/credit, usage, models, а также jobs/quote, который только рассчитывает цену запроса. Запись — остальные операции: createTask, retry, stream, purge, common/upload-url, common/download-url, а также совместимые эндпоинты chat/completions, messages и генерации Gemini. Нативные и совместимые эндпоинты используют те же два лимита, поэтому перенос текстовой интеграции с /api/v1 на /v1 не даёт дополнительную квоту.

Опрос состояния больше не может заблокировать отправку задач. Неконтролируемый цикл опроса исчерпывает только лимит чтения: recordInfo начинает возвращать 429, а запросы createTask продолжают проходить. Опрос всё равно расходует запросы, поэтому в рабочих интеграциях лучше использовать вебхуки, чтобы сократить лишние вызовы и задержку.

Каталог моделей расходует лимит чтения. Не запрашивайте неизменившуюся схему перед каждой задачей; кешируйте её по времени обновления и обновляйте после ошибок валидации.

У upload-url есть собственный защитный порог 1000 запросов за 10 секунд, который действует дополнительно к указанному выше лимиту записи. Он отдельно защищает выдачу разрешений на запись в объектное хранилище; обычные загрузки не должны приближаться к этому порогу.

У usage дополнительное ограничение гораздо строже: 30 запросов в минуту, сверх указанного выше лимита чтения. Этот эндпоинт агрегирует историю задач, поэтому один вызов требует значительно больше ресурсов, чем обычное чтение, и одного общего защитного порога недостаточно. Используйте его для сверки, а не для опроса состояния. Этот лимит также никогда не пропускает запросы при сбое проверки: если решение о допустимости запроса недоступно, он всегда возвращает 429, тогда как другие лимиты могут быть настроены на пропуск трафика в такой ситуации.

URL для загрузки, которые вы ещё не использовали

Отдельно действует ограничение: на одном аккаунте одновременно может быть не более 128 ещё не использованных URL для загрузки или URL для файлов с суммарным заявленным размером 1 GiB. Запрос ещё одного URL возвращает 429 с сообщением Too many pending uploads; finish existing uploads before requesting more, без Retry-After.

Здесь ожидание не поможет, поэтому не допускайте бесконечных повторов в общем цикле обработки ошибок. Загрузите файлы по уже запрошенным URL и подтвердите загрузку (либо дождитесь истечения срока URL — около 20 минут), и место сразу освободится. Обычно эта ошибка означает, что скрипт массово запрашивает URL для загрузки, но так и не использует их. См. Медиафайлы.

Все лимиты

Ограничения подключены по группам эндпоинтов: все запросы внутри одной группы проходят общую цепочку промежуточных обработчиков. Как пользователь API вы можете столкнуться с первыми пятью:

ЛимитЧто охватываетПо чему учитываетсяЗначение по умолчанию
(сетевой)каждый запрос к API, до проверки ключаIP-адрес источника (для IPv6 — подсеть /64)6000 в минуту — значительно выше обычной нагрузки; сотрудники одной компании за общей сетью делят этот лимит
open_apiзапись по путям /api/v1/*, /v1/* и /v1beta/* (все методы, кроме GET/HEAD, с исключением для jobs/quote)аккаунт1000 за 10 секунд (примерно 100 RPS при постоянной нагрузке)
open_api_readчтение по тем же путям: GET/HEAD (включая каталог models) и jobs/quoteаккаунт1000 за 10 секунд (примерно 100 RPS при постоянной нагрузке)
upload_url/api/v1/common/upload-urlаккаунт1000 за 10 секунд (дополнительно к open_api)
api_usage/api/v1/usageаккаунт30 в минуту (дополнительно к open_api_read)
эндпоинты консолиэндпоинты /console/v1/*, требующие авторизацииаккаунт120 в минуту для чтения и ещё столько же для записи
catalogпубличный анонимный каталог сайта (не /api/v1/models)IP-адрес источника300 в минуту

На аккаунт, а не на ключ

open_api и open_api_read учитывают запросы аккаунта. Создание новых ключей ничего не добавляет — иначе обойти ограничение можно было бы одним нажатием в консоли.

Однако upload_url и api_usage действительно используют отдельные корзины: загрузка референсного изображения расходует токен из open_api и из upload_url, а одно чтение usage — из open_api_read и из api_usage. Исчерпание любой из этих корзин приводит к 429.

Это значения по умолчанию, которые могут меняться без выпуска новой версии. Ваш текущий лимит всегда указан в заголовке X-RateLimit-Limit и в разделе Обзор консоли. Ориентируйтесь на заголовок и не фиксируйте значения по умолчанию в коде клиента.

Заголовки ответа

ЗаголовокГде присутствуетЗначение
X-RateLimit-LimitКаждый ответЛимит текущего интервала
X-RateLimit-RemainingКаждый ответОставшиеся токены
Retry-After429 из-за ограничения частотыВремя ожидания в секундах, не менее 1

Обычный ответ для аккаунта с лимитом по умолчанию содержит:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 997

X-RateLimit-Remaining передаётся и в успешных ответах, поэтому можно снизить частоту до получения 429, а не после.

При 401 эти заголовки описывают сетевой лимит (6000), а не лимит вашего аккаунта, поскольку ключ не был идентифицирован.

Как выглядит превышение лимита

{
  "code": 429,
  "msg": "Too many requests. Retry in a moment",
  "request_id": "req_…"
}

HTTP-статус 429 с Retry-After.

Запросы сверх лимита отклоняются, а не ставятся в очередь

Ответ возвращается сразу. Постановка в очередь лишь увеличивала бы задержку и оставляла соединение, которое никак не возвращает результат — это сложнее обработать, чем понятный 429. Отклонённый запрос не был принят, поэтому ничего не стоит.

Как обрабатывать ограничение

Читайте Retry-After. Не отправляйте повторные запросы с фиксированным интервалом. Примеры прекращают повторы после пяти попыток; это также не даёт бесконечно повторять запросы при описанном выше 429 из-за неиспользованных URL для загрузки.

JavaScript
async function callRespectingLimits(url, init) {
  for (let i = 0; i < 5; i++) {
    const res = await fetch(url, init);

    if (res.status !== 429) return res;

    // The server already told you how long to wait; don't guess
    const wait = Number(res.headers.get('retry-after') ?? 1);
    await new Promise((r) => setTimeout(r, wait * 1000));
  }
  throw new Error('persistently rate-limited');
}
Python
import time, requests


def call_respecting_limits(method: str, url: str, **kwargs) -> requests.Response:
    for _ in range(5):
        res = requests.request(method, url, **kwargs)

        if res.status_code != 429:
            return res

        # The server already told you how long to wait; don't guess
        time.sleep(float(res.headers.get("retry-after", 1)))

    raise RuntimeError("persistently rate-limited")

Параллельное выполнение — отдельный вопрос

Лимит регулирует частоту отправки, а не число выполняющихся задач

После принятия задачи в очередь она перестаёт расходовать лимит частоты запросов. Сотня одновременно выполняющихся генераций не приведёт к 429.

Что на самом деле ограничивает число активных задач — и это не ограничение частоты запросов:

  • Доступный баланс — под каждую активную задачу резервируются средства. Когда баланс заканчивается, новые задачи получают 40201.
  • Лимиты расходов — дневной, месячный и общий лимиты ключа, дневной и месячный лимиты команды (для принадлежащих команде ключей), а также дневной лимит платформы. Достижение любого из них приводит к 40202. См. Лимиты расходов.
  • Возможности выполнения — если модель вообще не может выполнить запрос, вы получаете 50301.

Поэтому для увеличения числа одновременно выполняющихся задач обычно нужно пополнить баланс или повысить лимит расходов, а не частоту запросов.

Как запросить увеличение лимита

Ваш текущий лимит показан в разделе Обзор консоли. Чтобы запросить увеличение, откройте обращение в разделе Поддержка (тема: Интеграция API) и опишите нагрузку: пиковое число запросов в секунду, используете ли пакетную обработку и насколько велики пакеты. Это заметно ускорит рассмотрение.

До этого ограничивайте число параллельных клиентских запросов и соблюдайте Retry-After. Выбирайте предел параллелизма исходя из нагрузки, времени генерации и доступного баланса, а не снижайте его искусственно ради соответствия стандартному лимиту частоты.

Если сам механизм ограничения недоступен

Ограничение частоты зависит от внешнего счётчика. При его сбое поведение определяется настройкой: разрешать запросы (продолжать обслуживание) или отклонять их (защищать лимит). По умолчанию запросы отклоняются — невозможность прочитать конфигурацию никогда не должна превращаться в отсутствие ограничений.

При настройке на отклонение вы получаете 429 с Retry-After: 1, а не 500. Это сделано намеренно: 500 означает сбой сервиса, а большинство клиентских SDK сразу повторяют такой запрос, увеличивая нагрузку во время инцидента. 429 с Retry-After говорит снизить частоту и вернуться позже — именно это и требуется.

Поэтому 429 не доказывает, что вы отправляли запросы слишком часто. В любом случае правильная реакция — соблюдать Retry-After.

На этой странице