Для AI-агентов: markdown этой страницы — /docs-content/errors/limits.md индекс документации — /llms.txt

Лимиты, очереди и паузы

Подробный разбор кодов, которыми API Вайбкод отвечает при ограничении частоты запросов, переполненной очереди портала и паузах на стороне Битрикс24.

Сводная таблица всех кодов API Вайбкод — Коды ошибок.

`RATE_LIMITED` (429)

Сработало одно из ограничений частоты: граница платформы Вайбкод, собственный лимит эндпоинта или лимит на стороне Битрикс24.

JSON
{
  "success": false,
  "error": {
    "code": "RATE_LIMITED",
    "message": "QUERY_LIMIT_EXCEEDED",
    "hint": "Wait 1-2 seconds and retry. Use POST /v1/batch to combine up to 50 calls in 1 request."
  }
}

Заголовки ответа:

Retry-After: 2

Поля retryAfter в теле этого отказа нет — срок повтора приходит только заголовком. Поле hint приходит не на всех путях отказа: у границы платформы тело состоит из code и message.

Причины:

  • Всплеск запросов с одного адреса превысил границу платформы — 60 запросов в секунду, считается по IP-адресу клиента. Такой отказ приходит с Retry-After: 1 и без заголовков X-RateLimit-*. У части эндпоинтов на границе действует свой, более строгий лимит.
  • Исчерпан собственный поминутный лимит эндпоинта. Он считается по API-ключу. Исключение — POST /v1/search (60 в минуту), POST /v1/batch (30 в минуту) и POST /v1/research (20 в минуту): там счётчик один на портал, и все его ключи делят его между собой.
  • Превышен лимит запросов в секунду на стороне Битрикс24. Он считается на портал.

Решение:

  • Дождаться времени из заголовка Retry-After.
  • Реализовать повторные попытки с экспоненциальной задержкой.
  • Объединять до 50 вызовов через POST /v1/batch.
  • Кэшировать справочные данные — поля, статусы, валюты.

`ERROR_LOOP_DETECTED` (429)

Вайбкод фиксирует серию одинаковых ошибок на одном ключе для одного метода Битрикс24 — и временно блокирует запрос на стороне Вайбкод, чтобы не накручивать счётчики Битрикс24. Каждый N-й запрос пробрасывается дальше: если бэкенд восстановился, блокировка снимается автоматически.

JSON
{
  "success": false,
  "error": {
    "code": "ERROR_LOOP_DETECTED",
    "message": "Vibe-side block (not a Bitrix24 limit). 12 failures on crm.deal.list in the last hour.",
    "hint": "Every 50th request will probe for recovery — keep retrying with backoff. If you suspect a platform-side issue (e.g. 5xx during an outage), platform admin can clear the block via POST /api/platform/analytics/circuit-breaker/<apiKeyId>/clear."
  }
}

Заголовки ответа:

Retry-After: 60

Поля retryAfter в теле этого отказа нет — срок повтора приходит только заголовком.

Причины:

  • В коде клиента баг: запрос с одинаковыми параметрами повторяется и стабильно даёт ошибку.
  • Платформенная авария на стороне Битрикс24 в момент серии запросов.

Решение:

  • Прочитать message — там указан конкретный метод с серией ошибок.
  • Найти источник запроса в коде, исправить параметры или логику.
  • При платформенной аварии — повторять с задержкой: каждый N-й запрос платформа пропускает для проверки восстановления, и блокировка снимается сама. Если она держится дольше самой аварии, обратитесь в поддержку.
  • Маршрут, названный в поле hint ответа, — служебный эндпоинт платформы. Своим ключом его не вызвать, и вмешательство не требуется: он адресован поддержке.

`QUEUE_OVERFLOW` (429)

Очередь запросов к Битрикс24 для конкретного портала переполнена: слишком много вызовов уже в ожидании (по умолчанию — 100 и больше). Ответ возвращается мгновенно, за миллисекунды, с HTTP-заголовком Retry-After: N (секунды).

