# API changes: August 24, 2026

[← Changelog](/docs/changelog) · [August 2026](/docs/changelog/2026-08)

### BC-0824-1: activity type can no longer be changed after creation

> Old format supported until: not provided

**Before**

`PATCH /v1/activities/:id` accepted the `typeId` field. The value never reached storage: an activity type is fixed at creation, so it was discarded. A request carrying `typeId` as its only field ended up with an empty field set and returned the opaque refusal `Fields is not specified.`, which gives no hint that immutability of the type is the reason. A request that also carried at least one writable field answered with success, so the caller believed the type had changed.

**After**

`typeId` is declared as a field that is set only on creation. `PATCH /v1/activities/:id` carrying it returns `400 READONLY_FIELD` and names the field. Both batch update operations answer the same way. `POST /v1/activities` still accepts the field, where it stays mandatory. In the `GET /v1/activities/fields` output, `typeId` now carries the `createOnly` marker.

**What integrators should do**

Remove `typeId` from the body of `PATCH /v1/activities/:id`. If the type genuinely has to change, create an activity with the required type and delete the previous one — the type of an existing activity cannot be edited. The `createOnly` marker in the `GET /v1/activities/fields` response lets you tell such fields apart before sending a request.

### FIX-0824-2: paid accounts no longer receive an error asking them to pay again

**Before**

[POST /v1/apps](/docs/apps/create) could return a `403` error asking a paid account to upgrade when application installation through Bitrix24 failed.

**After**

When Bitrix24 confirms that the plan is paid, the method returns the technical error `502 CONNECTOR_REST_UNAVAILABLE` with a safe reason and no upgrade prompt. A confirmed unpaid plan still returns a `403` plan error.

**Impact on integrations**

Requests require no changes. The technical error can be retried, while the plan error requires an upgrade.

### BC-0824-3: the deployment block changes shape for Belarusian accounts along with their access model

> Old format supported until: not provided

**Before**

An account licensed in Belarus landed in the limited-access bucket under three conditions at
once: it held a demo subscription, it held no paid subscription, and it had no history of
commercial payments. Its Bitrix24 plan — paid or free — did not affect membership, whereas an
account that had ever paid before did not land in the bucket at all. In
[`GET /v1/me`](/docs/keys-auth/me) such an account received a `deployment` block with no
`galaxyApp` sub-block, with `primary` = `standalone` and with a `placementNote` field
explaining that no galaxy host of its own is created for it and that an app must be deployed
in two steps. A one-shot create carrying `source` answered
`400 SOURCE_AT_CREATE_GALAXY_ONLY`.

**After**

The plan-based model has no limited-access bucket at all, so a Belarusian account leaves it in
both directions at once: on a paid or demo Bitrix24 plan it gets full access, on a free plan it
is denied. In both cases the `deployment` block changes shape the same way — provided galaxy
placement is open to the account and it does not yet have a galaxy of its own (both carve-outs
are named below): the
`deployment.galaxyApp` sub-block appears, the `deployment.placementNote` field disappears, and
`deployment.primary` switches from `standalone` to `galaxyApp`. For an account with full
access a one-shot create carrying `source` starts working.

**What integrators should do**

Detect the placement model by the PRESENCE of the `deployment.galaxyApp` sub-block, exactly as
the response reference prescribes. Rewrite any branch keyed on the presence of `placementNote`
or on the value of `primary`: both fields move with the account's access model, not only with
its plan. Read the permission to create a server separately, from
`capabilities.servers.create`: the `deployment` block describes the placement CONTRACT and is
present for a denied account too, while
[`POST /v1/infra/servers`](/docs/infra/servers/create) answers such an account with `402`.
Two carve-outs where the response shape does not change at all. The first is an account with
galaxy placement switched off: neither field is present before or after. The second is an
account that already has a galaxy: `placementNote` explained the absence of a galaxy of its
own, so the owner of a live galaxy host received `galaxyApp` and no `placementNote` while in
the bucket too. The change reaches an account at the moment it is moved onto the plan-based
model, so both response shapes occur side by side across accounts.

### NEW-0824-4: the Bitrix24 plan becomes the access condition for accounts licensed in Belarus

