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

API changes: October 5, 2026

← Changelog · October 2026

FIX-1005-1: the list of plans allowed on a trial can hold several plans

Before

On trial access, POST /v1/infra/servers answered 402 PLAN_NOT_ALLOWED_ON_TRIAL for any plan but a single allowed one, and GET /v1/me named that one plan in capabilities.servers.create.limits.allowedPlans and in note.

After

The list can hold several plans: limits.allowedPlans in GET /v1/me and error.details.allowedPlans in a 402 PLAN_NOT_ALLOWED_ON_TRIAL response list all of them, and note names each. Read the list from the response instead of hardcoding one plan.

FIX-1005-2: repeating an event subscription no longer returns an error

Before

Repeating POST /v1/infra/servers/:id/event-subscriptions for an event whose handler was already registered in Bitrix24 (a retry after a failure, an appPath change) returned 502 BIND_FAILED, and the subscription was not saved. If another app installer subscribed again, Bitrix24 added a second registration and every event reached the app twice.

After

The repeated call returns HTTP 200 and updates the subscription: an already registered handler counts as success. Extra registrations of the same event under another user are removed, so the event arrives once.

Impact on integrators

No action required. Retrying a request after 502 BIND_FAILED is now safe.

FIX-1005-3: sleeping-server deploy operation is visible during wake

Before

POST /v1/infra/servers/:id/deploy created an addressable dedicated-virtual-machine operation only after wake. If the connection dropped or wake was refused, the run could not be found through the operation list and the error response carried no operation id.

After

After successful authorization, the run is visible in the operation list as running during wake, including before the client receives an HTTP response. If wake or later preparation is refused, a response with an operation carries its id in X-Vibe-Operation-Id and error.operationId. The list reports the refusal code if the asynchronous outcome write succeeds. Operation tracking remains best-effort: just after the response it may remain running, and a failed write may leave it unknown without a refusal code after expiry. A missing id does not prove that the deploy never started.

Impact on integrations

When a response is lost, find the latest run through the server operation list and read its outcome before repeating the deploy.

FIX-1005-4: Reading pages without explicit field selection

Before

GET /v1/pages, GET /v1/pages/:id and POST /v1/pages/search without an explicit select could return 422 BITRIX_ERROR with the Bitrix24 code SYSTEM_ERROR.

After

The domainId field is no longer requested by default, so reading pages does not fail with this error. Existing ordinary requests need no changes. The field remains in GET /v1/pages/fields.

In the list (GET /v1/pages) and search (POST /v1/pages/search), an explicit selection of domainId is forwarded to Bitrix24 and can still return the stated error.

In the get-by-ID endpoint (GET /v1/pages/:id), domainId is not returned even with an explicit select: the endpoint requests the default fields from Bitrix24, and select only narrows the response. The id field is always returned.

BC-1005-5: the task comment list reads the legacy store and paginates it

Old format supported until: not provided

Before

GET /v1/tasks/:taskId/comments read only the chat on a task that has one. Comments written before the account moved to the new task card never migrate into the chat, so such a task answered 200 with an empty data while its comments were alive — and the client could not tell "there are no comments" from "we looked in the wrong place". The single GET /v1/tasks/:taskId/comments/:id found those same comments.

When the answer came from the legacy store, limit and offset were not applied to it: whatever Bitrix24 returned in one call was passed on whole, and meta.hasMore on such a response was always false.

After

When the chat is read to its end and yields no comment, the list reads the legacy store and answers from it — one extra Bitrix24 call, and only where the answer would otherwise be empty.

meta gained a sources field — the array of stores whose contents the response learned. A store is listed when it returned comments, or when it was read to the end and proved empty; a store the response learned nothing from is not listed. Being listed does not mean "read in full": completeness is carried by meta.truncated, and the chat is listed together with truncated: true when its walk broke off after collecting at least one comment. A conclusive "the task has no comments" comes from the set ["chat", "legacy"] with no meta.truncated. The set ["legacy"] means the chat was NOT READ — the method refused, the scope is missing, the response shape was unreadable, or the walk broke off. ⚠️ Such an answer MAY CARRY NO truncated: the flag speaks only for what WAS read being read in part, while an unread chat is reported by the set itself. So if (!meta.truncated) → the answer is complete is wrong: judge by the set AND the flag together. A task with no chat allotted is NOT that case: chat comments cannot exist there, so the set is complete. Only a fresh check proves it — within the five-minute cache the same task honestly answers ["legacy"], because a chat may have been allotted meanwhile. ["chat"] means the legacy store did not answer, and [] means neither did.

