# API changes: September 28, 2026

[← Changelog](/docs/changelog) · [September 2026](/docs/changelog/2026-09)

### NEW-0928-1: task results through legacy REST

The Vibecode API now has four task result routes: create from a legacy comment, list, first, and last. They call `tasks.Task.Result.*` and return the Bitrix24 result unchanged. An empty list remains `[]`, and no first or last result is `{ "result": 0 }`. Creating from a comment applies only to legacy forum comments; the new task card is not promised.

### NEW-0928-2: task results through REST 3.0

The Vibecode API adds four routes to create a task result, create one from a chat message, update it, and delete it. They call Bitrix24 REST 3.0 methods and preserve the response inside data. Every route requires the task or tasks scope and write access.

**Affected endpoints:** POST /v1/task-results, POST /v1/task-results/from-chat-message, PATCH /v1/task-results/:id, DELETE /v1/task-results/:id. [Task result guide](/docs/entities/tasks/results-v3).

### NEW-0928-3: Four task template methods

The Vibecode API now provides task template reads, lists, additions, and updates. `POST /v1/task-templates` calls `tasks.Template.add` and returns an ID. The list preserves the `task_templates` shape and next-page information.

### NEW-0928-4: 12 Scrum operations are available through named routes

New routes cover `/v1/scrum/backlogs`, epic and stage deletion, sprint creation, update, deletion, start and completion, and adding or removing a task on a board. Each route calls its Bitrix24 method and returns the result in `data`. Completing the active sprint takes a group ID. Existing successful responses remain successful and unchanged.

### FIX-0928-5: creating a custom field now checks the value that is sent to Bitrix24

**Before**

`POST /v1/userfields/users` and `POST /v1/items/{entityTypeId}/userfields` (together with `POST /v1/userfields/invoices`) checked required fields against the first spelling of a key in the body. When the body carried both spellings — `userTypeId` and `USER_TYPE_ID` (for employee fields also `fieldName` and `FIELD_NAME`) — one value passed the check while the other was sent to Bitrix24. An empty value reached the account and came back as `422 BITRIX_ERROR` with `b24Code: "0"`, which does not say what is wrong with the request.

**After**

The value that is actually sent to Bitrix24 is checked: with two spellings of one key the last one in the body wins, as in `POST /v1/userfields/{entity}`. An empty or missing value is rejected before the account is called, with `400 MISSING_FIELD`. For smart processes and invoices a single `userTypeId` key is sent to Bitrix24, even when the body passes `USER_TYPE_ID`. Requests that use one spelling of a key work as before.

### FIX-0928-6: a repeated `POST /v1/bots` for an existing bot no longer breaks its token

**Before**

A repeated `POST /v1/bots` with the `code` of an already registered bot answered `201`, but afterwards the bot stopped working: calls to `/v1/bots/{botId}/*` failed with an authorization error, and the bot's incoming webhooks were not delivered. The Bitrix24 account kept the bot's previous credentials, while we stored new ones the Bitrix24 account did not accept.

**After**

When the Bitrix24 account returns the same `botId`, the bot's previous credentials are kept and it keeps working. The `201` response and its shape are unchanged.

### BC-0928-7: the `agent_turn_loop_detected` refusal for a looping agent turn is switched on

> Old format supported until: not provided

**Before**

The `agent_turn_loop_detected` (409) refusal code of [POST /v1/chat/completions](/docs/ai/chat/completions) was announced but not enforced: a request in which many model answers without `tool_calls` had piled up after the last message with the `user` role was served as usual.

**After**

The refusal is enforced. If `messages` holds 20 or more model answers with the `assistant` role and without `tool_calls` after the last message with the `user` role, the request receives `409` with the code `agent_turn_loop_detected`, the model is not called and no limit is spent. The threshold is raised from the previously announced 15 to 20. Answers with `tool_calls` still do not count, so a turn in which the model calls tools at every step does not meet the condition. No support window for the previous behavior is provided: the refusal protects against an idle loop that would otherwise spend the limit until it runs out.

**What integrators should do**

A regular integration needs no changes. If your client continues a turn on its own without a new user message and receives `agent_turn_loop_detected`, stop the turn and wait for the user's message: a new message with the `user` role restarts the count.

### NEW-0928-8: Definition of Done settings and sprint metric source data are available

