For AI agents: markdown of this page — /docs-content-en/changelog/2026-10-06.md documentation index — /llms.txt
API changes: October 6, 2026
BC-1006-1: Comment files return only current metadata
Old format supported until: not provided
Before
GET /v1/posts/comments returned file metadata together with any additional fields in the Bitrix24 response.
After
files retains id, date, type, name, size, image, authorId, authorName, urlPreview, urlShow, urlDownload. image retains only width and height. Unknown fields and values with incorrect types are omitted. Links containing credentials remain redacted.
What integrators should do
Use only the listed fields with their primitive types; remove reads of additional fields and nested objects. Current file metadata and the array or dictionary shape are preserved. No support window is provided for additional fields: the closed DTO applies immediately.
NEW-1006-2: site actions and data
Added POST /v1/sites/:id/publication, POST /v1/sites/:id/unpublish, POST /v1/sites/:id/trash and POST /v1/sites/:id/restore with site state read back. Reads: GET /v1/sites/:id/public-url, GET /v1/sites/:id/preview, GET /v1/sites/:id/settings, GET /v1/sites/:id/export, GET /v1/sites/:id/my-permissions. Export is limited to 8 MiB; excess returns 413 SITE_EXPORT_TOO_LARGE. PUT /v1/sites/:id/permissions fully replaces rights with a non-empty dictionary; DELETE /v1/sites/:id/permissions explicitly clears them. my-permissions shows current-user operations, not assigned roles. All operations require landing scope and support scope.
NEW-1006-3: Page actions and template discovery
Added site page actions: POST /v1/pages/:id/trash, POST /v1/pages/:id/restore, POST /v1/pages/:id/copy and POST /v1/pages/:id/move. Actions return the page read back. Moving requires an explicit destination, and copying an active page may publish its copy immediately under Bitrix24 rules.
POST /v1/pages/from-template creates a page using a code from GET /v1/page-templates. GET /v1/pages/:id/public-url, GET /v1/pages/:id/preview, GET /v1/pages/:id/settings and GET /v1/pages/resolve obtain addresses, settings and a page ID from its public path. Every route requires the landing scope, with the optional scope query parameter for knowledge bases and groups.
NEW-1006-4: Site folders
Added GET|POST /v1/sites/:id/folders, PATCH /v1/sites/:id/folders/:folderId and POST actions trash, restore, publication, unpublish. Requires landing scope; pass scope for non-default site types. Writes return the folder read back. Partial PATCH preserves the parent; parentId: null moves the folder to root. Publication and unpublication affect the parent chain; trash unpublishes pages in the folder and descendants, restore does not republish them.
BC-1006-5: galaxy host without an agent gets the AGENT_NEVER_CONNECTED code
Old format supported until: not provided
Before
When the agent never came up on a galaxy host (kind: "GALAXY"), the platform moved the host to error with a text reason in provisionError, but provisionErrorCode stayed null. The case could not be told apart by code, and POST /v1/infra/servers/:id/start accepted the request: the host went back to running, billing resumed, and there was still no agent.
After
A newly judged host in this state gets provisionErrorCode: "AGENT_NEVER_CONNECTED", the same code a standalone server gets. Existing ERROR rows with the old reason text keep provisionErrorCode: null; /start and availableActions recognize that exact legacy text and expose the same repair path. POST /start on either form answers 422 with the code, and error.availableActions carries repair and delete.
What integrators should do
If you restart galaxy hosts in error on a schedule, treat AGENT_NEVER_CONNECTED or the exact legacy reason Galaxy host booted but its agent never connected — the on-boot Docker/agent install failed. Delete and recreate the host, or repair it. as a signal to call POST /v1/infra/servers/:id/repair, not to retry the start.
BC-1006-6: whitespace-only names of a key and of an AI credential are rejected
Old format supported until: not provided
Before
A value made only of spaces, tabs or line breaks (for example " ") passed the "at least one character" check. A key and an AI credential were accepted with such a name and stored with no visible character at all.
After
Such a value is rejected before anything is written:
- POST /v1/keys and PATCH /v1/keys/{id} — field
name, response400 VALIDATION_ERROR; - POST /v1/ai/credentials and PATCH /v1/ai/credentials/:id — field
name, response400 INVALID_REQUEST.
On the write paths of an application name and a placement title (title, catalogTitle) the same refusal has been in force since 16.09 — record BC-0916-20; nothing changed for them here.
An accepted name is still stored exactly as sent, as before: edge spaces are not trimmed, and only a name with no non-whitespace character at all is rejected. Requests with a regular name, and requests that omit name where it is optional, work as before.
What integrators should do
Only callers that put a whitespace-only string into name, for example untrimmed user input, need a change: check that the name holds at least one non-whitespace character before sending the request.
FIX-1006-7: `GET /v1/chats/:dialogId/messages`: the `limit` ceiling applies to any spelling of the name
Before
A LIMIT (or Limit) query parameter sent without a lowercase limit reached Bitrix24 as is: the 200 ceiling and the meta.appliedLimit echo were not applied.
After
Every spelling of limit is folded into one value (lowercase wins), clamped to 200 and sent as LIMIT; when clamped, the response carries meta.requestedLimit and meta.appliedLimit. Other query parameters pass through unchanged.
NEW-1006-8: System pages and template areas
VibeCode API supports reading and assigning system pages through /v1/sites/:id/system-pages, reading a role URL through /v1/sites/:id/system-pages/:type/url and explicitly clearing site or page roles. /v1/site-templates returns layout templates. /v1/sites/:id/template-areas and /v1/pages/:id/template-areas support GET, merging PATCH and DELETE to clear all areas. Omitted areas remain, null removes one area. Requires landing scope. Writes verify persisted state; silent Bitrix24 refusal is returned as 422 BITRIX_ERROR.
BC-1006-9: the refusal for a server with no cloud VM names only the endpoints the caller may call
Old format supported until: not provided
Before
A server with no cloud VM answered 422 VM_MISSING on wake via POST /v1/infra/servers/{id}/wake — including the automatic wake
inside POST /v1/infra/servers/{id}/deploy, /exec, /upload and
GET /v1/infra/servers/{id}/logs: all four share one preamble, and it wakes the same way. The hint was the same for every caller and
advised two endpoints: DELETE /v1/infra/servers/{id}, then POST /v1/infra/servers. A
read-only key is allowed to deploy, yet both advised calls answer it
403 WRITE_BLOCKED_READONLY_KEY: the platform printed an instruction it forbids itself. The
same applied to a key without the vibe:infra scope, a development-team member on someone
else's server, and an owner whose account is pending deletion.
After
An endpoint reaches the hint only when it is available to that caller. A key refused the
delete or the create is given the reason and the recipe instead of the address — what to
change (switch the key's access mode, grant the vibe:infra scope, ask the server owner);
when both halves are closed by different doors, both reasons are named. The half of the
recipe that is available is still named by its endpoint.
For a galaxy app (kind: GALAXY_APP) the same response advises redeploying with POST /v1/infra/servers/{id}/deploy instead of deleting and creating. That endpoint is now also
named only when deploying is open to the caller. In practice this affects one case: a
development team member reads GET /v1/infra/servers/{id}/logs with their own key while their
Bitrix24 account has the galaxy pilot switched off — they get the reason and the recipe instead
of the endpoint. The server owner, a development team key issued for this server and a caller
linked through an application do not receive this response: their requests to a galaxy app are
served by a separate branch.
TWO body fields change for such a caller: error.hint and error.message — the latter no
longer says "delete this server and create a new one", since the caller has no way to do it.
A third field, error.userMessage, is no longer sent to them at all: it is localized and
unconditional, and it ordered the very deletion the neighbouring hint had just declared
unavailable. The previous wording of all three fields is preserved for a read+write key that
owns the server. The code (VM_MISSING) and the status (422) did not change for anyone.
The VM_MISSING responses of POST /v1/infra/servers/{id}/start, /stop and /reboot now
use the same hint and carry an error.hint field for the first time — the field is additive,
existing clients ignore it.
Affected endpoints: POST /v1/infra/servers/{id}/wake, /deploy, /exec, /upload,
/start, /stop, /reboot and GET /v1/infra/servers/{id}/logs.
What integrators should do
A client that displayed ONLY error.userMessage on 422 VM_MISSING gets no text at all on a
refusal. Do not rely on error.userMessage being present in this response: read
error.message and error.hint — they carry the reason and what to change.
BC-1006-10: a smart process can no longer be re-attached to a workspace through customSectionId
Old format supported until: not provided
Before
PATCH /v1/smart-processes/:id accepted the field customSectionId. The value reached Bitrix24
and was discarded there: the type update method does not change the attachment of a type to a digital
workspace, only the workspace side changes it. The request answered with success, and the caller believed the
smart process had been moved to another workspace while nothing had changed. In
GET /v1/smart-processes/fields the field looked like an ordinary writable one.
After
customSectionId is no longer accepted when a type is updated. PATCH /v1/smart-processes/:id carrying it
answers 400 READONLY_FIELD and names the field; both batch update operations answer the same way.
POST /v1/smart-processes accepts the field as before. In GET /v1/smart-processes/fields the field
carries the readonlyOnUpdate flag: the value can only be passed on creation, but after creation it
changes along with the attachment. Its label and description mark it deprecated.
What integrators should do
Drop customSectionId from the body of PATCH /v1/smart-processes/:id — otherwise the whole request
gets 400 READONLY_FIELD instead of the former "success". This matters most when your code reads a
record with GET and sends the whole object back: such a call is now refused. Change the attachment
from the workspace side instead — PATCH /v1/automated-solutions/:id with the complete typeIds set
(the set is overwritten in full, so send the whole list). The readonlyOnUpdate flag in
GET /v1/smart-processes/fields lets you tell such fields apart before sending a request.
NEW-1006-11: digital workspaces are now an entity — /v1/automated-solutions
The entity /v1/automated-solutions is available with seven operations:
GET /v1/automated-solutions, GET /v1/automated-solutions/:id, POST /v1/automated-solutions,
PATCH /v1/automated-solutions/:id, DELETE /v1/automated-solutions/:id,
GET /v1/automated-solutions/fields, POST /v1/automated-solutions/batch. The crm scope is
required. Until now there was no programmatic way to create a digital workspace and attach
smart processes to it.
A record carries three fields: id (read-only), title (required on creation) and typeIds — an
array of the entityTypeId values of the attached smart process types. The attachment is written
from the workspace side: on PATCH the typeIds set is overwritten in full, so send the complete
list or omit the key altogether.
List filtering and sorting are limited to id and title — a limitation of the Bitrix24 method. A
request naming any other field is refused before the Bitrix24 call (400 UNKNOWN_FILTER_FIELD or
400 UNKNOWN_SORT_FIELD) instead of quietly returning the whole collection.
A new error code 403 B24_AUTOMATED_SOLUTION_LIMIT_EXCEEDED reports that the Bitrix24 account has used up
its allowance of digital workspaces; in the cloud the ceiling depends on the Bitrix24 plan. Retrying will
not help — free a slot or raise the plan. Bitrix24's refusal to delete a non-empty workspace
arrives as a 422 with b24Code: "HAS_BOUND_TYPES" and a hint naming the order of steps: move the
attached types first, then repeat the deletion.
NEW-1006-12: landing blocks over the API: a page can now be filled with content
Until now the API could create a site, create a page and publish it — but nothing could put a single block on that page, so a programmatically assembled site stayed empty. Six routes now cover the whole scenario.
- Block catalog — GET /v1/block-repository returns the block codes
available on the account. The catalog is account-wide and is not paginated: narrow it with
the
sectionparameter. - Blocks of a page — GET /v1/pages/{pageId}/blocks. It reads the
page DRAFT by default rather than the published version, because draft identifiers are what
every write accepts. Read the published tree with
version=published; block markup is returned only whencontent=trueis asked for. The response states the version it resolved, both once and on every block. - Add and edit — POST /v1/pages/{pageId}/blocks puts a block from the catalog on the page, PATCH /v1/pages/{pageId}/blocks/{blockId} replaces its markup wholesale. Both writes land in the draft, and the response says so: visitors see the change after the page is published.
- Deletion is reversible —
DELETE /v1/pages/{pageId}/blocks/{blockId} moves the block to the page
trash and POST /v1/pages/{pageId}/blocks/{blockId}/restore brings it
back; the restore address arrives in the deletion response itself. Permanent deletion is
deliberately absent from the API, so a mistake can always be undone. A trashed block is
listed with
deleted=true.
A write addressed to an identifier that is not in the page draft is refused BEFORE Bitrix24 is
called — HTTP 404 with the code BLOCK_NOT_IN_DRAFT. That is done for determinacy: otherwise
such a write could report success while changing nothing.
Boolean body fields (active on add, designed on markup replacement) accept only
true/false (and the strings "1"/"0"). Anything else is refused with HTTP 400 and the
code INVALID_ACTIVE / INVALID_DESIGNED rather than read as a silent «no»: otherwise the
block would be created HIDDEN while the response said 201, and nothing would tell that apart
from the block that was asked for.
content on create is type-checked too: a non-string is refused with HTTP 400
INVALID_CONTENT rather than silently falling back to the repository markup. The field stays
optional.
All six routes require the landing scope. Knowledge-base, group and vibe pages additionally
need the scope parameter — without it Bitrix24 answers that the page does not exist even
though it does.
A page cannot be assembled in one batch call: blocks are added one at a time, and the page is published once at the end.
FIX-1006-13: the reaction add and remove response is documented as `data.result`
Before
The API reference said that POST /v1/chats/messages/:messageId/reactions and DELETE /v1/chats/messages/:messageId/reactions/:reaction return { "success": true, "data": true }. The 422 BITRIX_ERROR refusal of GET /v1/chats/:dialogId/pins/count was not documented.
After
The reference describes the actual response of both reaction methods: { "success": true, "data": { "result": true } }. Read the success flag from data.result. For GET /v1/chats/:dialogId/pins/count the 422 BITRIX_ERROR refusal with error.b24Code CHAT_NOT_FOUND for a missing chat is documented. The methods themselves are unchanged, and the HTTP 200 response is unchanged.
NEW-1006-14: Drive file search, synchronization and saving
The Vibecode API allows clients to search files available to the user across Drive through POST /v1/disk/search.
GET /v1/disk/capabilities reports the capabilities supported by the connected Bitrix24 account.
File search and saving are available independently of synchronization support.
The /v1/disk/sync/* methods allow clients to retrieve a metadata snapshot, resume interrupted synchronization
and read subsequent changes. POST /v1/disk/sync/check checks the current state of objects
and the user's access to them.
POST /v1/disk/uploads/reserve and POST /v1/disk/uploads allow clients to create a file or save a new
version of an existing file. GET /v1/disk/uploads/:operationId returns the operation status.
If the write outcome is unknown, the client checks its status before submitting it again.
Checking a file version does not guarantee protection from concurrent changes by another user.
FIX-1006-15: typing indicator response example now matches the actual response
Before
The response example of POST /v1/chats/:dialogId/typing in the specification and the API reference showed data: true.
After
The example shows the actual response: data is an object with a result field, { "success": true, "data": { "result": true } }. The response itself did not change, it already arrived in this shape.
Impact on integrators
If your code checked data === true following the old example, check data.result instead.
BC-1006-16: feedback attachments now accept documents, not just images
Old format supported until: not provided
A ticket can now carry text, a spreadsheet, a saved web page or an archive — the upload used to accept images only.
The file type is decided by the FILENAME EXTENSION, not by the part's Content-Type header: browsers report these formats incorrectly — .md arrives with an empty type, .zip on Windows arrives as application/x-zip-compressed, and .csv with an office suite installed arrives as a spreadsheet type. Accepted extensions are txt, md, csv, html, htm, xlsx, zip alongside the existing png, jpg, jpeg, webp, gif. The limits are unchanged: 10 MB per file, 5 files per message, 25 per ticket.
An image is still re-encoded by the platform and shown as a thumbnail. A document is stored byte for byte and is always served as a download, so it has no thumbnail: the POST /v1/feedback/attachments response carries kind: "DOCUMENT", thumbnailUrl: null, and width and height are zero. The thumbnail address of a document answers 404. An image carries kind of IMAGE.
The kind field was also added to the attachment lists of every ticket read operation, and the list of accepted extensions arrived as attachmentAllowedExtensions in GET /v1/me. The neighbouring attachmentAllowedMime there grew: besides the four image types it now lists text/plain, text/markdown, text/csv, text/html, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet and application/zip. It is a reference list of types, not the acceptance rule: the filename extension decides, and only images are accepted by declared type when the name is not recognised.
Upload refusals: a name that is not recognised (no extension, or one outside the list) with a Content-Type that is not one of the four image types is 400 INVALID_MIME, content that does not match the extension (an archive with no signature) is 400 MIME_MISMATCH, and an empty file is 400 INVALID_FILE_EMPTY.
⚠️ Image uploads narrowed in two places. The attachment class is now decided by the filename extension, and where the extension and the declared type disagree the answer changed:
Before
Image class was decided by the declared Content-Type, so a filename extension that disagreed with it was ignored.
After
The extension decides, and the two disagreeing cases answer differently:
photo.zipwithContent-Type: image/pngand PNG bytes used to be accepted as an image (200,kind: IMAGE); it now answers400 MIME_MISMATCH;shot.txtwithContent-Type: image/pngused to become an image with a thumbnail; it is now accepted as a document (kind: DOCUMENT) and gets no thumbnail.
What did not narrow: a part whose name is not recognised — no extension (blob, the name FormData.append gives it) or an extension outside both lists (report.pdf) — is still accepted as an image when its Content-Type is one of the previously accepted image types and its bytes really are an image. Conversely, a PNG with an EMPTY Content-Type, refused before, is now accepted by its filename extension.
What integrators should do. Send a filename whose extension matches the content. If you built the part by hand and gave it a name with an unrelated extension, relying on Content-Type, fix the name — that pair is exactly what stopped being accepted.
BC-1006-17: reading, updating and deleting a smart process field check that the field belongs to the smart process in the path
Old format supported until: not provided
Before
GET /v1/items/:entityTypeId/userfields/:id, PATCH /v1/items/:entityTypeId/userfields/:id and DELETE /v1/items/:entityTypeId/userfields/:id, as well as the invoice short addresses /v1/userfields/invoices/:id, found the field by its id alone and did not match it against :entityTypeId. A request through the invoice path with the id of a deal field read that field and answered 200. A field that no longer exists answered 422 BITRIX_ERROR with a permission-refusal message, including a repeated DELETE.
After
Before reading, updating or deleting, the platform checks that the smart process in the path has a field with this id. A field of another entity and a deleted field get the same answer: 404 NOT_FOUND for GET, 404 ENTITY_NOT_FOUND for PATCH and DELETE. Update and delete then send nothing to Bitrix24. 422 BITRIX_ERROR remains for a field deleted between the check and the request itself.
What integrators should do
Move the "field is missing" branch from 422 BITRIX_ERROR to 404: NOT_FOUND for reading, ENTITY_NOT_FOUND for updating and deleting. A repeated DELETE answering 404 means the field is already gone. If an integration reached a field through the path of another entity, use the path of the entity the field belongs to: for a deal field, /v1/userfields/deals/:id. Each of the three operations takes one extra request to Bitrix24.
FIX-1006-18: the business-process editor spec names when the section is unavailable
Before
The OpenAPI specification described the /v1/workflow-designer methods as an available contract and did not name DESIGNER_NOT_RELEASED. GET /v1/workflow-designer/capabilities did not name that reason.
After
The response remains 200 on GET /v1/workflow-designer/capabilities: while the section is not released for this key, available is false and reason is DESIGNER_NOT_RELEASED. The other methods of the section still answer 403 DESIGNER_NOT_RELEASED and do not call Bitrix24. The specification now names the same fact. Once the section is released for the key, the methods are served on the merits and this code is not returned.
NEW-1006-19: Continue note search and list documents
GET and POST /v1/note/documents/search accept an optional offset from 0 to 10000 to fetch the next result page. While meta.hasMore is true, increase offset by limit; if the next offset exceeds 10000, use the list for a complete traversal. The new GET /v1/note/documents returns a flat document list and meta.nextCursor. Send that cursor as URL-encoded JSON in the next request's afterCursor query parameter until it becomes null, including after an empty page. The knowledge-base contents remain a tree, not a list page.
FIX-1006-20: A missing payment product returns 404 regardless of the Bitrix24 account language
Before
Adding a nonexistent product row through POST /v1/crm-payments/{id}/products could return 422 BITRIX_ERROR instead of 404 ENTITY_NOT_FOUND in Bitrix24 accounts using some languages.
After
When Bitrix24 confirms that the product row is absent, the API returns 404 ENTITY_NOT_FOUND regardless of the message language. If the row cannot be checked, the original add error is preserved.
BC-1006-21: Galaxy app deploy validates env line size
Old format supported until: not provided
Before
Galaxy app deploy accepted env without limiting the length of the complete variable line.
After
On POST /v1/infra/servers/:id/deploy, Galaxy requests whose full UTF-8 KEY=VALUE\n line exceeds 65536 bytes now receive 400 GALAXY_DEPLOY_INVALID_ENV. The same env limits apply when creating through POST /v1/infra/servers. Values containing \r, \n, NUL, or malformed Unicode surrogates receive 400 VALIDATION_ERROR on deploy and 400 INVALID_REQUEST on create.
What integrators should do
Before sending a request, check each Galaxy env line in UTF-8 including the key, =, and trailing newline; do not send forbidden characters.
BC-1006-22: reading post comments returns only valid identifiers and file fields
Old format supported until: not provided
Before
GET /v1/posts/comments could return fractional comment and attachment identifiers. The response schema did not enumerate the available file fields.
After
The successful HTTP 200 response is preserved. Comment and attachment identifiers are returned only as integers, and files contain only the documented optional fields. data.files can still be an array or a dictionary keyed by numeric IDs.
Impact on integrations
This narrows the previously published native data.files response: fields outside the listed allow-list are no longer returned. Integrations that used those undocumented fields must migrate to the documented fields (id, date, type, name, size, image, authorId, authorName, urlPreview, urlShow, urlDownload); there is no compatibility mode that preserves the old field set. Invalid identifiers are still omitted from the response.
What integrators should do
Review data.files handling and replace reads of undocumented fields with the listed allow-list; treat unsupported fields as absent.
NEW-1006-23: Copy, move, reorder and delete page blocks
Added POST actions copy, move, up, down, show, hide, purge under /v1/pages/:pageId/blocks/:blockId/ and bulk-purge under /v1/pages/:pageId/blocks/. Requires landing. Block ownership is checked before writing. Order and visibility are read back. purge and bulk-purge irreversibly delete blocks and their files; bulk-purge requires non-empty blockIds, at most 50 blocks and 50 images. Surviving blocks return 422 BITRIX_NO_EFFECT with error.blockIds. Order boundaries return 409 BLOCK_WRONG_SORT.
FIX-1006-24: server rename updates the application placement label
Before
PATCH /v1/infra/servers/:id with a new displayName copied the name to the server's application, but the label of its Bitrix24 placement — a CRM card tab or a left menu item — kept the old name.
After
When the server's application has placements, changing displayName first rebinds them with the new title and only then saves the name. If Bitrix24 did not confirm the binding, the name stays unchanged on both the server and the application, and the call can be retried: 502 BITRIX_PARTIAL_REBIND with the placement codes in error.unbound / error.restored, 400 NO_USER_TOKEN when the application is not authorized in Bitrix24, 400 BOX_NO_DEVELOPER_KEY / APP_NOT_INSTALLED_ON_BOX on a self-hosted Bitrix24, 409 APPLICATION_OP_IN_PROGRESS while another operation on the application is running. A key that may not change Bitrix24 data gets 403 WRITE_BLOCKED_READONLY_KEY under the same conditions as an application rename through PATCH /v1/apps/:id. Renaming a server without an application or an application without placements, and editing only the description, work as before; the response remains HTTP 200.
Impact on integrators
A client renaming the server of an application with placements should handle these refusals: the name is not saved in that case, and retrying the call is safe.
NEW-1006-25: Read page blocks and catalog samples
Added GET /v1/pages/:pageId/blocks/:blockId, GET /v1/pages/:pageId/blocks/:blockId/content, GET /v1/block-repository/:code/content and GET /v1/block-repository/:code/manifest. Requires the landing scope; READONLY keys can read. Optional query scope=KNOWLEDGE|GROUP|MAINPAGE selects the page context.
Reads include drafts. A block from another page, missing sample or manifest returns 404 ENTITY_NOT_FOUND. URL-encode the block code in the path. Application blocks repo_N have no manifest file. Manifest nodes and cards keys are selectors. Content returns HTML and a narrow set of data without the full manifest; php: true denotes a code block with restricted content editing. Block dates are ISO wall clocks without an invented timezone. Credential-bearing strings are replaced with [REDACTED], including the entire HTML string if it contains a secret.