Vibecode admits an account to the infrastructure either by its Bitrix24 plan or by a
subscription, depending on the licence region the account belongs to. Accounts licensed in
Belarus — served by a separate Vibecode deployment, not by this one — move onto the
plan-based model: a paid or a demo Bitrix24 plan grants access there, and an account with
neither is declined. The move is staged, account by account.

Nothing changes on this deployment and no action is required. Access here has always been
granted by the Bitrix24 plan alone: a commercial plan grants full access, a demo plan grants
a limited trial, and on a free plan [`POST /v1/infra/servers`](/docs/infra/servers/create) —
like an app publish, a wake of a sleeping machine or the issuance of a new key — is still
declined with `402` and `INT_TARIFF_REQUIRED`, which [`GET /v1/me`](/docs/keys-auth/me) also
reports in `capabilities.servers.create.reason`. No new field, no new denial code and no new
branch appear in the contract you consume here.

### FIX-0824-5: the server-creation hint in the key response no longer leads nowhere

**Before**

An account whose access is granted by a Bitrix24 plan rather than a subscription received a
`capabilities.servers.create` slot in [`GET /v1/me`](/docs/keys-auth/me) carrying a generic
wording: servers are available on commercial plans or during an active trial. That was wrong
twice over. Such an account is not entitled to the trial — the entitlement is computed on the
subscription model — and the address where a plan is chosen was not named at all. Separately,
for accounts licensed in Belarus the `alternatives[].url` field pointed at the subscription
checkout inside the account itself, and would have kept pointing there after the account moved
onto the plan-based model, where a subscription no longer resolves the denial.

**After**

The slot names the working paths and the address: a paid or demo Bitrix24 plan, and for
Belarus a paid subscription as well. The text in `capabilities.servers.create.userMessage`
now matches the `402` body that [`POST /v1/infra/servers`](/docs/infra/servers/create)
returns for the same account — one denial code no longer says different things on two
surfaces. For accounts licensed in Belarus that have moved onto the plan-based model,
`alternatives[].url` points at the plan-selection page instead of the subscription checkout.

**Impact on integrators**

No action required: a text field and a URL changed value, the response structure is unchanged.
The fix reaches Kazakhstan and Uzbekistan at once, and Belarus as each account is moved onto
the plan-based model. If you render your own copy instead of `userMessage`, review it: the
promise of a trial is wrong for these accounts.

### FIX-0824-6: the denial text for Kazakhstan and Uzbekistan no longer offers a subscription

**Before**

On the deployment that serves Kazakhstan and Uzbekistan an account on a free plan was
refused with the subscription-model text and was asked to activate a subscription that is
not sold in those countries. The action named in the text could not be performed, and the
working paths to access — a paid or a demo Bitrix24 plan — were not named at all, nor was
the address where a plan is chosen.

**After**

Such an account is now refused with the plan-based code of its own region, and the text
names both working paths and the address. The subscription brand is gone from it. The
correction reaches every surface where an access denial is visible to the client: server
creation ([`POST /v1/infra/servers`](/docs/infra/servers/create)), an app publish, a wake of
a sleeping machine and the issuance of a new key, as well as
`capabilities.servers.create.reason` in [`GET /v1/me`](/docs/keys-auth/me).

Nothing changes on this deployment and no action is required here. Access on this surface is
granted by the Bitrix24 plan alone, a free-plan denial is still answered with `402` and
`INT_TARIFF_REQUIRED`, and neither the request nor the shape of the response changes. The
regional denial codes corrected above are reachable only on the deployment named there.

### BC-0824-7: bot re-authorization is now explicit and safe

> Old format supported until: not provided

**Before**

`POST /v1/bots/:botId/reauth` could clear any disabled bot state, while `410 BOT_DISABLED` did not tell clients whether automatic recovery was allowed.

**After**

