# API changes: October 26, 2026

[← Changelog](/docs/changelog) · [October 2026](/docs/changelog/2026-10)

### FIX-1026-1: API reference field tables reflect update restrictions

**Before**

API reference field tables presented fields accepted only during creation
as writable during record updates as well.

**After**

The tables preserve `createOnly` and `readonlyOnUpdate` flags. Update cards mark
these fields as `readonly`. Their availability during creation is preserved.

**Impact on integrators**

API behavior and request examples are unchanged. The tables describe existing
write restrictions more accurately.

### NEW-1026-2: Drive agent documentation links in GET /v1/guide

The `diskAgent` block of the `GET /v1/guide` response gained a `docs` object with eight links to the Drive agent documentation pages: `index`, `capabilities`, `search`, `uploadsReserve`, `uploads`, `uploadsList`, `uploadsGet` and `syncCheck`. They lead to the agent overview, the available capabilities, file and folder search, the upload reserve, the content transfer, the list of upload operations, the state of one operation and the object visibility check. The object is returned to a key with the `disk` scope, the former `diskAgent` fields stay in place, and the response remains HTTP 200.

### BC-1026-3: Org-structure node and mailbox lists reject filtering and sorting

> Old format supported until: not provided

**Before**

[GET /v1/humanresources/nodes](/docs/humanresources/nodes/list) and [GET /v1/mail/mailboxes](/docs/mail/mailboxes/list) forwarded `filter` to Bitrix24 and returned `422 BITRIX_ERROR` with a message about an unrecognized filter expression. `sort` and `order` returned a successful response even though the record order did not change. The API description declared `filter`, `sort`, `order`, `withTotal` and the `meta.total` field for these lists.

**After**

A filter on any field other than `type` for nodes is refused before reaching Bitrix24 with `400 UNSUPPORTED_FILTER`, and any `sort` or `order` with `400 INVALID_SORT_FIELD`. The same refusals apply in [POST /v1/humanresources/nodes/aggregate](/docs/humanresources/nodes/aggregate) and in sub-calls of [POST /v1/batch](/docs/batch), `POST /v1/humanresources/nodes/batch` and `POST /v1/mail/mailboxes/batch`. `withTotal` is still accepted and has no effect: these lists never report a total count, so `withTotal` and `meta.total` are removed from the API description, as are `filter` for mailboxes and `sort` and `order` for both lists.

**What integrators should do**

Remove `filter` (except `type` for nodes), `sort` and `order` from these requests. Find nodes by name with [POST /v1/humanresources/nodes/search](/docs/humanresources/nodes/search) and apply the order you need in your application. Detect the end of the list by `meta.hasMore`.

### BC-1026-4: deploy refuses paths with a `.vibe-prev` directory, which the platform reserves

> Old format supported until: not provided

**Before**

[POST /v1/infra/servers/:id/deploy](/docs/infra/deploy/deploy) accepted `extractTo` and `dataDirs` entries that contain a directory whose name ends in `.vibe-prev` — for example `"dataDirs": ["/opt/app.vibe-prev"]` with `"extractTo": "/opt/app"`.

**After**

A clean deploy keeps the previous version of the application in the `<extractTo>.vibe-prev` directory and deletes that directory in the `clean` step and after the `flatten` step. A data directory at such a path would be erased on every deploy, so an `extractTo` or a `dataDirs` entry in which any directory is named `<name>.vibe-prev` is now refused with `400 PREVIOUS_TREE_DIRECTORY_RESERVED`. The check runs before the deploy takes the server, so a refusal changes nothing on the server. The response text names the refused path.

**What integrators should do**

If `extractTo` or a `dataDirs` directory is named that way, move the data to a directory with another name and pass the new path to the deploy. All other paths are accepted as before.

### FIX-1026-5: a failed redeploy no longer leaves the application without files

**Before**

On a clean deploy through [POST /v1/infra/servers/:id/deploy](/docs/infra/deploy/deploy), the `clean` step deleted the contents of `extractTo` before the new archive was downloaded. If the deploy aborted during the download or right after extraction, the server was left with neither the previous nor the new version of the application. A hang while removing the uploaded archive or while moving a nested folder up into the root of `extractTo` was not reported as a separate step.