The VibeCode API adds four routes for reading and saving Definition of Done settings and task lists, plus two sprint data routes: `/v1/scrum/groups/:groupId/burn-down` and `/v1/scrum/groups/:groupId/team-speed`. They return the Bitrix24 result in `data` without computing metrics in the platform. The DoD list read route is not published yet because its successful REST response needs verification on an accessible group with configured DoD.

### NEW-0928-9: Flows and task status lists are available through the API

Nine `/v1/tasks/flows` routes now create, read, update, and delete flows, toggle activity, and retrieve separate completed, pending, and in-progress task lists. Each route calls the corresponding Bitrix24 method and returns its result in `data`. READONLY keys can read; changes require a write-enabled key. [Flow guide](/docs/entities/tasks/flows).

### FIX-0928-10: the seat assignment link in the Cowork members list opens the Employees section

**Before**

The `links.assign` field in the `GET /v1/platform/cowork/members` response pointed to `/admin/cowork`. That page redirects to the company console overview, so the account administrator did not land where seats are assigned.

**After**

`links.assign` points to `/admin/company?ctab=people` — the Employees section of the company console, where the administrator assigns purchased seats. The other links in the `links` block are unchanged, and the response remains HTTP 200.

**Impact on integrators**

No changes are needed: keep taking the link from the response instead of building it yourself.

### FIX-0928-11: Public apps report unavailability when waking is blocked

**Before**

[A public app](/docs/infra/app-runtime) with no tunnel kept showing the startup waiting page with status `503` when waking was blocked, even though it could not be brought up.

**After**

Only in `PUBLIC` mode, a confirmed wake ban with no tunnel returns `409`: browsers get "App temporarily unavailable" with a "Refresh" button, and machine clients get `BH_APP_UNAVAILABLE` in JSON. The response discloses no reason, balance information or subscription brand and carries no `Retry-After`. Automatic waiting ends and no wake starts. In private mode, an identified user still receives `402 BH_WAKE_BLOCKED`.

**Impact on integrators**

Successful requests work as before. Do not automatically retry a request that returns `BH_APP_UNAVAILABLE`. Once the ban is lifted, the app can be opened manually at its original address, and POST is not retried automatically.

### BC-0928-12: server source access follows the owner key

> Old format supported until: not provided

**Before**

A second personal key of the same user received `404` from [GET /v1/infra/servers/:id](/docs/infra/servers/get) but could read and change sources through the [server source operations](/docs/source-storage/servers). [POST /v1/infra/servers/:id/sources/cleanup](/docs/source-storage/retention) returned `200`.

**After**

The second personal key without an application binding to this server also receives `404` from its source endpoints, including when its owner is an administrator. Pointers in [GET /v1/me/sources](/docs/source-storage/registry) and [GET /v1/apps/:id/sources](/docs/source-storage/versions) no longer advertise access to that key. The current server key and the personal key of its bound application retain access; administrators can still access other users' servers.

**What integrators should do**

Use the server's current managing key or the personal key of the application bound to that server for source requests.

### FIX-0928-13: business process templates, activities and automation rules on an account without the module answer 409 BIZPROC_MODULE_NOT_ENABLED

**Before**

On an account where Business Processes are not included in the plan or are switched off in settings, operations on [workflow templates](/docs/entities/bizproc-templates/list), [activities](/docs/entities/bizproc-activities/list) and [automation rules](/docs/entities/bizproc-robots/list) answered `404 ENTITY_NOT_FOUND`, or `422 BITRIX_ERROR` on an English-language account. That answer looked like a wrong ID, although the cause was the account state. In batch calls — [POST /v1/batch](/docs/batch) and `POST /v1/{entity}/batch` — the same refusal arrived as an item with the internal Bitrix24 code `ERROR_METHOD_NOT_FOUND` or with the generic codes `CALL_FAILED` and `AUTO_PAGINATION_FAILED`. The [running workflows](/docs/automation/workflows/list) section already answered `409 BIZPROC_MODULE_NOT_ENABLED` on the same account.

**After**

On an account without Business Processes, all operations of these three entities that call Bitrix24 answer `409 BIZPROC_MODULE_NOT_ENABLED` — the same way as the running workflows section. In batch calls the batch response stays HTTP 200, and the refused item carries the code `BIZPROC_MODULE_NOT_ENABLED` with the same message. The message names the Bitrix24 method that was called, both possible causes and the action to take: ask an account administrator to enable Business Processes. Other errors of these operations are unchanged.

