Лимиты частоты
Проектируйте под точные лимиты тарифа на ключ, заголовки ответа и безопасное поведение повторов.
Проектируйте под точные лимиты тарифа на ключ, заголовки ответа и безопасное поведение повторов.
Публичный API применяет скользящую минутную корзину запросов к каждому ключу API или токену доступа OAuth. Создание большего числа ключей для обхода лимита не поддерживается и может привести к ограничениям учётных данных или аккаунта.
Лимиты тарифов#
| Активный тариф | Запросов на ключ в минуту |
|---|---|
| Launch | 120 |
| Operate | 600 |
| Scale | 1 800 |
Учётные данные, чей аккаунт не имеет активного платного тарифа, получают 403 subscription_required до предоставления ёмкости лимита частоты. Make Agent Fast может ввести более низкие специфичные для конечной точки лимиты для необычно дорогих операций; когда это происходит, справочник конечной точки указывает их явно.
Ответ с ограничением частоты#
Когда корзина исчерпана, API возвращает 429 rate_limit_exceeded с:
HTTP/1.1 429 Too Many Requests
Retry-After: 17
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 0
X-Request-Id: 6c0b2f2e-...
Content-Type: application/jsonRetry-After — минимальное число секунд ожидания. Каждый аутентифицированный
ответ также включает X-RateLimit-Limit, X-RateLimit-Remaining и
X-RateLimit-Reset (временная метка Unix), так что приложения могут замедляться
до 429.
Реализация повтора#
Используйте экспоненциальный откат со случайным джиттером, соблюдайте больший Retry-After и ограничивайте общее число попыток.
async function requestWithRetry(url: string, init: RequestInit, attempts = 4) {
for (let attempt = 0; attempt < attempts; attempt += 1) {
const response = await fetch(url, init);
if (response.status !== 429 && response.status < 500) return response;
if (attempt === attempts - 1) return response;
const retryAfter = Number(response.headers.get("retry-after") ?? 0) * 1_000;
const exponential = 500 * 2 ** attempt;
const jitter = Math.random() * 250;
await new Promise((resolve) =>
setTimeout(resolve, Math.max(retryAfter, exponential + jitter)),
);
}
throw new Error("unreachable");
}Для POST, PATCH и DELETE сохраняйте один валидный Idempotency-Key на каждом сетевом или серверном повторе. Новый ключ идемпотентности может повторить завершённый побочный эффект.
Уменьшите объём запросов#
- Кэшируйте чтения аккаунта, сайта и конфигурации, которым не нужна свежесть реального времени.
- Запрашивайте до
100записей на страницу вместо повторных запросов очень малых страниц. - Обрабатывайте события вебхуков вместо опроса диалогов, заявок, состояния доменов или рассылок.
- Ограничивайте параллелизм воркеров на ключ API; всплеск от многих бессерверных вызовов разделяет одну корзину.
- Используйте отдельные ключи для отдельных сервисов ради изоляции и аудируемости, а не для умножения ёмкости одной нагрузки.
Таблица повторов и не-повторов#
| Ответ | Повторять? | Условие |
|---|---|---|
429 | Да | Дождитесь Retry-After, добавьте джиттер и ограничьте попытки |
500 | Иногда | Безопасные чтения или мутации, защищённые тем же ключом идемпотентности |
Конфликт обработки 409 | Да | Дождитесь его заголовка Retry-After: 2 и сохраните тот же ключ идемпотентности |
Другой 409 | Не сразу | Прочитайте текущее состояние ресурса и разрешите конфликт |
400, 401, 403, 404, 415 | Нет | Сначала исправьте ввод, учётные данные, право, путь или тип контента |
Если устойчивая нагрузка законно превышает свою корзину тарифа, уменьшите опрос, группируйте работу или обратитесь в поддержку с репрезентативными ID запросов и ожидаемым трафиком вместо добавления неограниченного цикла повторов.