Лимиты запросов
SecureCodingHub навязывает лимит в минуту и в час на каждом API-ключе. Лимиты разработаны быть невидимыми при нормальной работе и остановить убегающие скрипты до того, как они засорят платформу.
Лимиты по умолчанию
| Окно | Лимит | Заголовок |
|---|---|---|
| В минуту | 60 запросов | X-RateLimit-Window: per_minute |
| В час | 1 000 запросов | X-RateLimit-Window: per_hour |
Оба окна оцениваются на каждом запросе. Более узкое окно (60/минуту) управляет короткими всплесками; часовое окно управляет устойчивой нагрузкой. Если любое окно превышено, запрос отклоняется с 429 Too Many Requests — Вам не нужно инспектировать, какое окно сработало, только уважать заголовок Retry-After.
Ответ при отклонении
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Window: per_minute
X-RateLimit-Limit: 60
{ "error": "rate_limited" }Retry-After всегда целое число секунд — наименьшая безопасная задержка перед тем, как следующий запрос успеет. X-RateLimit-Limit отражает потолок для сработавшего окна.
Скользящие vs фиксированные окна
Окно в минуту фиксировано к календарной минуте (UTC). Запрос в 13:42:59 и в 13:43:01 попадают в разные корзины. Часовое окно — это истинное скользящее агрегирование за последние 60 минут. Это означает, что при нормальном использовании Вы никогда не сработаете часовой лимит, если только не срабатываете лимит в минуту неоднократно.
Рекомендуемое поведение клиента
- При
429спите как минимумRetry-Afterсекунд и повторите один раз. - Используйте jitter:
retryAfter + random(0, 5)секунд, чтобы избежать thundering herd, когда много воркеров достигают лимита одновременно. - Если Вы контролируете размер пакета, запускайте не более 50 запросов/минуту на ключ — это держит Вас безопасно под лимитом.
- Для высокообъёмных задач (экспорт данных, массовый провижининг пользователей) выпускайте один ключ на воркер, а не делите один ключ.
- Не относитесь к
429как к ошибке для оповещения. Оповещайте только о повторных сбоях после экспоненциального backoff.
Шаблон повторной попытки
Минимальный пример Node, уважающий Retry-After с jitter:
async function call(path) {
for (let attempt = 0; attempt < 4; attempt++) {
const res = await fetch(`https://api.limeplate.com${path}`, {
headers: { Authorization: `Bearer ${process.env.SCH_API_KEY}` },
});
if (res.status !== 429) return res;
const wait = parseInt(res.headers.get('Retry-After') || '60', 10);
const jitter = Math.floor(Math.random() * 5);
await new Promise(r => setTimeout(r, (wait + jitter) * 1000));
}
throw new Error('exhausted retries on 429');
}Запрос более высокой квоты
Большинство интеграций комфортно умещаются в лимитах по умолчанию. Если Вашей нагрузке действительно нужен более высокий потолок — например, ночное обновление Looker, выгружающее прогресс для 10 000 пользователей — пишите на support@securecodinghub.com с именем API-ключа, целью интеграции и пиковыми запросами/минуту, которые Вы ожидаете. Мы можем поднять лимиты на ключ без ротации токена.
Что не лимитируется
Входящие webhook-доставки, которые Вы принимаете от SecureCodingHub, не лимитируются с нашей стороны. Исходящие webhook-доставки, которые мы отправляем на Ваш эндпоинт, следуют отдельному расписанию повторных попыток, задокументированному в Webhook'и.