limit and offset now apply to an answer from the legacy store as well: you get the page you asked for rather than everything Bitrix24 returned in one call. The response remains 200.

⚠️ The Bitrix24 legacy store returns at most 50 comments per call and offers no navigation over them. The two meta fields therefore answer DIFFERENT questions. meta.hasMore — "the set this response was built from holds further rows", and you walk it with offset. meta.truncated — "the call came back full, and more comments may sit behind it with no way to ask for them". hasMore: false together with truncated: true means "you reached the end of the window, but not the end of the task's comments".

On that path meta.total is the Bitrix24 counter, and it does NOT always count the whole task: filter is passed to Bitrix24 as is, so with a filter the number counts the matches. Without a filter it does NOT become a task-wide counter either: task.commentitem.getlist is called once, with no start/NAV, and when Bitrix24 returns no counter of its own, total degenerates into the row count of that single page. It may exceed the length of data; it cannot reach past that one call. Read it together with truncated: "this many exist for this request, this many arrived, that is not all". ⚠️ Do not read total as "the task has this many comments" — neither with a filter nor without one. Judge completeness by truncated and meta.sources, not by comparing against total.

What integrators should do

If you passed limit or offset on a task whose comments live in the legacy store, they used to have no effect and you received everything Bitrix24 returned in one call. You now receive exactly the page you asked for — check those places.

On a long legacy history, do not read meta.hasMore: false as the end of the list: on this path the field describes only what arrived in one Bitrix24 call. This endpoint does not currently return the full set of comments for such a task.

FIX-1005-6: OpenAPI describes object filter serialization

Before

OpenAPI omitted the serialization settings for some object query filters. A client generated from the specification could send fields outside filter.

After

Pure-object query parameters declare style: deepObject and explode: true: for example, filter[amount]=1000. This covers generic entity lists, /v1/requisite-links, /v1/openline-configs and /v1/voximplant-sip. Nested objects and arrays remain an extension whose support depends on the client; use POST /search for complex filters in entity lists.

BC-1005-7: overall per-minute request limit per key and per key owner

Old format supported until: not provided

Before

There was no overall limit per client: limits were counted separately on each method.

After

Requests to /v1 are counted in a shared counter: 600 per minute per key and 1200 per minute across all keys of one owner. Bot event polling (GET /v1/bots/{botId}/events) is counted by separate counters and does not spend the shared counter of other requests: 120 per minute per bot, plus, with the same thresholds, 600 across all polls of one key and 1200 across all polls of the keys of one owner. On overflow the answer is 429 with the code CALLER_RATE_LIMITED. The X-RateLimit-Scope header names the counter that fired (key, user, bot) and Retry-After gives the seconds until the one-minute window ends. Retrying earlier does not extend the window. An app key is counted differently: 600 per minute for each app user in a Bitrix24 account, with no shared owner counter. AI methods are not part of this counter, except AI provider key management (/v1/ai/credentials and /v1/ai/providers), which is counted like any other request. The named numbers are platform-wide ceilings: they are divided across backend replicas, so a client on one connection can be refused earlier than the named number, and the effective number is not published in a header. Details — Limits, queues, and pauses.

What integrators should do

On a 429 with the code CALLER_RATE_LIMITED, wait for the time from Retry-After and retry the request, retrying a write is safe. For exports, read records in pages through search and combine calls with POST /v1/batch. Keep the pace well below the ceilings (120 per minute per bot, 600 per key, 1200 per owner) and wait Retry-After on a 429.

NEW-1005-8: Read-only mode for Cowork chats: chat keys and the mode choice

The Cowork desktop app gets three methods for read-only chats. GET /v1/cowork/portal-access and PATCH /v1/cowork/portal-access read and change the mode for the next chats of the person in this Bitrix24 account: read-only or changes allowed. A change sends the version it read and gets 409 COWORK_PREFERENCE_CONFLICT when that version is stale. POST /v1/cowork/chat-key issues a chat key of the chosen mode, and the desktop app hands it to the agent instead of its own key. A chat key is never wider than the current rights of the desktop key and stops working together with it (401 COWORK_CHAT_KEY_INACTIVE). A read-only chat key does not change Bitrix24 data: such a call gets 403 COWORK_READONLY before anything reaches Bitrix24. A chat key does not manage keys or the mode choice (403 COWORK_CHAT_KEY_FORBIDDEN), and GET /v1/me called with it returns the coworkPortalAccess field with the effective mode of the chat. Only the Cowork desktop key may call the new methods, any other key gets 403 COWORK_DESKTOP_KEY_REQUIRED. Until the feature is enabled for the account, all three methods answer 403 COWORK_CHAT_KEY_DISABLED.

