[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"docs-ai\u002Fchat\u002Frate-limits":3,"docs-tabs-ai\u002Fchat\u002Frate-limits":6},{"content":4,"lastmod":5},"\n## Лимиты запросов и повторы\n\nОбращения к моделям ограничены двухуровневой корзиной, а при пиковой нагрузке платформа может ненадолго отказывать в обслуживании. Оба сигнала — `429` и `503` — означают «повтори позже», а не «запрос неверен». Ни один из них не списывает квоту.\n\n## Два уровня корзины\n\n- **На ключ** — по умолчанию `600` запросов в минуту. Корзина привязана к ключу, а не к IP-адресу: клиент за NAT не делит её с другими ключами, а один и тот же ключ с разных адресов имеет общий счётчик.\n- **На пользователя** — по умолчанию `1500` запросов в минуту суммарно по всем ключам одного пользователя. Это защищает платформу, когда один аккаунт раздаёт десяток ключей агентам и каждый выбирает свой лимит.\n\nЗапрос проверяется сначала по ключу, затем по пользователю. Первый исчерпанный счётчик выдаёт `429`.\n\nДля отдельных ключей — партнёрских интеграций, пакетных обработчиков — администратор платформы может поднять лимит на ключ. Лимит на пользователя при этом продолжает действовать.\n\n## Ответ `429`\n\n```json\n{\n  \"error\": {\n    \"type\": \"rate_limit_exceeded\",\n    \"code\": \"rate_limit_exceeded\",\n    \"message\": \"Rate limit exceeded (per-key). Limit: 600 per minute. Retry after 12 seconds.\",\n    \"scope\": \"per-key\",\n    \"limit\": 600,\n    \"retryAfter\": 12\n  }\n}\n```\n\nПоле `scope` принимает одно из двух значений:\n\n- `per-key` — исчерпан лимит конкретного ключа. Снизьте число одновременных запросов этого ключа.\n- `per-user` — исчерпан общий лимит аккаунта. Снизьте суммарную нагрузку по всем ключам или попросите администратора платформы поднять лимит.\n\nВместе с `429` приходят заголовки:\n\n- `Retry-After: \u003Cсекунды>` — сколько ждать перед следующей попыткой.\n- `X-RateLimit-Scope: per-key | per-user` — уровень, в который упёрлись. Полезно для логов и метрик клиента.\n\nЛимит проверяется после проверки ключа, поэтому запросы с некорректным ключом (`401`) квоту не расходуют.\n\n## Транзитные `503 pool_exhausted`\n\nПомимо `429`, который означает превышение клиентской квоты, платформа может отдать `503` с кодом `pool_exhausted`, когда внутренний пул соединений временно исчерпан — например, при одновременном пике у нескольких клиентов. Это сигнал «попробуй ещё раз через несколько секунд», а не «инфраструктура сломана». Ответ всегда содержит заголовок `Retry-After` — целое число секунд от 3 до 7, со случайным разбросом на стороне сервера, чтобы массовое восстановление не било повторно в пул.\n\n```json\n{\n  \"error\": {\n    \"code\": \"pool_exhausted\",\n    \"type\": \"server_error\",\n    \"retryAfter\": 5\n  }\n}\n```\n\nВ потоковом режиме (`stream: true`) статус `200` уже отправлен до того, как платформа узнаёт о перегрузке, поэтому сигнал приходит последним событием потока: `data: { \"error\": { \"code\": \"pool_exhausted\", \"retryAfter\": \u003Cчисло> } }`, после чего идёт обычный `data: [DONE]`. Распознайте `code === \"pool_exhausted\"` и повторите запрос через `retryAfter` секунд.\n\nЕсть и третий сигнал перегрузки — `429 ai_congested`. Он приходит, когда перегружен пул AI-кластера. Запрос при этом не выполнялся и списания нет. Отличить его от превышения квоты можно по заголовку `X-AI-Admission: shed`, которого нет у ответа `429 rate_limit_exceeded`.\n\n## Ответ `429 ai_pacing_limited`\n\nЧетвёртый ответ со статусом `429` не связан с нагрузкой на платформу. Он приходит, когда администратор портала включил равномерное расходование AI-квоты и вызов пробил суточное или недельное окно. Тело такого ответа приходит в конверте `{ \"success\": false, \"error\": { ... } }`, а не в сыром формате остальных ошибок этой страницы, и несёт поля `reason`, `overageDenied` и `resetAt`. Разбор полей и режимов — на странице [AI-квота компании](\u002Fdocs\u002Fai\u002Fconsumption\u002Fquota).\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 429 | `rate_limit_exceeded` | Превышен лимит запросов. Уровень — в поле `scope` и заголовке `X-RateLimit-Scope` |\n| 429 | `ai_congested` | Пул AI-кластера перегружен. Запрос не выполнялся, списания нет. Ответ несёт заголовок `X-AI-Admission: shed` |\n| 429 | `ai_pacing_limited` | Пробито суточное или недельное окно равномерного расходования квоты. Повторите запрос по заголовку `Retry-After` |\n| 503 | `pool_exhausted` | Платформа временно перегружена. Повторите запрос через число секунд из `Retry-After` |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Готовый рецепт повторов\n\n```javascript\nasync function callWithBackoff(makeRequest, { maxAttempts = 5 } = {}) {\n  for (let attempt = 0; attempt \u003C maxAttempts; attempt++) {\n    const res = await makeRequest()\n    if (res.status === 429 || res.status === 503) {\n      const retryAfterSec = Number(res.headers.get('retry-after')) || 0\n      \u002F\u002F Соблюдаем Retry-After и добавляем небольшой случайный разброс,\n      \u002F\u002F чтобы параллельные обработчики не возвращались синхронно.\n      const baseMs = retryAfterSec * 1000 || Math.min(1000 * 2 ** attempt, 30000)\n      const jitterMs = Math.floor(Math.random() * 1000)\n      await new Promise(r => setTimeout(r, baseMs + jitterMs))\n      continue\n    }\n    return res\n  }\n  throw new Error('Повторы исчерпаны')\n}\n```\n\nЧто важно:\n\n- **Всегда соблюдайте `Retry-After`.** Он соответствует ожидаемому времени восстановления, меньший интервал ничего не ускоряет, а только нагружает платформу.\n- **Добавляйте собственный случайный разброс** поверх серверного — задержка в 100-1000 мс разрывает синхронные циклы обработчиков.\n- **Ограничивайте количество попыток.** Пяти достаточно для большинства сценариев, дальше возвращайте ошибку наружу.\n- **При `5xx` без `Retry-After`**, например при сбое на стороне провайдера, увеличивайте паузу по экспоненте: `min(2^attempt × 1s, 30s)` со случайным разбросом.\n- **Не запускайте `Promise.all` поверх тысяч записей.** Без пауз пакетная обработка упрётся в один из уровней корзины.\n\n## Смотрите также\n\n- [Создать чат-комплишен](.\u002Fcompletions.md)\n- [Потоковая передача](.\u002Fstreaming.md)\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization)\n- [Ошибки](\u002Fdocs\u002Ferrors)\n","2026-07-10",{}]