**After**

The `clean` step moves the previous tree into the sibling directory `<extractTo>.vibe-prev` instead of deleting it — except when the move is impossible: `extractTo` turned out to be a mount point, the file system has no room for a second copy, or the size of the tree could not be measured; the previous contents are then deleted with no way to bring them back. When `extractTo` is a symbolic link, the step neither moves nor deletes anything: the new archive is extracted over the previous files. If the deploy aborts before the `flatten` step completes and the outcome of the archive delivery is known, the platform tries to put the moved tree back over the same server connection; a failed move-back is not shown in the deploy response, and the application stays stopped either way. When the download outcome is unknown, the tree is not put back and stays in the sibling directory (see "Impact on integrators"). After `flatten` the platform deletes the sibling directory; if the deletion does not go through — the server was busy with another command or the connection dropped — the directory stays until the next clean deploy, which deletes it first. `data.steps[]` gains the `remove_uploaded_archive` and `flatten` steps after `download`: if the command of either one is cut off, `error.step` names that step. The `clean` step timeout is 120 seconds.

**Impact on integrators**

No request changes are needed. During the download the disk holds two copies of the application, the previous one and the new one. If the download outcome is unknown (`DOWNLOAD_OUTCOME_UNCONFIRMED`, `DOWNLOAD_COMMIT_UNCONFIRMED`, `DOWNLOAD_RELAY_INTERRUPTED`, or the connection to the server dropped after the archive delivery started), or the move-back itself or the deletion after `flatten` failed, the previous tree stays in `<extractTo>.vibe-prev` and the next deploy deletes it first — copy it out before retrying if you need it. `extractTo` and `dataDirs` paths with that name are refused with `400 PREVIOUS_TREE_DIRECTORY_RESERVED`.

### NEW-1026-6: Five-hour window phase and Cowork turn completion marker

[GET /v1/cowork/me](/docs/cowork/me) and [GET /v1/cowork/state](/docs/cowork/state) return `completion.phase` (`normal`, `landing`, `exhausted`) and `completion.resetAt`. A successful [POST /v1/chat/completions](/docs/ai/chat/completions) response may carry `X-Cowork-Completion-Mode` (`landing-finish` or `reserve`) and `X-Cowork-Completion-Reset-At` when finishing an ongoing turn. A new task is admitted normally before the window runs out.

### FIX-1026-7: app address with a name instead of app-… in handlers and appUrl

**Before**

An address of the form `https://<name>.<platform app domain>/…`, where `<name>` is a single label without the `app-` prefix, was accepted in `appUrl`, in a placement handler, in the `HANDLER` of a business process robot or activity, and in a bot `webhookUrl` just like an `app-…` address, and was stored as is, but it led nowhere: before app names existed, such an address was bound to no app, and a request to it got a platform answer that the app was not found. No placement, robot or bot with such an address worked. A name is not bound to an app forever, so an address stored with it could later lead to another app.

**After**

If the name is bound to a server of your Bitrix24 account, the address is stored as the `app-…` address of that server with the same path and parameters. Any other name is refused with `422 APP_HOST_NOT_ALLOWED_HERE` before Bitrix24 is called, and nothing is stored. Inside [POST /v1/batch](/docs/batch) the same code arrives in the error of the single call.

**Affected endpoints:** [POST /v1/apps](/docs/apps/create), [PATCH /v1/apps/:id](/docs/apps/update), [POST /v1/apps/:id/publish](/docs/apps/publish), [POST /v1/placements/bind](/docs/apps/placements/bind), [POST /v1/bots](/docs/bots/management/create), [PATCH /v1/bots/:botId](/docs/bots/management/update), [POST /v1/bizproc-robots](/docs/entities/bizproc-robots), [POST /v1/bizproc-activities](/docs/entities/bizproc-activities), [POST /v1/batch](/docs/batch), `POST /v1/cowork/portal-rest`

**Impact on integrators**

