Лимиты запросов
Все лимиты sliding-window. Превышение → 429 Too Many Requests:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1714050300
Retry-After: 47Все лимиты
| Область | Лимит | На что |
|---|---|---|
| User | 100 / час | POST /run/*, POST /queue/* |
| API-ключ | 1000 / час | Любая ручка через ключ |
| API-ключ | monthlyLimitRub (опц.) | Расход ₽ на ключ за месяц → 429 key_limit_exceeded |
| User | 5 одновременных | SSE-стримы прогресса |
| IP | 100 / 1 мин | POST /webhooks/* |
Retry-стратегия
async function callWithRetry(url, init, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const resp = await fetch(url, init)
if (resp.status !== 429 && resp.status !== 503) return resp
if (attempt === maxRetries) return resp
const retryAfter = Number(resp.headers.get('Retry-After')) || 1
await new Promise(r => setTimeout(r, retryAfter * 1000))
}
}503 provider_error тоже отдаёт Retry-After — это circuit breaker, временная проблема, повторите через Retry-After секунд. Стратегия та же.
Месячный лимит на ключ
В дашборде у каждого ключа можно поставить cap расхода в рублях за календарный месяц. Превышение → 429 key_limit_exceeded. Сбрасывается 1 числа.
Удобно для:
- ограничения партнёрской интеграции;
- sandbox-ключа с маленьким cap для тестов;
- защиты production от непредвиденного расхода.
Что НЕ ограничено
GETручки (/models,/me/balance,/me/transactions) — только глобальный 1000/час./health,/openapi.json,/docs— публичные.
Заголовки в CORS
X-RateLimit-* и Retry-After экспонируются в browser fetch — читаемы из JS на клиенте.
Дальше
- Коды ошибок — как ветвить по
error. - Асинхронная очередь и SSE — как не упереться в лимит SSE.