**Impact on integrators**

No action is required: the refusal was a 4xx and stays a 4xx, and the former `404 ENTITY_NOT_FOUND` and `422 BITRIX_ERROR` were never documented for this state. An integration that caught the internal code `ERROR_METHOD_NOT_FOUND` or the generic codes `CALL_FAILED` and `AUTO_PAGINATION_FAILED` in a batch item now sees the dedicated code `BIZPROC_MODULE_NOT_ENABLED` for this case; an integration that treats an unknown code as a failed call keeps working. Retrying does not help while Business Processes are unavailable on the account.

### NEW-0928-14: Cowork plans return a promo block: a seat-limited promotion and the price of the rest of the order

`GET /v1/platform/cowork/plans` returns a seat-limited promotion in the form the checkout reads: a `promo` block at the root of the response and per-term prices in `price.terms[]`.

The `promo` block is `null` when the Bitrix24 account has no seat-limited promotion. Otherwise it holds:

- `code` — which promotion applies: `FIRST_PURCHASE`, `TEAM_VOLUME` or `PROMO`
- `discountPercent` — the promotion percentage, for the "−N %" caption only
- `plans` — plans whose terms have a promotion price
- `seatsLimit` — how many seats of an order go at the promotion price, that is, how many seats the account can still get at it
- `rest` — the second tier: the price of the rest of the order beyond `seatsLimit`, or `null`. It holds `discountPercent`, the caption percentage, and `plans`, the plans with a rest-of-order price

Each term in `price.terms[]` gains these fields:

- `promo` — `vibesMonth` and `vibesTotal` of a seat at the promotion price for this term
- `promoRest` — `vibesMonth` and `vibesTotal` of a rest-of-order seat for this term

The platform computes and rounds the prices, `vibesTotal` equals `vibesMonth` × `months`. When a term has no such price, the field is absent. Promotions without a seat limit are not in the block: their price is already in `vibesMonth` and `vibesTotal`.

How to price an order: seats within `seatsLimit` at `promo`, starting from the seat with the largest saving over the whole term (`vibesTotal` − `promo.vibesTotal`), on a tie the higher plan, then the longer term. The rest of the order at `promoRest`, only if at least one seat went at `promo`, otherwise at `vibesMonth` and `vibesTotal`. An order without a quote is credited by the same rules as of the payment moment: a seat gets the `promoRest` price only if a seat at the `promo` price was created in the same order.

### FIX-0928-15: empty POST requests receive the intended validation response

**Before**

POST requests without a body or a `Content-Type` header to the endpoints listed below returned HTTP 500 instead of a bad-request response.

**After**

These requests receive the existing HTTP 400 response. For [POST /v1/calls/register](/docs/telephony/crm/register), the response to a successful request remains HTTP 201, while for [POST /v1/connect/device/authorize](/docs/partner-connect), the response to a successful request remains HTTP 200.

**Impact on integrators**

No changes are required. Clients can handle missing required parameters as a request error rather than an internal server error.

**Affected endpoints:** [POST /v1/calls/register](/docs/telephony/crm/register), [POST /v1/calls/:callId/show](/docs/telephony/crm/show), [POST /v1/calls/:callId/hide](/docs/telephony/crm/hide), [POST /v1/calls/:callId/finish](/docs/telephony/crm/finish), [POST /v1/calls/:callId/transcription](/docs/telephony/crm/transcription), [POST /v1/calls/auto-call](/docs/telephony/outbound/auto-call), [POST /v1/calls/auto-call-audio](/docs/telephony/outbound/auto-call-audio), [POST /v1/calls/callback](/docs/telephony/outbound/callback), [POST /v1/connect/device/authorize](/docs/partner-connect).

### FIX-0928-16: warning about application access to the Bitrix24 account after deploy

**Before**

A successful [POST /v1/infra/servers/:id/deploy](/docs/infra/deploy/deploy) response with an OAuth app key did not remind callers that the request key is not automatically copied into the application environment and application access to the Bitrix24 account has not been verified.

**After**

A successful response adds this explanation to `warnings`: in JSON for a dedicated virtual machine and a Galaxy application, or in the SSE `done` event. Deploy success and existing warnings are preserved. The new warning is not added for a personal key or a failed deploy. Environment variables and keys are unchanged; the warning does not claim that the application has no credentials. [Application contract](/docs/infra/app-runtime) describes authentication for per-user and headless service flows.