No change is needed, so this entry is classified as a fix, not as a breaking change. The refusal applies only to an address that led to no app before this change, so no working integration could rely on it. App names appear only with this change and are enabled for Bitrix24 accounts gradually. The refusal applies only to an address with a name; `app-…` addresses and addresses outside the platform are checked as before. In handlers and `appUrl`, use the app's `app-…` address.

### NEW-1026-8: MCP package 3.3.0: sign-in flow and CRM form guidance

In `@bitrix24/mcp-vibecode-api` 3.3.0, the `add-user-login` flow asks which sign-in providers to offer and supports a chosen provider that needs no registration: ready-made environment variable values are applied without requesting a client id.

Compared with 3.2.1, `call_api` guidance for CRM forms covers reading configuration and dictionaries, creating, updating, deleting, activating and validating forms without saving, submitting results and sending a form to an open-line session, embedding settings and connected places. Writes require a READWRITE key; validation without saving also works with READONLY.

The entity reference no longer suggests `sort` for lists without sorting support, including departments, structure nodes and mailboxes. Server creation guidance names Node.js 24 as the default runtime. Deploy and diagnostic instructions require waiting for a server resize on `EXEC_BUSY`, and the deploy flow explains when the previous application tree is preserved and restored. Upgrade the package and restart the MCP session to load the new guidance.

### FIX-1026-10: Company connection daily caps are now optional

**Before**

A missing daily cap for the Bitrix24 account or company connection blocked connection and requests.

**After**

Daily caps are independent and optional: `null` means no corresponding cap. General limits, usage accounting and billing remain in force. `CONNECT_COMPANY_NOT_READY` reports temporary technical conditions for connection, not a requirement to set a daily cap. Company key issuance remains closed until the technical conditions are met.

### NEW-1026-11: List unread mention and reaction marks

[GET /v1/chats/anchors](/docs/chats/messages/anchors-list) returns all your anchors across chats in one request, ordered by `messageId`, highest first. There are no query parameters. The `im` scope is required, and read-only keys are supported. Reading does not remove marks or join chats.

The method is rolling out in the `im 26.1600.0` update. Until the update reaches your Bitrix24 account, the call returns `422 METHOD_NOT_YET_AVAILABLE` with `error.release`.

### BC-1026-12: Access for hour-long cloud tasks

> Old format supported until: not provided

**Before**

Key and consent lifetime checks for a one-time cloud task covered a short run.

**After**

Creating or rescheduling a one-time task through `POST /v1/cowork/cloud-tasks` and `PATCH /v1/cowork/cloud-tasks/{id}` requires access until the scheduled time plus 71 minutes: 70 minutes for the run including preparation and completion, and one minute of allowed start lateness. Insufficient key lifetime returns `CREDENTIAL_EXPIRING`. Key and consent lifetimes are never extended automatically.

**What integrators should do**

Before confirming a task, check that the current access covers the complete run. If it is refused, renew access and confirm the task again.

### FIX-1026-13: Incomplete aggregate counts are now marked

**Before**

When Bitrix24 omitted `total`, the platform recovered the count by paging. A page error or the 5000-row ceiling could stop the walk, but [POST /v1/deals/aggregate](/docs/entities/deals/aggregate) and other POST aggregates returned `200` with `meta.truncated: false` and presented the partial `count` as exact.

**After**

The response remains `200`. When count recovery stops early, `data.truncated` and `meta.truncated` are `true`, while `count` and `meta.totalRecords` are lower bounds. `meta.warnings` contains `AGGREGATE_TRUNCATED`. A failed or malformed page has a safe `meta.pageErrorSample` with code `AGGREGATE_COUNT_PAGE_FAILED`; the ceiling is marked by `meta.countWalkLimit: 5000`. A complete count still has `meta.truncated: false`.

**Impact on integrations**

Check `meta.truncated` before treating `count` as an exact total. If it is `true`, narrow the filter or retry the request.

### BC-1026-14: Web search uses AI quota

> Old format supported until: not provided

**Before**

Paid [POST /v1/search](/docs/search/run) and [POST /v1/research](/docs/search/research) requests with sufficient wallet balance succeeded and deducted Ꝟ from the wallet.

**After**

