For AI agents: markdown of this page — /docs-content-en/changelog/2026-09-13.md documentation index — /llms.txt

API changes: September 13, 2026

← Changelog · September 2026

FIX-0913-1: the API description now names the refusals shared by every operation

Before

The machine-readable description (/v1/openapi.json) did not name the refusals produced not by the endpoints themselves but by shared platform layers — and a client generated from the description met them as an unknown answer.

The balance refusal 402 ACCOUNT_FROZEN (the account is frozen for debt) is possible on any key-authenticated operation except a few informational and service ones — and was described on 22 operations out of 842. The answers 429 RATE_LIMITED (Bitrix24 limited the call rate), 429 ERROR_LOOP_DETECTED, 429 QUEUE_OVERFLOW, 429 QUEUE_TIMEOUT, 429 OPERATION_TIME_LIMIT, 429 TIMEOUT_QUARANTINE, 502 BITRIX_UNAVAILABLE (Bitrix24 is unavailable) and 503 BITRIX_TIMEOUT (Bitrix24 did not answer in time) are possible on every operation that calls Bitrix24 — 502 BITRIX_UNAVAILABLE was described on 11 operations, 503 BITRIX_TIMEOUT on 4, the rest almost nowhere. The operations of workflow templates, robots and activities (/v1/bizproc-templates, /v1/bizproc-robots, /v1/bizproc-activities) answer a personal key with 403 OAUTH_REQUIRED — the description was silent; GET /v1/triggers described only success while Bitrix24 answers a personal key with 403 BITRIX_ACCESS_DENIED. The 400 INVALID_PARAMS answer to a non-numeric record id in the path was described on the record read of no entity with a numeric id (GET /v1/tasks/{id}, GET /v1/workgroups/{id} and the rest) nor on most of the task, scrum, timeline and timeline-log sub-resource endpoints.

After

Endpoint behaviour is unchanged — the description is corrected. The successful responses remain the same 200, 201 and 204 they were: the description of the refusals changes, the response does not.

402 ACCOUNT_FROZEN is described on exactly the operations the shared freeze gate can refuse: every key-authenticated operation except GET /v1/me, GET /v1/me/sources, GET /v1/guide, the four feedback-conversation calls (GET /v1/feedback, POST /v1/feedback, GET /v1/feedback/{id}, POST /v1/feedback/{id}/comments) and DELETE /v1/cowork/key. The description states that the refusal arrives before any check of the operation itself and always in the common response envelope (on the OpenAI-compatible AI operations too), and that as the narrowing rolls out the refusal will remain only on wallet-paid operations — a successful answer on a frozen account does not mean the account is clear (the state is infraState in the GET /v1/me response).