JSON
{
  "success": false,
  "error": {
    "code": "QUEUE_OVERFLOW",
    "message": "Portal queue overloaded — 100 Bitrix24 calls already pending",
    "userMessage": "Слишком много одновременных запросов к Bitrix24 — повторите через несколько секунд.",
    "hint": "Honor the Retry-After header. Use exponential backoff with jitter for repeated failures.",
    "retryAfter": 10
  }
}

Решение:

  • Повторить запрос через Retry-After секунд, увеличивая паузу перед каждой следующей попыткой и добавляя к ней случайную величину, чтобы повторы от разных клиентов не пришли одной волной.
  • Уменьшить параллелизм на стороне клиента.
  • Объединить вызовы через POST /v1/batch.

`QUEUE_TIMEOUT` (429)

Очередь запросов к Битрикс24 для конкретного портала перегружена: больше 30 секунд ожидания.

JSON
{
  "success": false,
  "error": {
    "code": "QUEUE_TIMEOUT",
    "message": "Portal queue saturated — too many concurrent Bitrix24 calls",
    "userMessage": "Запросы к Bitrix24 в очереди дольше 30 секунд. Вероятно, на портале много одновременных операций.",
    "hint": "The request was NOT sent to Bitrix24 — safe to retry (honor Retry-After, use backoff with jitter). If this is a /search request with a wide date range, try adding \"autoWindow\": false OR narrow the date range to <14 days.",
    "retryAfter": 10
  }
}

Запрос НЕ был отправлен в Битрикс24 — безопасно повторить.

Решение:

  • Повторить через retryAfter секунд, увеличивая паузу перед каждой следующей попыткой и добавляя к ней случайную величину.
  • Уменьшить параллелизм.
  • Для /search-эндпоинтов — сузить диапазон дат либо передать autoWindow: false.
  • Объединить вызовы через POST /v1/batch.
  • Проверить таймаут на своей стороне: ожидание в очереди входит во время ответа, поэтому клиенту нужен запас — Клиентский таймаут.

`TIMEOUT_QUARANTINE` (429)

Метод несколько раз подряд не ответил вашему порталу Битрикс24 за отведённое вызову время, поэтому Вайбкод поставил пару «портал + метод» на паузу и больше не отправляет к ней запросы.

В процессе раскатки. Механизм включается на порталах постепенно. Пока он не включён на вашем, этот код не приходит: вызовы уходят в Битрикс24 как раньше и упираются в таймаут BITRIX_TIMEOUT.

JSON
{
  "success": false,
  "error": {
    "code": "TIMEOUT_QUARANTINE",
    "message": "Vibe-side block (not a Bitrix24 limit). crm.item.list timed out 5 times in a row on this portal, so calls to it are paused.",
    "hint": "Портал не отвечал на этот метод за отведённое вызову время, поэтому каждый следующий вызов только добавлял бы нагрузку. Дождитесь срока из Retry-After и НЕ сокращайте интервал повторов: агрессивный повтор занимает слот пробы восстановления и держит метод закрытым для всего портала дольше. Раз в 5 мин один вызов пропускается как проба, и первый успешный ответ снимает паузу немедленно. Облегчите запрос — меньше полей, меньше страница, более узкий фильтр: пару снимает с паузы именно лёгкий вызов.",
    "retryAfter": 288,
    "scope": "portal"
  }
}

Заголовки ответа:

Retry-After: 288