Requests first use the Bitrix24 account AI quota, while requests with a Cowork key use the seat quota. Usage beyond the AI quota uses the wallet when overage is enabled and available. Sufficient wallet balance no longer always guarantees that a request can proceed. Before the SSE stream starts, the following ordinary HTTP error responses may occur:

- `402 AI_QUOTA_EXHAUSTED` — AI quota is exhausted and wallet overage is unavailable. Fields `error.reason` and `error.resetAt` describe the reason and reset time.
- `429 AI_PACING_LIMITED` — the quota pacing limit is reached. The response includes `error.reason`, `error.overageDenied`, `error.resetAt` and the `Retry-After` header in seconds.
- `402 COWORK_QUOTA_EXHAUSTED` — a Cowork seat quota window is exhausted. Field `error.window` is `fiveHour`, `week` or `month`. The response includes `error.resetAt` and the `Retry-After` header in seconds.
- `402 COWORK_SUBSCRIPTION_INACTIVE` — there is no active Cowork seat.

The synchronous search response and the `done` event in both SSE streams gain a `billing_source` field: `wallet`, `quota`, `cowork` or `byok`. The value `wallet` includes usage beyond the AI quota. The field is omitted for a free request using a platform key. Field `cost_vibes` means the amount deducted from the wallet: it is `0` when using AI quota, Cowork seat quota or your own key.

The `byModel` array in [GET /v1/ai/quota](/docs/ai/consumption/quota) may include a row with the reserved `modelId: "web-search"`: this is the quota share used by web search, rather than a model in the catalogue. Fields `calls` and `pctOfLimit` show the request count and share of the monthly limit.

**What integrators should do**

Handle the new refusals before opening SSE. For quota limits, wait until `error.resetAt` or for the delay in `Retry-After`. To pay for usage beyond the AI quota, enable overage in the account dashboard and top up the wallet. If a Cowork seat is inactive, activate or resume it. You can also switch search to your own key (BYOK). Read the payment source from `billing_source` and the wallet deduction from `cost_vibes`. In the quota breakdown, handle `web-search` separately from catalogue models.

### NEW-1026-15: Rejection before a personal model call starts

Personal Cowork calls through `/v1/ai/chat/completions`, `/v1/ai/images/generations` and `/v1/ai/audio/transcriptions` may return HTTP 503 with `USAGE_BASIS_UNAVAILABLE` in `error.type` when call registration is temporarily unavailable. The provider request has not started in this case; the client can retry later.

### FIX-1026-16: temporary promotion limit-reset failures can be retried safely

**Before**

Under contention, `POST /v1/cowork/limits/reset` waited for a lock and returned a generic 500 error if it failed.

**After**

A V1 call without `resetVersion` returns `503 COWORK_LIMIT_RESET_BUSY` only for temporary contention. Other failures return a generic 500 error. In both cases, the right and usage windows remain unchanged, and no reset is deferred. Successful responses still contain `rightId`, `usedAt` and `alreadyUsed`; repeating a spent right returns `alreadyUsed: true` and the original spend time.

**Impact on integrators**

After `COWORK_LIMIT_RESET_BUSY`, retry the same `rightId` after a pause. This is a new attempt; no request UUID or operation polling is needed.

### NEW-1026-17: An overly complex request body is refused with 413 BODY_TOO_COMPLEX

A request body with more than 100,000 JSON values, an array longer than 20,000 items or nesting deeper than 128 levels is refused with `413 BODY_TOO_COMPLEX` before the method runs. The body root, every array item and every object field each count as one value. A string of any length, a base64 file included, is one value. The `error.message` names the limit that was hit.

On AI methods (`/v1/ai/*`, `/v1/chat/*`, `/v1/audio/*`, `/v1/models`) the refusal comes in the OpenAI-compatible envelope: `error.code` is `body_too_complex` and `error.type` is `invalid_request_error`.

The limits sit well above the largest bodies that API methods accept. Retrying the same body will not help: split the data across several requests. See [error codes](/docs/errors).

### NEW-1026-18: company key for verified self-hosted Bitrix24 accounts

The company key in Partner Connect is also available on self-hosted Bitrix24 accounts verified by the platform. Application permissions and administrator consent are still required.
