> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ycloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Ограничения частоты запросов

> Проверяйте квоты YCloud API, считывайте заголовки ограничений частоты запросов и безопасно повторяйте запросы, ограниченные лимитами.

YCloud ограничивает количество запросов к API в пределах временного окна. Лимиты применяются к аккаунту, отправителю или группе эндпоинтов. При превышении лимита возвращается HTTP-ответ `429 Too Many Requests` со стандартным [ответом об ошибке](/ru/api-reference/guides/api-fundamentals/handle-errors).

## Лимиты Messaging API

`rps` означает количество запросов в секунду (rps). Отправитель — это рабочий номер телефона WhatsApp.

| Эндпоинт | Ограничение частоты | Область действия |
| - | - | - |
| `POST /v2/emails` | 200 rps | На аккаунт |
| `POST /v2/sms` | 200 rps | На аккаунт |
| `POST /v2/voices` | 200 rps | На аккаунт |
| `POST /v2/whatsapp/messages` | 200 rps | На отправителя |
| `POST /v2/whatsapp/messages/sendDirectly` | 80 rps по умолчанию; 1000 rps после автоматического повышения пропускной способности при соответствии условиям | На отправителя |

Для большинства эндпоинтов действует ограничение 200 rps на аккаунт. Для эндпоинтов отправки WhatsApp действуют лимиты на отправителя, указанные выше. Ознакомьтесь с [документацией Meta по пропускной способности](https://developers.facebook.com/docs/whatsapp/cloud-api/overview#throughput) касательно автоматических повышений.

### Асинхронная и прямая отправка сообщений WhatsApp

YCloud учитывает лимиты для двух эндпоинтов отправки WhatsApp раздельно. Эндпоинт отправки через очередь `/v2/whatsapp/messages` принимает до 200 rps на отправителя, в то время как YCloud передает сообщения из очереди в Meta со скоростью 60 rps. Помещение сообщения в очередь не означает, что Meta приняла или доставила его.

Избегайте одновременной отправки с высокой частотой через оба эндпоинта от одного и того же отправителя. При отправке через очередь и прямой отправке используется один и тот же рабочий номер телефона WhatsApp, поэтому их суммарный трафик может достигнуть лимита Meta и привести к ошибкам.

## Лимиты Management API

Большинство API без отдельно задокументированных правил относятся к Management API. Эти эндпоинты делят общую квоту аккаунта: **200 запросов в секунду и 10 000 запросов в час**. Применяются оба лимита: невозможно непрерывно отправлять 200 rps в течение всего часа. Запросы к одному эндпоинту управления расходуют квоту, доступную для остальных.

Общие правила распространяются на:

* `/v2/balance`
* `/v2/webhookEndpoints/*`
* `/v2/whatsapp/businessAccounts/*`
* `/v2/whatsapp/phoneNumbers/*`
* `/v2/whatsapp/templates/*`
* `/v2/whatsapp/messages/{id}`
* Другие API без отдельно задокументированных правил

## Чтение заголовков с информацией об ограничениях частоты

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

| Заголовок | Значение |
| - | - |
| `Retry-After` | Количество секунд ожидания перед повторной попыткой или отправкой следующего запроса. |
| `RateLimit-Limit` | Максимальное количество единиц квоты для аккаунта или отправителя в указанном временном окне. |
| `RateLimit-Policy` | Информационные правила квот и соответствующие временные окна. Например, `100;w=60` описывает 100 единиц квоты за 60 секунд. |
| `RateLimit-Remaining` | Количество единиц квоты, еще доступных для указанного лимита. |
| `RateLimit-Reset` | Количество секунд до сброса указанной квоты. |

<Note>
  Заголовки `RateLimit-*` находятся на этапе бета-тестирования и могут измениться. Описанный формат
  заголовков YCloud следует спецификации IETF draft-06 для rate limit. Рассматривайте параметры
  правил как информационные и настраивайте клиент так, чтобы он был устойчив
  к появлению дополнительных параметров.
</Note>

### Пример: исчерпана общая почасовая квота

```http theme={"theme":{"light":"github-light","dark":"github-dark"}}
HTTP/2 429
Content-Type: application/json
Retry-After: 1800
RateLimit-Limit: 10000
RateLimit-Policy: 200;w=1;burst=200;algorithm=token_bucket;level=account;scope=management_api, 10000;w=3600;algorithm=fixed_window;level=account;scope=management_api
RateLimit-Remaining: 0
RateLimit-Reset: 1800
```

Аккаунт исчерпал общую квоту в **10 000 запросов в час** . Подождите не менее 1800 секунд перед отправкой следующего запроса в рамках этой квоты. Переход на другой эндпоинт управления не предоставит новую квоту.

## Обработка ответа `429`

1. Приостановите запросы, использующие исчерпанную квоту аккаунта или отправителя.
2. Учитывайте заголовок `Retry-After`, если он присутствует. Не повторяйте попытку до истечения указанного времени задержки.
3. Снизьте уровень параллелизма и добавьте экспоненциальную задержку (exponential backoff) со случайным разбросом (jitter).
4. Ограничивайте количество повторных попыток числом попыток или таймаутом вашего приложения.
5. Логируйте эндпоинт, HTTP-метод, ошибку `code`, `requestId` и время запроса.
   Исключайте ключи API и персональные данные.

Если успешный ответ содержит `Retry-After`, отложите последующие запросы; не отправляйте повторно уже выполненный запрос. Отслеживайте `RateLimit-Remaining` и `RateLimit-Reset`, чтобы снизить частоту отправки до исчерпания квоты.

### Повторная отправка с задержкой и случайным разбросом (backoff and jitter)

В этом примере на JavaScript значение `Retry-After` рассматривается как минимальное время ожидания. Максимальный предел задержки ограничивает разброс приложения; он не сокращает время ожидания, запрошенное сервером. Количество попыток и настройки задержки определяются логикой приложения, а не лимитами API.

```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
async function requestWithBackoff(url, options) {
  const maxAttempts = 5;
  const baseDelayMs = 500;
  const maxBackoffMs = 30_000;

  for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
    const response = await fetch(url, options);
    if (response.status !== 429) return response;
    if (attempt === maxAttempts - 1) {
      throw new Error("YCloud API rate limit persisted after retries");
    }

    const header = response.headers.get("Retry-After");
    const seconds = header === null ? NaN : Number(header);
    const serverDelayMs = Number.isFinite(seconds) && seconds >= 0
      ? seconds * 1000
      : 0;
    const backoffCap = Math.min(maxBackoffMs, baseDelayMs * 2 ** attempt);
    const delayMs = Math.max(serverDelayMs, Math.random() * backoffCap);
    await response.body?.cancel();
    await new Promise((resolve) => setTimeout(resolve, delayMs));
  }
}
```

Используйте этот пример только в тех случаях, когда операцию безопасно повторять. Для длительного ожидания используйте очередь с расписанием, чтобы воркеру не приходилось оставаться активным.

## Управление параллелизмом и повторными попытками

Используйте очередь ограниченного размера и общий лимит воркеров. Избегайте независимых циклов повторных попыток, каждый из которых предполагает доступность полной квоты аккаунта или отправителя. Восстанавливайте объем трафика постепенно после окончания ограничения.

Повторный запрос `POST` может создать еще один ресурс или отправить еще одно сообщение. Сначала ознакомьтесь с рекомендациями по повторным попыткам для конечной точки и сохраненным результатом. Где это поддерживается, сохраняйте постоянный `externalId`, но не рассматривайте его как универсальный ключ идемпотентности. Сохраняйте ID ответа YCloud и устраняйте неоднозначные результаты перед повторной отправкой.

Отслеживайте объем запросов, ответы `429`, задержку, количество повторных попыток и время нахождения в очереди в разрезе конечных точек и отправителей. См. [Рекомендации по работе с WhatsApp Messages API](/ru/api-reference/guides/whatsapp-platform/whatsapp-messages-api-best-practices) касательно постановки в очередь, сверки и предотвращения дублирования.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.