`410 BOT_DISABLED` includes boolean `error.details.reauthAllowed`. Call `POST /v1/bots/:botId/reauth` automatically only when `reauthAllowed=true`; the server emits that signal only for writable bots disabled by authentication failures and enables it gradually. A manual call also remains the credential probe for an active bot after ownership transfer. Other disabled states now fail immediately with `409 BOT_REAUTH_NOT_ALLOWED`; a concurrent state change returns `409 BOT_REAUTH_STATE_CHANGED`. Update clients that called re-authorization for every `BOT_DISABLED` response.

### FIX-0824-8: galaxy application deploy warns when environment variables are reset

**Before**

A successful `/deploy` without user `env` recreated the galaxy application without previous variables but did not report that in the response.

**After**

The response includes a `warnings[]` entry asking callers to send the complete `env` on every deploy. A development-team member's deploy, where the owner's variables are preserved, receives no false warning.

**Impact**

The deploy status and behaviour are unchanged; clients should read the existing `warnings[]` array.

### NEW-0824-9: task dependencies are now available through the API

**Before**

The Bitrix24 task card shows a "Related tasks" block, but there was no way to read those links through the API: no dependency fields in the task list, none in a task read by id, nothing about them in the task field description, and no dedicated endpoint. A dashboard that needed the dependency graph could not build it.

**After**

Two read-only endpoints were added. `GET /v1/tasks/:taskId/dependencies` returns the dependencies of one task as an array of id-and-title pairs, sorted by id. `POST /v1/tasks/dependencies/bulk` takes up to 50 tasks and answers per task: successes in `results`, failures in `errors`, counters in `meta`.

The bulk call answers `200` even when every sub-call failed — partial failure is the whole point of it, so what has to be read is `errors`, not only `results`. Duplicate ids collapse silently and the requested counter counts unique ids, so "requested" always equals "succeeded" plus "failed".

**Boundaries, stated explicitly**

Only predecessors are returned — the tasks the requested one depends on. Bitrix24 exposes no reverse direction through the API, so a dashboard builds it by inverting the pairs it collected. The link type is readable by no Bitrix24 method, so it is absent from the response entirely: an empty or guessed value in a contract is worse than a missing field.

Links added through the Gantt chart are invisible to these endpoints: Bitrix24 keeps them separately and returns them from no read method. Telling "there are no links" apart from "there are links, in the invisible store" is impossible here and in raw REST alike.

A task carrying more dependencies than the endpoint returns gets an explicit refusal rather than a truncated list: the response is either complete or a refusal.

**Impact on integrators**

There are no breaking changes — both routes are new. Writing dependencies did not get an endpoint of its own: the set is still changed through the `DEPENDS_ON` field on task update, and the semantics there are a full replacement of the set rather than an addition.

### FIX-0824-10: international bot access keeps the Bitrix24 plan model

**Before**

The international instance already governed account access through the Bitrix24
plan model. Bot permission failures returned `403 BITRIX_ACCESS_DENIED`.

**After**

There is no change to that `.com` contract: bot access stays on the international
plan model. `GET /v1/me?refresh=tariff` continues to refresh the account's
Bitrix24 plan state after an upgrade.

**What integrators should do**

Keep handling international access through the existing plan errors. No new bot
error branch is required on `.com`.

### BC-0824-11: opening a workday no longer confirms an expired state

> Old format supported until: not provided

**Before**

`POST /v1/workday/open` returned `200 success:true` when Bitrix24 left the
workday in the `EXPIRED` status. No new workday was opened.

**After**

An unchanged `EXPIRED` status is returned as HTTP 409 with `success:false` and
the `WORKDAY_EXPIRED` code. The instructions say to read status for the same
user, close the expired day using its `timeStart` date and a report, and then
retry open.

**What integrators should do**

Handle `success:false` and HTTP 409 as an explicit signal that the workday was
not opened; resolve the previous day's state using the response hint first.

### NEW-0824-12: calendar events can be linked to CRM elements

A calendar event now carries a `crmFields` field — the link between a meeting and CRM elements: deals, leads, contacts and companies. The field is readable and writable, is declared in [GET /v1/calendar-events/fields](/docs/entities/calendar-events/fields), and is available in `select`.

