For AI agents: markdown of this page — /docs-content-en/errors/limits.md documentation index — /llms.txt

Limits, queues, and pauses

A detailed breakdown of the codes the Vibecode API returns when the request rate is throttled, the account queue is full, or Bitrix24 pauses a method.

The summary table of all Vibecode API codes — Error codes.

`RATE_LIMITED` (429)

One of the rate restrictions fired: the Vibecode platform edge, an endpoint's own limit, or a limit on the Bitrix24 side.

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."
  }
}

Response headers:

Retry-After: 2

The body of this refusal carries no retryAfter field — the retry deadline arrives only in the header. The hint field does not arrive on every refusal path: at the platform edge the body consists of code and message.

Causes:

  • A burst of requests from one address exceeded the platform edge — 60 requests per second, counted per client IP address. Such a refusal arrives with Retry-After: 1 and without X-RateLimit-* headers. Some endpoints carry their own, stricter limit at the edge.
  • An endpoint's own per-minute limit is exhausted. It is counted per API key. The exceptions are POST /v1/search (60 per minute), POST /v1/batch (30 per minute) and POST /v1/research (20 per minute): there the counter is one per Bitrix24 account, and all of its keys share it.
  • The requests-per-second limit on the Bitrix24 side was exceeded. It is counted per account.

Solution:

  • Wait for the time given in the Retry-After header.
  • Implement retries with exponential backoff.
  • Combine up to 50 calls through POST /v1/batch.
  • Cache reference data — fields, statuses, currencies.

`ERROR_LOOP_DETECTED` (429)

Vibecode records a series of identical errors on one key for one Bitrix24 method and temporarily blocks the request on the Vibecode side, so as not to run up the Bitrix24 counters. Every Nth request is passed through: if the backend has recovered, the block is lifted automatically.

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."
  }
}

Response headers:

Retry-After: 60

The body of this refusal carries no retryAfter field — the retry deadline arrives only in the header.

Causes:

  • A bug in the client code: a request with identical parameters repeats and consistently fails.
  • A platform-wide outage on the Bitrix24 side during the series of requests.

Solution:

  • Read message — it names the specific method with the series of errors.
  • Find the source of the request in the code and fix the parameters or the logic.
  • During a platform outage, retry with a delay: the platform lets every Nth request through to check for recovery, and the block lifts on its own. If it holds longer than the outage itself, contact support.
  • The route named in the hint field of the response is an internal platform endpoint. Your key cannot call it, and no intervention is required: it is meant for support.

`QUEUE_OVERFLOW` (429)

The queue of requests to Bitrix24 for a specific account is full: too many calls are already waiting (100 or more by default). The response returns instantly, within milliseconds, with the Retry-After: N HTTP header (seconds).

JSON
{
  "success": false,
  "error": {
    "code": "QUEUE_OVERFLOW",
    "message": "Portal queue overloaded — 100 Bitrix24 calls already pending",
    "userMessage": "Too many concurrent requests to Bitrix24 — retry in a few seconds.",
    "hint": "Honor the Retry-After header. Use exponential backoff with jitter for repeated failures.",
    "retryAfter": 10
  }
}

Solution:

  • Retry the request after Retry-After seconds, increasing the pause before each subsequent attempt and adding a random amount to it, so that retries from different clients do not arrive in one wave.
  • Reduce concurrency on the client side.
  • Combine calls through POST /v1/batch.

`QUEUE_TIMEOUT` (429)

The queue of requests to Bitrix24 for a specific account is saturated: more than 30 seconds of waiting.

JSON
{
  "success": false,
  "error": {
    "code": "QUEUE_TIMEOUT",
    "message": "Portal queue saturated — too many concurrent Bitrix24 calls",
    "userMessage": "Bitrix24 requests have been queued for more than 30 seconds. The Bitrix24 account likely has many concurrent operations.",
    "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
  }
}

The request was NOT sent to Bitrix24 — it is safe to retry.

Solution:

  • Retry after retryAfter seconds, increasing the pause before each subsequent attempt and adding a random amount to it.
  • Reduce concurrency.
  • For /search endpoints, narrow the date range or pass autoWindow: false.
  • Combine calls through POST /v1/batch.
  • Check the timeout on your side: waiting in the queue counts toward the response time, so the client needs headroom — Client-side timeout.

`TIMEOUT_QUARANTINE` (429)