Причины:

  • Метод стабильно не отвечает порталу за отведённое вызову время. Причина — тяжёлый запрос: широкий диапазон дат, много полей в select, большая страница, фильтр по неиндексированному полю.
  • Пауза считается на пару «портал + метод» и не зависит от того, каким ключом сделан вызов: scope: "portal" означает, что её видят ВСЕ ключи портала, включая чужие интеграции. Контраст — OPERATION_TIME_LIMIT со scope: "apiKey": тот отказ про ваш ключ, этот — про весь портал.
  • Это отказ на стороне Вайбкод, а не лимит Битрикс24: запрос до портала не дошёл, поэтому ничего не изменилось — повтор безопасен даже для методов записи.
  • Код приходит и внутри 200-ответа — на подвызовах POST /v1/batch, которые Вайбкод исполняет отдельными запросами (data.errors[<id>]), и на элементах батча одной сущности (data[i].error). У 200-конверта нет заголовка Retry-After для отдельного подвызова, поэтому срок приходит полем retryAfter, а scope и hint — те же, что в одиночном 429.

Решение:

  • Дождаться срока из retryAfter (или заголовка Retry-After) и не сокращать интервал повторов: пока пауза действует, один вызов раз в 5 минут пропускается как проба восстановления, и агрессивный повтор занимает этот слот собой — метод остаётся закрытым для всего портала дольше, чем если бы вы просто подождали.
  • Добавлять к паузе случайную величину, чтобы повторы разных клиентов не пришли одной волной.
  • Облегчить сам вызов: меньше полей в select, меньше страница, более узкий фильтр или более узкий интервал дат. Пауза снимается первым успешным ответом, поэтому её снимает именно лёгкий вызов — тяжёлый снова упрётся в таймаут и продлит окно.
  • Не искать эндпоинт для снятия паузы — его нет, и вмешательство не требуется.
  • Сам конверт POST /v1/batch под паузу не попадает: он объединяет разные методы, и его собственная задержка не говорит о том, какие из них перестали отвечать.

`OPERATION_TIME_LIMIT` (429)

Битрикс24 приостановил ЭТОТ метод примерно на 5 минут, потому что метод исчерпал бюджет рабочего времени на портале. Отказ приходит и когда его прислал сам портал, и когда Вайбкод отбивает вызов на входе, зная, что пауза ещё действует.

JSON
{
  "success": false,
  "error": {
    "code": "OPERATION_TIME_LIMIT",
    "message": "Bitrix24 operation-time limiter banned crm.item.list on this portal, retry in 245s",
    "userMessage": "Битрикс24 приостановил этот запрос на несколько минут: метод исчерпал лимит рабочего времени на портале. Дождитесь срока из Retry-After — остальные методы работают.",
    "hint": "Bitrix24 banned THIS method on this portal for ~5 minutes because it exhausted the portal's operating-time budget. Honor Retry-After — the same call cannot succeed sooner and retrying earlier only adds load. Other methods on the portal are unaffected; spread heavy reads over time or narrow them (fewer fields, smaller pages, POST /v1/batch).",
    "retryAfter": 245,
    "scope": "apiKey"
  }
}

Заголовки ответа:

Retry-After: 245

Причины:

  • Бюджет рабочего времени Битрикс24 считает на скользящем окне.
  • Пауза адресная: scope: "apiKey" означает, что Битрикс24 приостановил связку «ваш ключ + этот метод». Другие методы работают, и другие ключи портала тот же метод вызывать могут. Контраст — TIMEOUT_QUARANTINE со scope: "portal": там пауза общая для всего портала.
  • Запрос не был выполнен — повтор безопасен, в том числе для методов записи.
  • Код приходит и внутри 200-ответа — на подвызовах POST /v1/batch, которые Вайбкод исполняет отдельными запросами (data.errors[<id>]), и на элементах батча одной сущности (data[i].error). У 200-конверта нет заголовка Retry-After для отдельного подвызова, поэтому срок приходит полем retryAfter, а scope и hint — те же, что в одиночном 429. Поля userMessage в конверте нет.

Решение:

  • Дождаться срока из retryAfter (или заголовка Retry-After): раньше этого срока тот же вызов не пройдёт, а повторы только добавляют нагрузку.
  • Разнести тяжёлые чтения по времени, а не запускать их пачкой.
  • Облегчить вызовы: меньше полей в select, меньше страница, объединение через POST /v1/batch.

Смотрите также