The value is an array of typed references: `D_<id>` deal, `C_<id>` contact, `L_<id>` lead, `CO_<id>` company. On create and update the value must be an array; `[]` clears every link, and omitting the field from the body keeps the stored ones. Clearing with an empty array works on `POST` and `PATCH`; in a batch request an empty array is refused rather than silently succeeding — a batch sub-call cannot carry one. On `POST /v1/batch` that is `INVALID_PARAMS` in `data.errors` under the call's `id`; on `POST /v1/calendar-events/batch` it is `400 BATCH_ITEM_VALIDATION` for the whole batch, with the name `INVALID_PARAMS` and the item index inside `message`. An event with no links reads back as `[]` — the empty value never arrives as `null` or an empty string, so a `crmFields.length` check is always safe. An unknown prefix, or a reference to a record that does not exist, is rejected.

**Affected endpoints:** [GET /v1/calendar-events](/docs/entities/calendar-events/list), [GET /v1/calendar-events/:id](/docs/entities/calendar-events/get), [POST /v1/calendar-events/search](/docs/entities/calendar-events/search), [POST /v1/calendar-events](/docs/entities/calendar-events/create), [PATCH /v1/calendar-events/:id](/docs/entities/calendar-events/update), [GET /v1/calendar-events/fields](/docs/entities/calendar-events/fields).

### FIX-0824-13: an application on a galaxy host that does not boot can be deleted without a live tunnel

**Before**

`DELETE /v1/infra/servers/{id}` on a galaxy application answered `502` with the code
`GALAXY_HOST_UNREACHABLE` whenever the host was offline, whatever the reason. When the host guest
operating system does not boot at all (the `provisionErrorCode` field of the server record equals
`GUEST_NOT_BOOTING`), the tunnel will never come back, so retrying helped neither a minute later
nor a day later. Deleting the host itself was blocked too: it answered `409` with the code
`GALAXY_HAS_APPS`, because its applications formally remained alive. The owner ended up in a closed
loop, still holding a quota slot with a machine that no longer runs.

**After**

Once the platform has proven that the host guest operating system does not boot, an application on
that host is deleted without contacting the host: `DELETE /v1/infra/servers/{id}` answers `200`, the
application record is closed, and its access tokens, domain and catalog item are released. After
deleting the applications one by one, the owner deletes the host itself with the regular call — the
`GALAXY_HAS_APPS` refusal no longer appears. The `GALAXY_HOST_UNREACHABLE` code keeps its previous
meaning for every other case: the host is temporarily offline and retrying makes sense.
**Important:** the does-not-boot mark alone does not guarantee the `200`: before deleting without
contacting the host, the platform also confirms through the gateway that no live tunnel
exists. That check is fail-safe — an unreachable gateway, an answer without a connection
list, or a host that came back meanwhile all keep the answer at `502`. Clients need
no changes — the retry loop for this state simply stops being necessary.

### BC-0824-14: an unknown select field name is refused with 400 on almost every entity

> Old format supported until: 18.02.2027

> Until now such a request answered `200` with the requested field simply missing from the records — so the "old format" here means an incomplete answer, not a working one.

**Before**

A field name the entity does not have went into the selection silently. The request ran, the
field was absent from the records, and the explanation sat in `meta.warnings` — where nobody
looks. A typo in `select` therefore looked like a successful request with mysteriously
incomplete records:

```
GET /v1/deals?select=id,titel      →  200, records carry only id
```

Only [calendar events](/docs/entities/calendar-events/list) answered such a name with an error.

**After**

The request is refused before the Bitrix24 call — `400` with the `UNKNOWN_SELECT_FIELD` code
and the list of accepted names in the message. That list is the precise answer to "what may I
ask for".

It applies to the entities whose field set has been verified against Bitrix24: deals, contacts,
companies, leads, quotes, activities, addresses, smart processes, products and product sections,
catalogs with their products and sections, orders and order statuses, statuses, currencies,
calendar sections, files, folders, storages, departments, workgroups, document
templates. Everywhere else the behaviour is unchanged — a warning in `meta.warnings`.

