For AI agents: markdown of this page — /docs-content-en/changelog/2026-09-29.md documentation index — /llms.txt
API changes: September 29, 2026
NEW-0929-1: Catalog measure and VAT rate reference data
The Vibecode API now provides GET, POST, PATCH, and DELETE for /v1/catalog-measures and /v1/catalog-vat-rates. Clients can read valid measure and vatId values before creating a product. Search, fields, and batch are also available for both entities.
BC-0929-2: employee and requisite sorting now orders by identifier
Old format supported until: not provided
Before
sort=-id and order[id]=desc did not change the order of employees, requisites, and requisite presets. Sorting employees by another ordinary field could be silently ignored while the request returned HTTP 200 with rows.
After
Both forms sort these lists by id in descending order on single endpoints, search, and POST /v1/batch. For employees, id is the only supported ordinary sort field. Other ordinary fields are rejected with UNKNOWN_SORT_FIELD. UF_* keeps its previous passthrough on one page and is rejected with INVALID_SORT_FIELD for multi-page retrieval. Responses to supported requests remain HTTP 200.
What integrators need to do
ID sort requests need no changes. Do not use other ordinary employee fields. Keep UF_* to single-page requests and remember that its order still depends on Bitrix24.
Affected endpoints: GET /v1/users, POST /v1/users/search, GET /v1/requisites, POST /v1/requisites/search, GET /v1/requisite-presets, POST /v1/requisite-presets/search, POST /v1/batch.
BC-0929-3: Cowork ERP management status lists the EMAIL channel only when the account has an email address
Old format supported until: not provided
Before
With admin.stepUp.required: true, GET /v1/cowork/onec/status always included EMAIL in admin.stepUp.channels.
After
For an account without an email address, EMAIL is not included in admin.stepUp.channels. The list may contain only PORTAL or be empty with required: true. The response for an account with an email address is unchanged.
What integrators should do
Build the channel choice from admin.stepUp.channels instead of assuming EMAIL. An empty list with required: true means the action cannot be confirmed right now.
NEW-0929-5: catalog services are available through V1
The Vibecode API now provides /v1/catalog-services for listing, searching, reading, creating, updating, and deleting services. List and search require filter.iblockId. Service prices use the existing /v1/catalog-prices endpoint.
FIX-0929-6: heavy revenue export pages no longer fail with 503 after 5 seconds
Before
An export page whose database query ran longer than 5 seconds answered 503 with code DB_TRANSIENT and the text "Service temporarily overloaded. Retry after a few seconds.", even though the export's own query budget is 25 seconds and nothing was overloaded. This showed most often on the first page of GET /v1/platform/revenue/charges over a long window; GET /v1/platform/revenue/topups, GET /v1/platform/revenue/expirations, GET /v1/platform/revenue/refunds, GET /v1/platform/revenue/consumption/by-service, GET /v1/platform/revenue/money-in and GET /v1/platform/revenue/money-in/payments could answer the same way. A retry a few seconds later sometimes went through and sometimes failed again.
After
An export query gets the full declared 25-second budget, and a page that fits in it answers HTTP 200. The response format, the traversal order and the cursors are unchanged.
Impact on integrators
None. Keep retrying on 503 after Retry-After — it is still needed for genuine short-lived failures. If a reconciliation over a window was interrupted by such a response, simply restart it: all of these endpoints only read data.
FIX-0929-7: /v1/me lists only scopes obtainable on the Bitrix24 account
Before
GET /v1/me suggested reissuing a key for performan on a Bitrix24 account without the required flag. Public GET /v1/openapi.json?scope=performan differed from a request with an unknown name.
After
scopeRequirements.missing lists a flag-gated scope only when the Bitrix24 account can obtain it; an already granted scope remains in granted. Public ?scope=performan returns the same full specification variant as an unknown name.
NEW-0929-8: connector gateway for Cowork
The Vibecode API answers POST /v1/connectors/mcp, an MCP gateway through which the Cowork desktop calls tools of connected services. The gateway is behind a feature flag and accepts only the Cowork desktop key, any other key gets 403 CONNECTOR_KEY_NOT_ALLOWED. While the feature is not enabled, the path answers 404 ROUTE_NOT_FOUND.
FIX-0929-9: the Cowork/Code tier change preview quotes the discounted price
Before
GET /v1/cowork/subscription/preview quoted the plan price for the term in chargeVibes and netVibes even when a platform discount applied to the purchase: the purchase then charged less than the preview showed.
After
chargeVibes and netVibes include the discount this purchase will receive — exactly the amount that will be charged. Renewing a plan that is already paid and repeating the current plan get no discount, the same as the purchase itself. The response shape is unchanged and the response remains HTTP 200.
NEW-0929-10: cause and action in Bitrix24 permission and scope refusals
403 BITRIX_ACCESS_DENIED responses and 422 BITRIX_ERROR responses whose b24Code is ACCESS_DENIED_EXTEND or NO_AUTH_FOUND carry new optional fields. error.cause distinguishes a refusal by the rights of the Bitrix24 user (b24_permission), a scope missing on the key's credential (b24_scope) and a cause that cannot be determined (unknown). error.fix names the action (action) and where it is performed (via); error.method is the Bitrix24 method, at most 100 characters; error.requiredScope is the missing scope when it is known; error.hint is always present on these refusals. The values of cause, fix.action and fix.via are open sets: read an unknown value as unknown or none. Response codes and statuses are unchanged. Values explained — Authorization, keys and permissions.
FIX-0929-11: a post permission refusal returns an English message
Before
PATCH /v1/posts/{id}, DELETE /v1/posts/{id} and POST /v1/posts/{id}/share returned the Bitrix24 account's text as is in error.message when Bitrix24 refused access to the post — on a Russian-language account that text was in Russian.
After
error.message of such a refusal is the fixed English text Bitrix24 denied access to this post., and the response also carries error.cause, error.method, error.fix and error.hint. The code and status are unchanged — 403 BITRIX_ACCESS_DENIED.
Impact on integrators
Client code that branches on error.code needs no change. Parsing the error.message text of this refusal is no longer needed.
BC-0929-12: File and folder search validates both supplied parent folder IDs
Old format supported until: not provided
Before
In POST /v1/files/search and POST /v1/folders/search, a parent folder ID could be supplied both at the body top level and in filter. If one value was valid, a malformed value in the other location could reach the Disk call or go unnoticed.
After
Both supplied values must be non-empty scalars. A request with an object, array, null, or an empty string in either location is rejected before the Disk call. Two valid values still use the top-level value.
What integrators should do
If an ID is present in both locations, remove the malformed value and keep the valid folderId or parentId. Such a request could previously succeed when the valid value was at the top level.
NEW-0929-13: balances export: user counters per Bitrix24 account
The GET /v1/platform/revenue/balances row gains three fields. usersInVibecode is the number of the Bitrix24 account's users registered on the Vibecode platform, the same value as portal.usersInVibecode in GET /v1/platform/cowork/members. usersLoggedIn is how many of them have signed in to Vibecode at least once. usersInvited is how many are registered but have never signed in. The numbers add up: usersLoggedIn + usersInvited = usersInVibecode.
0 and null are different answers. A Bitrix24 account with no users returns 0 in all three fields. null in usersLoggedIn and usersInvited means the sign-in status of some of its users cannot be established; usersInVibecode is still a number in that case.
Deactivated users are not counted. A change in the counters does not move the account's updatedAt and does not show up in a changedSince query: fresh values come with a full pass without changedSince. The existing row fields, query parameters and pass order are unchanged.
BC-0929-14: chat read boundaries, file metadata and publication recovery
Old format supported until: not provided
Before A personal vibe_api_* key in READONLY mode received 403 WRITE_BLOCKED_READONLY_KEY for GET /v1/chats/{dialogId}/load, GET /v1/chats/{dialogId}/messages?format=v2, and GET /v1/chats/messages/{messageId}/context.
After These employee reads are allowed when the key has the im scope and the user has Bitrix24 access, the successful read response remains HTTP 200. If the chat allows auto-join, the call may make the employee a member. Bitrix24 updates presence on these reads. Chat loading may also trigger lazy project conversion. REST parameters cannot disable these effects. The method bodies do not mark messages read. Explicit state-changing commands remain blocked for a read-only key.
What integrators should do A personal employee read-only key can perform these named reads without enabling write commands. Guest session authentication is outside this contract. Successful response shapes are unchanged.
Before GET /v1/chats/files/{fileId} accepted an im-only key and looked up an arbitrary Disk file ID. Message PATCH /v1/chats/{dialogId}/messages/{messageId} and DELETE /v1/chats/{dialogId}/messages/{messageId} did not verify that messageId belonged to dialogId.
After READONLY requires an existing chat: chatN, or a numeric peer (including a resolved me) proved by the same employee’s recent list. The check scans at most 4000 raw rows; an unproved binding receives 403 WRITE_BLOCKED_READONLY_KEY before a method that could create a chat. Metadata requires both im and disk, plus the user’s Bitrix24 access to the file. A missing scope returns 403 SCOPE_DENIED before contacting Bitrix24. A message mutation is permitted only after finding the exact ID in the named dialog’s visible history. A mismatch returns 404 MESSAGE_NOT_FOUND_IN_DIALOG, a received lookup response that cannot confirm membership returns 503 MESSAGE_MEMBERSHIP_UNAVAILABLE; other preflight errors retain their ordinary API status and code. Neither refusal sends a mutation. In the GET /v1/chats/recent, offset counts visible unique rows. Window validation is bounded to 20 pages or 4,000 rows, returning 503 RECENT_WINDOW_UNAVAILABLE instead of partial success when the budget is exceeded. Metadata contains eight fields: id, name, size, type, detailUrl, createdBy, createdAt, updatedAt. The former optional downloadUrl is removed from metadata and successful file uploads to avoid returning a URL containing Bitrix24 credentials. Successful HTTP 200 message mutation responses are preserved. Chat file upload still requires im. In POST /v1/chats/messages/bulk, a duplicate computed key (id, otherwise dialogId) now returns 400 INVALID_PARAMS before any call to Bitrix24 instead of dropping the first item. Unique string keys, including Object property names, are preserved. Batch cursors accept non-negative safe integers and decimal-digit strings within the same range; null continues to omit a cursor. Validation and normalization run before sending the request to the Bitrix24 account. Incomplete or contradictory batch outcomes and unusable event polling responses return 502 BITRIX_ERROR instead of a false HTTP 200. An empty recent page claiming continuation, or a row without a confirmed ID, returns 503 RECENT_WINDOW_UNAVAILABLE; healthy response shapes are preserved.
What integrators should do For a read-only key, use an existing chatN or a private binding from recent dialogs; handle an unproved-context refusal. Add disk to metadata-reading keys. For bytes, replace downloadUrl with authenticated GET /v1/files/{fileId}/download, using disk or crm. Pass the dialog that contains the message to be changed. Handle membership refusals and do not try to mutate a message through a different dialog. Use the v2 cursor for deep recent-list navigation and handle temporary window-check refusal. The former im-only access closes immediately to correct the scope boundary.
Before A publication failure after uploading a file to Drive did not explain whether the file remained. Automatic replay or deletion after an ambiguous refusal could create a duplicate or delete an attached file.
After POST /v1/chats/{chatId}/files does not automatically replay upload or publication. A failure after upload preserves its original status and code and adds meta.uploadRecovery with the file and chat IDs and the publication and cleanup outcomes. Deletion is permitted only after a confirmed pre-attachment refusal and affects only this request’s file. An unknown outcome preserves the file. The successful HTTP 201 response contains fileId, name, size, without the former optional downloadUrl.
What integrators should do Inspect chat history and the named file’s metadata before recovery. Do not automatically replay an upload whose publication outcome is unknown.
Before GET /v1/chats/{chatId}/folder could initialize a missing Drive folder with a read-only key.
After Initialization requires READWRITE; closing modes receive 403 WRITE_BLOCKED_READONLY_KEY before this method is called. File listing, metadata and byte reads retain their read rules.
What integrators should do Use a key with write access to retrieve the folder. After upload, verified local refusals before publication dispatch permit deletion of only this request's file; unknown outcomes preserve it. Upload, publication and compensation do not automatically replay after 429 or scope refusals.
Before POST /v1/chats forwarded users without local validation; malformed entries could produce a Bitrix24 error or be dropped when creating the chat.
After Before im.chat.add, a provided list is checked as an array of positive safe integer IDs. Numbers and canonical decimal strings without leading zeros or spaces are normalized to numbers; malformed input receives 400 INVALID_PARAMS before the method call. An omitted list or an empty array remains valid. The READONLY write refusal still precedes body validation. Entity-binding fields, including opaque entityId values such as DEAL|1663, are preserved.
What integrators should do Send valid participant IDs instead of relying on malformed values being silently dropped. Correct the list shape before retrying after 400 INVALID_PARAMS.
NEW-0929-16: catalog SKUs and offers are available through V1
The API now provides /v1/catalog-skus and /v1/catalog-offers for listing, searching, reading, creating, updating, and deleting records. List and search require the relevant catalog's filter.iblockId. An offer can be free or linked to a parent SKU through parentId on creation.
NEW-0929-17: Chats: dialog list sections, shared chats, changes since a moment, chat pinning and reading
The chats section gained ten endpoints on the Bitrix24 messenger v2 methods. Dialog list sections are read in pages: GET /v1/chats/recent/channels returns public channels by the lastMessageId cursor, GET /v1/chats/recent/collabs returns collab chats, and GET /v1/chats/recent/external returns the chats of one section by its type code, such as task chats or calendar event chats, both by the lastMessageDate cursor and the hasNextPage flag. GET /v1/chats/shared returns the chats shared with the given employee, and GET /v1/chats/sync returns changes to chats, messages and pins since the given moment. A chat is pinned in the dialog list with POST /v1/chats/:dialogId/pin, its position among the pinned chats is set with PUT /v1/chats/:dialogId/pin, and the pin is removed with DELETE /v1/chats/:dialogId/pin. POST /v1/chats/read-all marks all of the user's chats as read, and POST /v1/chats/recent/read marks the chats of one list section as read. Limits outside the range are clamped with an echo in meta, and an unknown or repeated parameter or an extra body field is refused with 400 INVALID_PARAMS. Pinning, changing the pinned order and marking as read are writes: a read-only key gets 403 WRITE_BLOCKED_READONLY_KEY for them, as described on the access rights page.
FIX-0929-18: The legacy chat list supports deep offsets again
GET /v1/chats/recent without format=v2 again forwards a deep OFFSET to Bitrix24 and reads one page with a possible refill for a hollow boundary row, as before Stage 2. Prefix replay, the 4,000-row window and the new 503 RECENT_WINDOW_UNAVAILABLE refusals were removed. Ordinary keys also retain the original query parameters for legacy message reads; the READONLY protected-selector filter remains. This restores compatibility instead of the changes in the !4345 BC fragment.
NEW-0929-19: write catalog list-property values through V1
The Vibecode API now supports creating, partially updating, and deleting list-property options: POST /v1/catalog-product-property-enums, PATCH /v1/catalog-product-property-enums/:id, and DELETE /v1/catalog-product-property-enums/:id. A partial update fills omitted Bitrix24-required fields from the existing record.
NEW-0929-20: cause and a ready transfer step in the BOT_ACCESS_DENIED refusal
The 403 BOT_ACCESS_DENIED response (the bot is bound to another API key) carries new optional fields: error.cause with the value bot_other_key, error.fix and error.hint. When the calling key can run the transfer to itself, error.fix is { "action": "transfer_bot", "via": "same_key", "path", "body" }: path is the ready route POST /v1/bots/{botId}/transfer with the bot identifier from the request, and body holds the identifier of the calling key itself. The response never names the key the bot is bound to. Otherwise error.fix.action is none, and error.hint names the reason. The code, status and error.message are unchanged. Details — Authorization, keys and permissions.