**Impact on integrators**

No API client changes are required. If the application needs to call Bitrix24, its author must explicitly configure runtime authentication; a successful deploy does not verify it. Treat the new `warnings` entry as guidance, not as a deployment error.

### FIX-0928-17: the Cowork desktop key can read its application's server sources again

**Before**

`GET /v1/infra/servers/{id}/sources` and `GET /v1/infra/servers/{id}/sources/{versionId}/download` answered the Cowork desktop key with `404 SERVER_NOT_FOUND`, although `GET /v1/applications` returned the application card with that server to the same key. `GET /v1/me/sources` returned `reachableViaApi: false` and empty pointers for that row.

**After**

The Cowork desktop key lists versions and receives a download link when the server carries a live application card of the same user in the same Bitrix24 account. `GET /v1/me/sources` returns `reachableViaApi: true` and working pointers for that row. Writing, deleting and cleaning up versions stay closed to this key; other secondary personal keys of the server owner gain no access.

### NEW-0928-19: Cowork/Code limit reset with a promotion right

The new [POST /v1/cowork/limits/reset](/docs/cowork/limits-reset) method spends a right to reset
the usage of all three quota windows — the 5-hour, weekly and monthly ones. Rights are granted by
platform promotions and stay valid until the promotion ends. Only a Cowork/Code desktop key can
spend them; `rightId` is the idempotency key, and a repeat with the same value returns
`alreadyUsed: true`.

[GET /v1/cowork/me](/docs/cowork/me) and [GET /v1/cowork/state](/docs/cowork/state) gain a
`limitReset` block: the user's rights, when the last reset happened and whether the account is
frozen. The block arrives when the capability is enabled for the account, and until the first
promotion its list of rights is empty. Check for the key: without it the capability is absent.

### FIX-0928-20: reading sites on an account without the Sites module answers with its own code

**Before**

Reading sites on a Bitrix24 account where the Sites module is unavailable answered `422 BITRIX_ERROR` with "Method not found!", or `404 ENTITY_NOT_FOUND` when Bitrix24 returned the equivalent message in Russian. Neither code explained that the module was disabled, and repeating the request returned the same refusal indefinitely.

**After**

The same requests answer `409 LANDING_MODULE_NOT_ENABLED`, and the message states the reason outright: the Sites module has to be enabled on the account, after which the `landing.*` methods become available. Other Bitrix24 errors on the same addresses keep their previous code.

**Affected endpoints:** [GET /v1/sites](/docs/entities/sites/list), [GET /v1/sites/{id}](/docs/entities/sites/get), [POST /v1/sites/search](/docs/entities/sites/search), [POST /v1/sites/aggregate](/docs/entities/sites/aggregate) and the legacy `GET /v1/sites/aggregate`. Creating, updating and deleting a site go through different Bitrix24 methods and answer as before.

**Impact on integrators**

No call has to change. A handler that parsed the response text to tell a disabled module from a failure can now branch on the `LANDING_MODULE_NOT_ENABLED` code, and retrying such a request is worth postponing until the module is enabled — the answer does not change before that.

### NEW-0928-21: the spec now names the rollout refusal on the call follow-up methods

The call follow-up methods ship in Bitrix24 update `call 26.600.0` and have not reached every account yet. On an account without the update the call answers `422 METHOD_NOT_YET_AVAILABLE` and the error body carries `error.release` with the number of the awaited update — a rollout signal, not an integration error. Until now only the documentation pages said so, while the `openapi.json` spec promised a single `BITRIX_ERROR` code on 422, so a client generated from the spec could not tell a rollout apart from a Bitrix24 refusal. Both codes are now named in the spec, and the operation descriptions carry the release number. The spec does not probe the account, so the notice is general and not the status of yours: call the method, `200` means it is already live there. Affected: [POST /v1/calls/followups/list](/docs/calls/followup/list) and [GET /v1/calls/followups/:callId](/docs/calls/followup/get). No integration changes are required.

### NEW-0928-22: Cowork cloud tasks