A separate class is a name the entity DOES have but never returns: `GET /v1/{entity}/fields`
shows such a field with `notReturned: true`. In this cohort that is, for example, `currencyId`
on products and `sort` on product sections. It is refused with a `400` too, but under its own
`SELECT_FIELD_NOT_RETURNED` code and a message that names the reason. The separate code is
deliberate: `UNKNOWN_SELECT_FIELD` claims the name does not exist, while the entity's own field
catalogue publishes it — a client that honestly took the name from there would otherwise read
the answer as "the catalogue is lying".

Only the name is checked. Custom fields (`UF_*`, `ufCrm*`) are accepted as before on every
entity; product properties are each accepted on THEIR OWN entity: `PROPERTY_295` on products,
`property295` on catalog products, where their numbers are assigned by Bitrix24; the other
spelling is not understood by the method and the gate rejects it. A `*` (or `UF_*`) value still
means "return every field", and a typo next to it causes no refusal — a warning arrives instead.
In both batch calls — the global one and the per-entity one — the selection refuses only its own
sub-call while neighbouring ones still run.

**What integrators should do**

Check the field names in your `select` against the list in the error message or against the
`GET /v1/{entity}/fields` schema. A request that used to "work" but returned records missing
some of the requested fields will now answer `400` naming exactly which name was not found —
which was its original mistake.

### FIX-0824-15: the `datePeriod` field schema is now visible in `GET /v1/bookings/fields`

**Before**

The `datePeriod` field was described as `"type": "object"` with no nested schema. The shape of the object could not be learned from the contract itself — a client would send `{}` or a date string, get `422 BITRIX_ERROR`, and could only guess the required keys from the error text.

**After**

Fields of type `object` with a known nested shape now carry a `properties` key holding a recursive schema of the nested keys. For `datePeriod` that is `from` and `to`, each with `timestamp` (number, Unix seconds) and `timezone` (string, an IANA zone name). The same key now appears for `requisiteLink` in `GET /v1/orders/fields`, and on both surfaces at once — `fieldsDetailed` in `GET /v1/guide` carries it too, so the shape is visible without Bitrix24 tokens. Arrays of objects still carry no element schema. The change is additive: existing field-description keys stay in place, and create-time validation was not tightened.

### NEW-0824-16: Scrum kanban stages and sprint listing in the API

Four operations for working with the columns of a Scrum board. Stages belong to a sprint rather than to a workgroup — different sprints of one project hold independent sets of columns — so the collection is addressed through the sprint.

[GET /v1/scrum/sprints](/docs/scrum/stages) returns the sprints of a project. It is the only way to obtain the `sprintId` the other three operations need; without the `groupId` parameter it returns every sprint the key can see.

[GET /v1/scrum/sprints/:sprintId/stages](/docs/scrum/stages/list) returns the columns of a sprint, converting `id`, `sort` and `sprintId` to numbers. [POST /v1/scrum/sprints/:sprintId/stages](/docs/scrum/stages/create) creates a column and returns it re-read in full, including the defaults Bitrix24 substitutes. [PATCH /v1/scrum/stages/:stageId](/docs/scrum/stages/update) renames, recolours and reorders a column.

Platform-side validation closes the places where Bitrix24 answers with success and stores something else: a name longer than 255 characters, a colour longer than six characters and a `type` outside `NEW`, `WORK`, `FINISH` now get a clear refusal instead of a silent substitution. A colour may be sent with a leading `#`, which is stripped.

Moving a column to another sprint is not exposed: `sprintId` in the request body is rejected. Updating a stage that does not exist, or that belongs to a project the key cannot access, answers `STAGE_NOT_FOUND_OR_NO_ACCESS` — the two cases cannot be told apart, because Bitrix24 answers both identically.

### FIX-0824-17: ACCOUNT_FROZEN is now documented on server creation

The `402` response of [POST /v1/infra/servers](/docs/infra/servers/create) listed only the plan, trial and Marketplace-subscription refusals. It omitted `ACCOUNT_FROZEN`, the code the platform answers to an account whose wallet is frozen, even though the endpoint already returned it: the balance check runs ahead of the handler, and server creation is not exempt from it.

Because of the omission, a client generated from `/v1/openapi.json` treated the code as impossible and dropped a refusal that has a clear remedy — top up the balance. Endpoint behaviour is unchanged; only the description was.