NEW-1005-9: chats of one project as a separate list

The new endpoint GET /v1/chats/projects/{projectId}/recent returns the chats of one project (collab) from the recent list: the project's own chat and the chats nested in it. projectId is the chat id of the project, the same chatId as in its row of GET /v1/chats/recent/collabs. It requires the im scope.

The response is built like that of GET /v1/chats/recent with format=v2 — recentItems, chats, users, messages, files, hasNextPage — and on the first page it also carries the data.sectionMeta object with the project details. A non-empty data.sectionMeta.fixedChatIds shows that projectId points at a project chat: the ID of any other chat answers 200 with empty collections. In data.chats the project's own chat has parentChatId equal to 0, and the nested chats have it equal to projectId. Paging works as in the collab list: limit from 50 to 200, the next page by lastMessageDate. The endpoint accepts no other query parameters and answers 400 INVALID_PARAMS.

The first page is not a pure read: on the first read of a project Bitrix24 creates the CoPilot chat of that project for the key owner, once per project and for members only. A key whose access mode forbids writes therefore gets 403 WRITE_BLOCKED_READONLY_KEY on the first page. The pages with lastMessageDate only read and stay available to such a key.

BC-1005-10: device limit on Cowork/Code desktop key issuance and the COWORK_DEVICE_LIMIT_REACHED code

Old format supported until: not provided

Before

Issuing a Cowork/Code desktop key through Connect (device-code sign-in, the consent page, the Atlas token exchange) did not limit the number of live desktop keys of a user and account pair: every sign-in added a new key.

After

A user and account pair may hold at most 10 live desktop keys. Revoked, blocked and expired keys take no slot, and reconnecting the same installation spends none.

Above the limit a sign-in from a client that does not report an installation id revokes the longest-unused keys of such clients without an installation id, as many as needed to get back to the limit (usually one). If the pair holds too few such keys, including when every slot is held by keys with an installation id, issuance is refused with COWORK_DEVICE_LIMIT_REACHED (HTTP 409, details.used and details.limit). On the return to redirect_uri the app receives error=access_denied with this code in error_description.

What integrators should do

Report the installation id on sign-in: reconnecting the same computer then spends no slot, and the client's keys are not evicted. On COWORK_DEVICE_LIMIT_REACHED, tell the person to sign out an unused device in the Cowork/Code section of the Vibecode cabinet, and repeat the sign-in.

BC-1005-11: auto-sleep no longer stops an application with a fetch Bot

Old format supported until: not provided

Before

An ordinary server or Galaxy application with an enabled fetch Bot could store a numeric idle threshold and read as IDLE. Requests to PATCH /v1/infra/servers/:id/sleep and PATCH /v1/infra/servers/:id/run-mode accepted this mode even though outbound Bitrix24 polling did not count as inbound activity and the application went to sleep.

After

GET /v1/infra/servers and GET /v1/infra/servers/:id return the new idleSleepProtected field. It is true for an application with an enabled fetch Bot, and its mode without a schedule is ALWAYS even when a numeric threshold is stored. A numeric sleepAfterMinutes or the IDLE mode now returns 400 AGENT_IDLE_SLEEP_FORBIDDEN. This also applies to POST /v1/infra/servers with explicit runMode: IDLE when the key is associated with an enabled fetch Bot: the refusal arrives before a server is created. null and the SCHEDULE mode remain available. When an assigned schedule is deleted with reassign=true, such an application moves to effective ALWAYS and retains its idle threshold; agent and bot servers move to ALWAYS with their threshold cleared.

What integrators should do

Check idleSleepProtected before changing auto-sleep. When it is true, use null for around-the-clock operation or assign a schedule. When creating a server with a key associated with an enabled fetch Bot, do not request runMode: IDLE. Handle AGENT_IDLE_SLEEP_FORBIDDEN on both create and update. Before deleting an assigned schedule with reassign=true, account for protected applications switching to around-the-clock operation.