The Cowork desktop client can create one-time or recurring tasks after user confirmation, read the schedule, state, and result of each run, edit the text and schedule, pause, resume, stop future runs, start a run manually through `POST /v1/cowork/cloud-tasks/:id/runs`, revoke access, and receive events through replay/SSE. Schedules accept the user's time zone and support calendar recurrence or intervals; a manual run shifts the next interval run but not a calendar run. A run that has already started continues when its task is stopped. Requests require an active Cowork key and are scoped to its user and Bitrix24 account. Creation, confirmation, uploading selected input files, editing, and manual runs require a write-enabled key; a read-only key can view tasks and results. After task confirmation, Cowork can send an immutable snapshot of selected files through `POST /v1/cowork/cloud-task-inputs`; the returned `input_ref` is usable only for that task. Cloud execution supports limited read operations in Bitrix24 and image generation with checks for current access and ordinary user limits.

### FIX-0928-23: Read application sources from Cowork

The Cowork desktop key can again list source versions and obtain a download link for the same user's application bound to a live server. This access remains read-only; other unbound personal keys do not gain it.

### BC-0928-24: Sequential bot polling uses the persisted position

> Old format supported until: not provided

**Before**

[GET /v1/bots/:botId/events](/docs/bots/events/polling) without `offset` could repeat an event. The response reported `persisted: true` before persistence completed.

**After**

A successful response with `persisted: true` confirms the persisted position for the next poll. An overlapping poll receives `409 BOT_EVENTS_BUSY`; failure to confirm the result returns `503 BOT_EVENTS_UNAVAILABLE` without events. Both responses include `Retry-After: 1`. A polling subsystem failure may affect several bots at once. The `limit` documentation now states the existing 1-200 range; out-of-range values are clamped without a new error. An explicit `offset` below the stored position still leaves it unchanged.

**What integrators should do**

Wait for one poll to finish before starting the next. On `409 BOT_EVENTS_BUSY` or `503 BOT_EVENTS_UNAVAILABLE`, retry after one second according to `Retry-After`. Continue without `offset` or use `nextOffset` from the previous response. Keep application deduplication: a connection break after cursor persistence does not guarantee exactly-once application processing.

### NEW-0928-25: seat demo status in Cowork/Code subscription responses

The [GET /v1/cowork/me](/docs/cowork/me) and [GET /v1/cowork/state](/docs/cowork/state) responses include a `demo` field. While the seat has demo access, it is an object with the end moment `until` and the terms of use link `rulesUrl`; otherwise it is `null`. The seat tier stays `FREE`, and quota shares are already computed against the demo limits — show the plan as "Demo" with the end date and a link to the rules.

### FIX-0928-26: a chat response without tool calls is no longer marked as a tool call

**Before**

[POST /v1/chat/completions](/docs/ai/chat/streaming) could return a response with `finish_reason: "tool_calls"` that contained no tool call at all: the model tried to call a tool, but the call stayed plain text. This happened both in a stream and in a non-streamed response. An agent client waited for tool results on such a finish reason, did not end the turn and re-sent the request with the same context until it hit the step limit.

**After**

If the response contains no tool call, `finish_reason: "tool_calls"` arrives as `finish_reason: "stop"`: in a stream, in the terminal event; without a stream, in `choices[].finish_reason`. Responses with real tool calls are unchanged. The response status remains `200`.

**Impact on integrators**

No change is required. The client ends the turn on `finish_reason: "stop"` and shows the received text instead of re-sending the request.

### FIX-0928-27: a connection failure in workflow operations is no longer reported as a disabled module

**Before**

The Workflows section operations — [GET /v1/workflows](/docs/automation/workflows/list), start, termination, log entry and event sending — answered `409 BIZPROC_MODULE_NOT_ENABLED` whenever the error text contained the words "Method not found", regardless of the response code. Transient failures fell under this rule: the account returned an HTML page instead of JSON and its text carried those words (`502`), or the request rate limit answered `429` with the same words in its text. The client received a permanent "ask an administrator to enable the module" refusal and stopped retrying, although a retry would have helped.

**After**

`409 BIZPROC_MODULE_NOT_ENABLED` is returned only for a 4xx client refusal from the account (except `429`) — the same as in the `/v1/bizproc-*` entities and in batch. A transient failure answers with its own code: `502 BITRIX_UNAVAILABLE` or `429 RATE_LIMITED`, and such a request can be retried. An account without the business processes module still receives `409 BIZPROC_MODULE_NOT_ENABLED` with the same message.

**Integrator impact**

No action required. An integration that retries on `502` and `429` now retries these cases as well instead of stopping at `409`.
