Документация/API и Webhook'и/Лимиты запросов

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

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'и.