The method failed to answer your Bitrix24 account several times in a row within the time allowed for the call, so Vibecode paused the "account + method" pair and no longer sends requests to it.

The rollout is in progress. The mechanism is being enabled on accounts gradually. Until it is enabled on yours, this code does not arrive: calls go to Bitrix24 as before and hit the BITRIX_TIMEOUT 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": "The portal was not answering this method within the call timeout, so every further call would only add load. Honor Retry-After and do NOT shorten your retry interval: an aggressive retry occupies the recovery-probe slot and keeps the method closed for the whole portal longer. One call is let through as a probe every 5 minutes, and the first success lifts the pause immediately. Narrow the request — fewer fields, a smaller page, a tighter filter: a lighter call is what recovers the pair.",
    "retryAfter": 288,
    "scope": "portal"
  }
}

Response headers:

Retry-After: 288

Causes:

  • The method consistently fails to answer the account within the time allowed for the call. The reason is a heavy request: a wide date range, many fields in select, a large page, a filter on a non-indexed field.
  • The pause is tracked per "account + method" pair and does not depend on which key made the call: scope: "portal" means that ALL keys of the account see it, including third-party integrations. Contrast that with OPERATION_TIME_LIMIT and its scope: "apiKey": that refusal is about your key, this one is about the whole account.
  • This is a refusal on the Vibecode side, not a Bitrix24 limit: the request never reached the account, so nothing changed — a retry is safe even for write methods.
  • The code also arrives inside a 200 response — on the subcalls of POST /v1/batch that Vibecode executes as separate requests (data.errors[<id>]), and on the items of a single-entity batch (data[i].error). A 200 envelope has no Retry-After header for an individual subcall, so the deadline arrives in the retryAfter field, while scope and hint are the same as in a standalone 429.

Solution:

  • Wait for the deadline from retryAfter (or from the Retry-After header) and do not shorten the retry interval: while the pause holds, one call every 5 minutes is let through as a recovery probe, and an aggressive retry takes that slot for itself — the method stays closed for the whole account longer than if you had simply waited.
  • Add a random amount to the pause, so that retries from different clients do not arrive in one wave.
  • Make the call itself lighter: fewer fields in select, a smaller page, a narrower filter, or a narrower date interval. The pause is lifted by the first successful response, so it is a light call that lifts it — a heavy one hits the timeout again and extends the window.
  • Do not look for an endpoint that lifts the pause — there is none, and no intervention is required.
  • The POST /v1/batch envelope itself is never paused: it combines different methods, and its own latency says nothing about which of them stopped answering.

`OPERATION_TIME_LIMIT` (429)

Bitrix24 paused THIS method for about 5 minutes because the method exhausted the operating-time budget on the account. The refusal arrives both when it comes from the Bitrix24 account itself and when Vibecode rejects the call up front, knowing that the pause is still in effect.

JSON
{
  "success": false,
  "error": {
    "code": "OPERATION_TIME_LIMIT",
    "message": "Bitrix24 operation-time limiter banned crm.item.list on this portal, retry in 245s",
    "userMessage": "Bitrix24 paused this request for several minutes: the method exhausted its operating-time limit on the Bitrix24 account. Wait out the Retry-After delay — other methods keep working.",
    "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"
  }
}

Response headers:

Retry-After: 245

Causes:

  • Bitrix24 counts the operating-time budget over a sliding window.
  • The pause is targeted: scope: "apiKey" means that Bitrix24 paused the "your key + this method" pair. Other methods keep working, and other keys of the account can call the same method. Contrast that with TIMEOUT_QUARANTINE and its scope: "portal": there the pause is shared by the whole account.
  • The request was not executed — a retry is safe, including for write methods.
  • The code also arrives inside a 200 response — on the subcalls of POST /v1/batch that Vibecode executes as separate requests (data.errors[<id>]), and on the items of a single-entity batch (data[i].error). A 200 envelope has no Retry-After header for an individual subcall, so the deadline arrives in the retryAfter field, while scope and hint are the same as in a standalone 429. The envelope carries no userMessage field.

Solution:

  • Wait for the deadline from retryAfter (or from the Retry-After header): the same call will not go through before that deadline, and retries only add load.
  • Spread heavy reads over time instead of firing them all off at once.
  • Make the calls lighter: fewer fields in select, a smaller page, combining through POST /v1/batch.

See also