Перейти к содержимому страницы
Документация
Документация Make Agent Fast

Лимиты частоты

Проектируйте под точные лимиты тарифа на ключ, заголовки ответа и безопасное поведение повторов.

Кратко

Проектируйте под точные лимиты тарифа на ключ, заголовки ответа и безопасное поведение повторов.

Путь запроса APIОграниченный ключ → версионированный ресурс → подписанный ответ
Приложение / SDKКлюч Bearermaf_live_…/api/v1/…РесурсJSON
На ключОдна минутаRetry-After

Публичный API применяет скользящую минутную корзину запросов к каждому ключу API или токену доступа OAuth. Создание большего числа ключей для обхода лимита не поддерживается и может привести к ограничениям учётных данных или аккаунта.

Лимиты тарифов#

Активный тарифЗапросов на ключ в минуту
Launch120
Operate600
Scale1 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/json

Retry-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Не сразуПрочитайте текущее состояние ресурса и разрешите конфликт
503 outcome_unknownНетМутация могла завершиться; проверьте ресурс, прежде чем использовать новый ключ идемпотентности
400, 401, 403, 404, 415НетСначала исправьте ввод, учётные данные, право, путь или тип контента

Если устойчивая нагрузка законно превышает свою корзину тарифа, уменьшите опрос, группируйте работу или обратитесь в поддержку с репрезентативными ID запросов и ожидаемым трафиком вместо добавления неограниченного цикла повторов.