FIX-1005-12: request examples in the reference and the specification no longer show a body the route does not accept

Before

Generated examples on the Vibecode platform printed array and object fields empty where sending such a body makes no sense.

In the update examples: PATCH /v1/bookings/{id} printed "resourceIds":[] and PATCH /v1/bizproc-templates/{id} printed "documentType":[]. A reader who copied such an example to rename a record got one of two outcomes instead of a result: the booking answered 422 with the BITRIX_ERROR code and the Empty resource collection message, while on a business process template the documentType field is not applied by an update at all — the request returned 200 and left the document type unchanged.

In the create examples, required fields were printed empty: POST /v1/bookings sent "resourceIds":[] and "datePeriod":{}, POST /v1/bizproc-templates sent "templateData":[] and "documentType":[]. Those requests were refused as well: templateData with the MISSING_REQUIRED_FIELDS code, the others on the Bitrix24 side.

After

The update example does not show fields that are replaced as a whole — neither arrays nor objects with a described nested structure. The create example shows working values for required fields: the list of resource identifiers, the booking period built from from and to, and the document type as module, object and type. The template file carries an explicit placeholder, <base64-encoded .bpt file contents> — the caller supplies the contents of their own file, and the sample is written so that it cannot be mistaken for a ready-to-send value. The same values now appear in the GET /v1/openapi.json specification as the example of those fields and in the response examples. The one exception is documentType on a business process template: the write schema carries no example for it, because an update does not apply the field and a ready-to-send value there would read as an invitation to send a write that answers 200 and changes nothing. The read schema keeps the example, and the field description states the behaviour in words on both schemas. An empty array stays where it is meaningful — on optional fields it still means "the list is empty".

Impact on integrators

Route behaviour is unchanged for every operation listed: these bodies were refused or ignored before as well, and the error codes and messages are the same. Nothing has to change in working code. A client generated from the specification will see a filled-in example on the fields listed above.

FIX-1005-13: OpenAPI describes every address route

Before

OpenAPI and the API reference described only GET /v1/addresses/fields for addresses. The list, search, create and composite-key operations worked, but client generators and AI agents reading the specification could not see them.

After

The full specification, the crm slice and both reference languages describe GET /v1/addresses, POST /v1/addresses, POST /v1/addresses/search, and GET, PATCH and DELETE /v1/addresses/{typeId}/{entityTypeId}/{entityId}. Route behaviour is unchanged. Regenerate your client from the current specification to expose the operations.

BC-1005-14: deleting a call log entry searches the 5000 newest entries

Old format supported until: not provided

Before

DELETE /v1/calls/log/{callId} deleted an entry at any depth of the personal call log: before deleting, the wrapper read the journal page by page until it found the entry or reached the end, with no limit on the number of pages. The response was 200.

After

Before deleting, the 5000 newest journal entries are searched (at most 50 pages). An older entry returns 422 CALL_LOG_PREREAD_LIMIT_EXCEEDED, and nothing is deleted: such an entry cannot be deleted via the API. For entries among the 5000 newest the response remains 200; a missing entry still returns 404 ENTITY_NOT_FOUND.

What integrators should do

Treat 422 CALL_LOG_PREREAD_LIMIT_EXCEEDED as a final refusal and do not retry.

NEW-1005-15: Calendar resources, availability and meeting RSVP

Added calendar resources: list, create, rename and delete; resource bookings and attendee availability. Timed intervals return ISO-8601 dates with timezone offsets; all-day intervals return civil dates without a timezone. Meeting RSVP reads or changes the current credential owner response: accepted, declined or invited. Requires calendar scope; READONLY keys cannot write. A missing resource or event returns 404 ENTITY_NOT_FOUND; an unconfirmed status write returns 422 BITRIX_ERROR.

FIX-1005-16: OpenAPI describes employee deactivation

Before

The working DELETE /v1/users/{id} was missing from OpenAPI and the VibeCode API reference, so client generators could not discover the operation.

After

The operation is included in the full specification, the user slice and both reference languages. The response remains HTTP 200 with success: true and data: { id, active: false, deactivated: true }; the user field is optional. No request body is required. This is employee deactivation through ACTIVE=N, reversible through PATCH /v1/users/{id} with active: true. Regenerate your client from the current specification to expose the operation.