429, 502 and 503 with the codes listed above are described on the operations that call Bitrix24: the generated entity operations (list, read, create, update, delete, search, batch, import, aggregate, relations, product rows, actions — except GET /v1/{entity}/fields, which answers a Bitrix24 failure with 200, the static field set and a fields_partial warning), the batch call POST /v1/batch (with a set of its own: a Bitrix24 rate limit on the envelope itself arrives not as 429 but as 502 BITRIX_UNAVAILABLE in its usual form or 422 BITRIX_ERROR, with the Bitrix24 code in error.bitrixError.error; 429 there is the batch budget and the queue), and the hand-written families: the task sub-resources, scrum, timeline, timeline log, workday, calls, workflows (/v1/workflows), CRM custom fields (/v1/userfields), stage history, file upload, duplicate search, GET /v1/addresses/fields, POST /v1/doc-templates. Where an operation already had a 429 of its own (the read or batch budget, the endpoint's own limit), its own 502 or 503, the previous text is kept and extended. Each such operation also describes 422 BITRIX_ERROR — the common answer to a Bitrix24 error that falls under no narrower code.

All operations of the three workflow entities describe 403 OAUTH_REQUIRED; on writes, next to WRITE_BLOCKED_READONLY_KEY. GET /v1/triggers and POST /v1/triggers/fire describe 401, 403 (SCOPE_DENIED, BITRIX_ACCESS_DENIED, and WRITE_BLOCKED_READONLY_KEY on firing), 422 and, on firing, 400 (MISSING_PARAMS, INVALID_ENTITY_TYPE, INVALID_ENTITY_TYPE_ID).

400 INVALID_PARAMS to a non-numeric record id is described on the record read, update and delete of every entity with a numeric id and on the task, scrum, timeline, timeline-log, call transcript (GET /v1/activities/{activityId}/transcript), workgroup member and lead conversion endpoints. The endpoint-specific codes of the same refusal are named where an endpoint answers with them: INVALID_DYNAMIC_PARAM (all smart-process operations by {entityTypeId}), INVALID_ENTITY_TYPE_ID (a smart-process record, smart-process custom fields, CRM card configuration), INVALID_ROW_ID (a product row), INVALID_ANCHOR (requisite links), VALIDATION_ERROR (configurable activities), INVALID_ID (an employee photo), INVALID_BOT_ID (bot ownership transfer), UNKNOWN_ENTITY (CRM custom fields by {entity}).

What the description STILL does not name — deliberately: the daily call-quota refusal (429 QUOTA_EXCEEDED) is shared by the whole API and is outside this change; on the batch reads that report a Bitrix24 refusal inside the successful answer, per sub-call (POST /v1/mail/mailboxes/batch, POST /v1/tasks/{taskId}/comments/batch), no response-level Bitrix24 refusal is described — there is none.

The shared answers live in the reusable description components AccountFrozen, PortalRateLimited, PortalUnavailable, PortalTimeout and OauthAppKeyRequired. The interactive reference (/docs → API reference) has been regenerated from the corrected description in both segments. Code details — on the Errors page.

NEW-0913-2: a Partner Connect application requests the vibe:ai scope itself

vibe:ai is now listed among the scopes of a Connect application at registration and on edit — like any Bitrix24 scope, with no request form and no review. From there the scope travels the usual path: the application passes it in the scope parameter of /v1/connect/authorize, the user sees an "AI models" line on the consent page and confirms the set as a whole, and the issued key carries the scope. AI Router calls made with such a key work, and consumption is covered by the account's monthly AI allowance.

The scope is never added automatically: an application that did not ask for it behaves exactly as before, and previously issued keys keep their scope sets. The other platform scopes — vibe:search, vibe:infra, vibe:storage, vibe:feedback — are granted by a platform administrator, and a self-registration request carrying them is rejected with SCOPE_NOT_ALLOWED. The /.well-known/oauth-authorization-server document lists vibe:ai in its scopes_supported field.

FIX-0913-3: product rows of a missing record now answer "not found", like the sibling methods

Before

GET /v1/deals/{id}/products on a nonexistent id answered 403 BITRIX_ACCESS_DENIED — that is how Bitrix24 answers a product-row request for an owner that does not exist, and VibeCode passed the answer through as is. The sibling methods on the same id — the record itself, its contacts, writing product rows — answered 404 ENTITY_NOT_FOUND. A client that received "access denied" went to check permissions instead of checking the id. The same for leads, quotes, invoices and smart-process items.

After

When Bitrix24 refuses a product-row read, VibeCode checks the record itself once — with the same call GET /v1/{entity}/{id} makes. The record does not exist — the answer is 404 ENTITY_NOT_FOUND, like the sibling methods. The record exists but the employee's permissions restrict it — still 403 BITRIX_ACCESS_DENIED. Successful requests make no extra call. OpenAPI declares the 404 response for the method; the invoices page no longer describes 403 as the answer for a missing record.

Affected endpoints: GET /v1/deals/{id}/products, GET /v1/leads/{id}/products, GET /v1/quotes/{id}/products, GET /v1/invoices/{id}/products, GET /v1/items/{entityTypeId}/{id}/products.

FIX-0913-4: the account freeze is checked for an application key even without a user session

Before

An application key (vibe_app_*) sent without an Authorization: Bearer header carrying a user session was not checked against the account freeze: the call went on to the operation's own checks. On a frozen account such a key passed through the doors paid for from the Vibe credits balance — creating an application with its paired key, uploading and downloading ticket attachments, updating a ticket, search and deep research, the server list — whereas a personal key and the same application key with a session received 402 ACCOUNT_FROZEN.

After

The freeze is a state of the account, not of the session: on a frozen account an application key without a session answers 402 ACCOUNT_FROZEN exactly where a personal key does — the set of closed and open calls is described in the "What the account freeze closes" section. The calls open under the freeze — the self-description, the reference, the spec, the support conversation — stay open for such a key too. On an account that is not frozen the responses do not change: the successful response is preserved.

Impact on integrators

Nothing changes for the client. If an integration used an application key without a session and suddenly receives 402 ACCOUNT_FROZEN on a frozen account, the key is not broken — the account is in debt: top up the balance; the account state is visible in the infraState block of GET /v1/me.

FIX-0913-5: the batch call answers 429 ERROR_LOOP_DETECTED instead of 500 when the platform paused it after a series of refusals

Before

When the batch calls of one key kept being refused by Bitrix24 and the Vibecode platform temporarily paused them (see ERROR_LOOP_DETECTED), POST /v1/batch itself answered 500 INTERNAL_ERROR with no Retry-After header and no hint — while every other operation in the same state answers 429 ERROR_LOOP_DETECTED. The client read an internal platform error where the platform's own protective mechanism was at work, and did not know how long to wait.

After

POST /v1/batch answers 429 ERROR_LOOP_DETECTED with a Retry-After header, and error.message and error.hint carry the number of refusals in the last hour and how often a probe request is let through to check that the series is over. The individual calls inside a batch already received this code in data.errors.<id> — only the answer to the whole batch changed.

Impact on integrators

Nothing to change. A handler that honours the Retry-After pause on 429 ERROR_LOOP_DETECTED now covers the batch call too. If an alert was set on a 500 from the batch call, it stops firing on this state.