[{"data":1,"prerenderedAt":7},["ShallowReactive",2],{"docs-changelog\u002F2026-08-24":3,"docs-tabs-changelog\u002F2026-08-24":6},{"content":4,"lastmod":5},"# API changes: August 24, 2026\n\n[← Changelog](\u002Fdocs\u002Fchangelog) · [August 2026](\u002Fdocs\u002Fchangelog\u002F2026-08)\n\n### BC-0824-1: activity type can no longer be changed after creation\n\n> Old format supported until: not provided\n\n**Before**\n\n`PATCH \u002Fv1\u002Factivities\u002F: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.\n\n**After**\n\n`typeId` is declared as a field that is set only on creation. `PATCH \u002Fv1\u002Factivities\u002F:id` carrying it returns `400 READONLY_FIELD` and names the field. Both batch update operations answer the same way. `POST \u002Fv1\u002Factivities` still accepts the field, where it stays mandatory. In the `GET \u002Fv1\u002Factivities\u002Ffields` output, `typeId` now carries the `createOnly` marker.\n\n**What integrators should do**\n\nRemove `typeId` from the body of `PATCH \u002Fv1\u002Factivities\u002F: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 \u002Fv1\u002Factivities\u002Ffields` response lets you tell such fields apart before sending a request.\n\n### FIX-0824-2: paid accounts no longer receive an error asking them to pay again\n\n**Before**\n\n[POST \u002Fv1\u002Fapps](\u002Fdocs\u002Fapps\u002Fcreate) could return a `403` error asking a paid account to upgrade when application installation through Bitrix24 failed.\n\n**After**\n\nWhen 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.\n\n**Impact on integrations**\n\nRequests require no changes. The technical error can be retried, while the plan error requires an upgrade.\n\n### BC-0824-3: the deployment block changes shape for Belarusian accounts along with their access model\n\n> Old format supported until: not provided\n\n**Before**\n\nAn account licensed in Belarus landed in the limited-access bucket under three conditions at\nonce: it held a demo subscription, it held no paid subscription, and it had no history of\ncommercial payments. Its Bitrix24 plan — paid or free — did not affect membership, whereas an\naccount that had ever paid before did not land in the bucket at all. In\n[`GET \u002Fv1\u002Fme`](\u002Fdocs\u002Fkeys-auth\u002Fme) such an account received a `deployment` block with no\n`galaxyApp` sub-block, with `primary` = `standalone` and with a `placementNote` field\nexplaining that no galaxy host of its own is created for it and that an app must be deployed\nin two steps. A one-shot create carrying `source` answered\n`400 SOURCE_AT_CREATE_GALAXY_ONLY`.\n\n**After**\n\nThe plan-based model has no limited-access bucket at all, so a Belarusian account leaves it in\nboth directions at once: on a paid or demo Bitrix24 plan it gets full access, on a free plan it\nis denied. In both cases the `deployment` block changes shape the same way — provided galaxy\nplacement is open to the account and it does not yet have a galaxy of its own (both carve-outs\nare named below): the\n`deployment.galaxyApp` sub-block appears, the `deployment.placementNote` field disappears, and\n`deployment.primary` switches from `standalone` to `galaxyApp`. For an account with full\naccess a one-shot create carrying `source` starts working.\n\n**What integrators should do**\n\nDetect the placement model by the PRESENCE of the `deployment.galaxyApp` sub-block, exactly as\nthe response reference prescribes. Rewrite any branch keyed on the presence of `placementNote`\nor on the value of `primary`: both fields move with the account's access model, not only with\nits plan. Read the permission to create a server separately, from\n`capabilities.servers.create`: the `deployment` block describes the placement CONTRACT and is\npresent for a denied account too, while\n[`POST \u002Fv1\u002Finfra\u002Fservers`](\u002Fdocs\u002Finfra\u002Fservers\u002Fcreate) answers such an account with `402`.\nTwo carve-outs where the response shape does not change at all. The first is an account with\ngalaxy placement switched off: neither field is present before or after. The second is an\naccount that already has a galaxy: `placementNote` explained the absence of a galaxy of its\nown, so the owner of a live galaxy host received `galaxyApp` and no `placementNote` while in\nthe bucket too. The change reaches an account at the moment it is moved onto the plan-based\nmodel, so both response shapes occur side by side across accounts.\n\n### NEW-0824-4: the Bitrix24 plan becomes the access condition for accounts licensed in Belarus\n\nVibecode admits an account to the infrastructure either by its Bitrix24 plan or by a\nsubscription, depending on the licence region the account belongs to. Accounts licensed in\nBelarus — served by a separate Vibecode deployment, not by this one — move onto the\nplan-based model: a paid or a demo Bitrix24 plan grants access there, and an account with\nneither is declined. The move is staged, account by account.\n\nNothing changes on this deployment and no action is required. Access here has always been\ngranted by the Bitrix24 plan alone: a commercial plan grants full access, a demo plan grants\na limited trial, and on a free plan [`POST \u002Fv1\u002Finfra\u002Fservers`](\u002Fdocs\u002Finfra\u002Fservers\u002Fcreate) —\nlike an app publish, a wake of a sleeping machine or the issuance of a new key — is still\ndeclined with `402` and `INT_TARIFF_REQUIRED`, which [`GET \u002Fv1\u002Fme`](\u002Fdocs\u002Fkeys-auth\u002Fme) also\nreports in `capabilities.servers.create.reason`. No new field, no new denial code and no new\nbranch appear in the contract you consume here.\n\n### FIX-0824-5: the server-creation hint in the key response no longer leads nowhere\n\n**Before**\n\nAn account whose access is granted by a Bitrix24 plan rather than a subscription received a\n`capabilities.servers.create` slot in [`GET \u002Fv1\u002Fme`](\u002Fdocs\u002Fkeys-auth\u002Fme) carrying a generic\nwording: servers are available on commercial plans or during an active trial. That was wrong\ntwice over. Such an account is not entitled to the trial — the entitlement is computed on the\nsubscription model — and the address where a plan is chosen was not named at all. Separately,\nfor accounts licensed in Belarus the `alternatives[].url` field pointed at the subscription\ncheckout inside the account itself, and would have kept pointing there after the account moved\nonto the plan-based model, where a subscription no longer resolves the denial.\n\n**After**\n\nThe slot names the working paths and the address: a paid or demo Bitrix24 plan, and for\nBelarus a paid subscription as well. The text in `capabilities.servers.create.userMessage`\nnow matches the `402` body that [`POST \u002Fv1\u002Finfra\u002Fservers`](\u002Fdocs\u002Finfra\u002Fservers\u002Fcreate)\nreturns for the same account — one denial code no longer says different things on two\nsurfaces. For accounts licensed in Belarus that have moved onto the plan-based model,\n`alternatives[].url` points at the plan-selection page instead of the subscription checkout.\n\n**Impact on integrators**\n\nNo action required: a text field and a URL changed value, the response structure is unchanged.\nThe fix reaches Kazakhstan and Uzbekistan at once, and Belarus as each account is moved onto\nthe plan-based model. If you render your own copy instead of `userMessage`, review it: the\npromise of a trial is wrong for these accounts.\n\n### FIX-0824-6: the denial text for Kazakhstan and Uzbekistan no longer offers a subscription\n\n**Before**\n\nOn the deployment that serves Kazakhstan and Uzbekistan an account on a free plan was\nrefused with the subscription-model text and was asked to activate a subscription that is\nnot sold in those countries. The action named in the text could not be performed, and the\nworking paths to access — a paid or a demo Bitrix24 plan — were not named at all, nor was\nthe address where a plan is chosen.\n\n**After**\n\nSuch an account is now refused with the plan-based code of its own region, and the text\nnames both working paths and the address. The subscription brand is gone from it. The\ncorrection reaches every surface where an access denial is visible to the client: server\ncreation ([`POST \u002Fv1\u002Finfra\u002Fservers`](\u002Fdocs\u002Finfra\u002Fservers\u002Fcreate)), an app publish, a wake of\na sleeping machine and the issuance of a new key, as well as\n`capabilities.servers.create.reason` in [`GET \u002Fv1\u002Fme`](\u002Fdocs\u002Fkeys-auth\u002Fme).\n\nNothing changes on this deployment and no action is required here. Access on this surface is\ngranted by the Bitrix24 plan alone, a free-plan denial is still answered with `402` and\n`INT_TARIFF_REQUIRED`, and neither the request nor the shape of the response changes. The\nregional denial codes corrected above are reachable only on the deployment named there.\n\n### BC-0824-7: bot re-authorization is now explicit and safe\n\n> Old format supported until: not provided\n\n**Before**\n\n`POST \u002Fv1\u002Fbots\u002F:botId\u002Freauth` could clear any disabled bot state, while `410 BOT_DISABLED` did not tell clients whether automatic recovery was allowed.\n\n**After**\n\n`410 BOT_DISABLED` includes boolean `error.details.reauthAllowed`. Call `POST \u002Fv1\u002Fbots\u002F:botId\u002Freauth` 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.\n\n### FIX-0824-8: galaxy application deploy warns when environment variables are reset\n\n**Before**\n\nA successful `\u002Fdeploy` without user `env` recreated the galaxy application without previous variables but did not report that in the response.\n\n**After**\n\nThe 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.\n\n**Impact**\n\nThe deploy status and behaviour are unchanged; clients should read the existing `warnings[]` array.\n\n### NEW-0824-9: task dependencies are now available through the API\n\n**Before**\n\nThe 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.\n\n**After**\n\nTwo read-only endpoints were added. `GET \u002Fv1\u002Ftasks\u002F:taskId\u002Fdependencies` returns the dependencies of one task as an array of id-and-title pairs, sorted by id. `POST \u002Fv1\u002Ftasks\u002Fdependencies\u002Fbulk` takes up to 50 tasks and answers per task: successes in `results`, failures in `errors`, counters in `meta`.\n\nThe 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\".\n\n**Boundaries, stated explicitly**\n\nOnly 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.\n\nLinks 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.\n\nA 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.\n\n**Impact on integrators**\n\nThere 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.\n\n### FIX-0824-10: international bot access keeps the Bitrix24 plan model\n\n**Before**\n\nThe international instance already governed account access through the Bitrix24\nplan model. Bot permission failures returned `403 BITRIX_ACCESS_DENIED`.\n\n**After**\n\nThere is no change to that `.com` contract: bot access stays on the international\nplan model. `GET \u002Fv1\u002Fme?refresh=tariff` continues to refresh the account's\nBitrix24 plan state after an upgrade.\n\n**What integrators should do**\n\nKeep handling international access through the existing plan errors. No new bot\nerror branch is required on `.com`.\n\n### BC-0824-11: opening a workday no longer confirms an expired state\n\n> Old format supported until: not provided\n\n**Before**\n\n`POST \u002Fv1\u002Fworkday\u002Fopen` returned `200 success:true` when Bitrix24 left the\nworkday in the `EXPIRED` status. No new workday was opened.\n\n**After**\n\nAn unchanged `EXPIRED` status is returned as HTTP 409 with `success:false` and\nthe `WORKDAY_EXPIRED` code. The instructions say to read status for the same\nuser, close the expired day using its `timeStart` date and a report, and then\nretry open.\n\n**What integrators should do**\n\nHandle `success:false` and HTTP 409 as an explicit signal that the workday was\nnot opened; resolve the previous day's state using the response hint first.\n\n### NEW-0824-12: calendar events can be linked to CRM elements\n\nA 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 \u002Fv1\u002Fcalendar-events\u002Ffields](\u002Fdocs\u002Fentities\u002Fcalendar-events\u002Ffields), and is available in `select`.\n\nThe value is an array of typed references: `D_\u003Cid>` deal, `C_\u003Cid>` contact, `L_\u003Cid>` lead, `CO_\u003Cid>` 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 \u002Fv1\u002Fbatch` that is `INVALID_PARAMS` in `data.errors` under the call's `id`; on `POST \u002Fv1\u002Fcalendar-events\u002Fbatch` 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.\n\n**Affected endpoints:** [GET \u002Fv1\u002Fcalendar-events](\u002Fdocs\u002Fentities\u002Fcalendar-events\u002Flist), [GET \u002Fv1\u002Fcalendar-events\u002F:id](\u002Fdocs\u002Fentities\u002Fcalendar-events\u002Fget), [POST \u002Fv1\u002Fcalendar-events\u002Fsearch](\u002Fdocs\u002Fentities\u002Fcalendar-events\u002Fsearch), [POST \u002Fv1\u002Fcalendar-events](\u002Fdocs\u002Fentities\u002Fcalendar-events\u002Fcreate), [PATCH \u002Fv1\u002Fcalendar-events\u002F:id](\u002Fdocs\u002Fentities\u002Fcalendar-events\u002Fupdate), [GET \u002Fv1\u002Fcalendar-events\u002Ffields](\u002Fdocs\u002Fentities\u002Fcalendar-events\u002Ffields).\n\n### FIX-0824-13: an application on a galaxy host that does not boot can be deleted without a live tunnel\n\n**Before**\n\n`DELETE \u002Fv1\u002Finfra\u002Fservers\u002F{id}` on a galaxy application answered `502` with the code\n`GALAXY_HOST_UNREACHABLE` whenever the host was offline, whatever the reason. When the host guest\noperating system does not boot at all (the `provisionErrorCode` field of the server record equals\n`GUEST_NOT_BOOTING`), the tunnel will never come back, so retrying helped neither a minute later\nnor a day later. Deleting the host itself was blocked too: it answered `409` with the code\n`GALAXY_HAS_APPS`, because its applications formally remained alive. The owner ended up in a closed\nloop, still holding a quota slot with a machine that no longer runs.\n\n**After**\n\nOnce the platform has proven that the host guest operating system does not boot, an application on\nthat host is deleted without contacting the host: `DELETE \u002Fv1\u002Finfra\u002Fservers\u002F{id}` answers `200`, the\napplication record is closed, and its access tokens, domain and catalog item are released. After\ndeleting the applications one by one, the owner deletes the host itself with the regular call — the\n`GALAXY_HAS_APPS` refusal no longer appears. The `GALAXY_HOST_UNREACHABLE` code keeps its previous\nmeaning for every other case: the host is temporarily offline and retrying makes sense.\n**Important:** the does-not-boot mark alone does not guarantee the `200`: before deleting without\ncontacting the host, the platform also confirms through the gateway that no live tunnel\nexists. That check is fail-safe — an unreachable gateway, an answer without a connection\nlist, or a host that came back meanwhile all keep the answer at `502`. Clients need\nno changes — the retry loop for this state simply stops being necessary.\n\n### BC-0824-14: an unknown select field name is refused with 400 on almost every entity\n\n> Old format supported until: 18.02.2027\n\n> 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.\n\n**Before**\n\nA field name the entity does not have went into the selection silently. The request ran, the\nfield was absent from the records, and the explanation sat in `meta.warnings` — where nobody\nlooks. A typo in `select` therefore looked like a successful request with mysteriously\nincomplete records:\n\n```\nGET \u002Fv1\u002Fdeals?select=id,titel      →  200, records carry only id\n```\n\nOnly [calendar events](\u002Fdocs\u002Fentities\u002Fcalendar-events\u002Flist) answered such a name with an error.\n\n**After**\n\nThe request is refused before the Bitrix24 call — `400` with the `UNKNOWN_SELECT_FIELD` code\nand the list of accepted names in the message. That list is the precise answer to \"what may I\nask for\".\n\nIt applies to the entities whose field set has been verified against Bitrix24: deals, contacts,\ncompanies, leads, quotes, activities, addresses, smart processes, products and product sections,\ncatalogs with their products and sections, orders and order statuses, statuses, currencies,\ncalendar sections, files, folders, storages, departments, workgroups, document\ntemplates. Everywhere else the behaviour is unchanged — a warning in `meta.warnings`.\n\nA separate class is a name the entity DOES have but never returns: `GET \u002Fv1\u002F{entity}\u002Ffields`\nshows such a field with `notReturned: true`. In this cohort that is, for example, `currencyId`\non products and `sort` on product sections. It is refused with a `400` too, but under its own\n`SELECT_FIELD_NOT_RETURNED` code and a message that names the reason. The separate code is\ndeliberate: `UNKNOWN_SELECT_FIELD` claims the name does not exist, while the entity's own field\ncatalogue publishes it — a client that honestly took the name from there would otherwise read\nthe answer as \"the catalogue is lying\".\n\nOnly the name is checked. Custom fields (`UF_*`, `ufCrm*`) are accepted as before on every\nentity; product properties are each accepted on THEIR OWN entity: `PROPERTY_295` on products,\n`property295` on catalog products, where their numbers are assigned by Bitrix24; the other\nspelling is not understood by the method and the gate rejects it. A `*` (or `UF_*`) value still\nmeans \"return every field\", and a typo next to it causes no refusal — a warning arrives instead.\nIn both batch calls — the global one and the per-entity one — the selection refuses only its own\nsub-call while neighbouring ones still run.\n\n**What integrators should do**\n\nCheck the field names in your `select` against the list in the error message or against the\n`GET \u002Fv1\u002F{entity}\u002Ffields` schema. A request that used to \"work\" but returned records missing\nsome of the requested fields will now answer `400` naming exactly which name was not found —\nwhich was its original mistake.\n\n### FIX-0824-15: the `datePeriod` field schema is now visible in `GET \u002Fv1\u002Fbookings\u002Ffields`\n\n**Before**\n\nThe `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.\n\n**After**\n\nFields 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 \u002Fv1\u002Forders\u002Ffields`, and on both surfaces at once — `fieldsDetailed` in `GET \u002Fv1\u002Fguide` 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.\n\n### NEW-0824-16: Scrum kanban stages and sprint listing in the API\n\nFour 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.\n\n[GET \u002Fv1\u002Fscrum\u002Fsprints](\u002Fdocs\u002Fscrum\u002Fstages) 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.\n\n[GET \u002Fv1\u002Fscrum\u002Fsprints\u002F:sprintId\u002Fstages](\u002Fdocs\u002Fscrum\u002Fstages\u002Flist) returns the columns of a sprint, converting `id`, `sort` and `sprintId` to numbers. [POST \u002Fv1\u002Fscrum\u002Fsprints\u002F:sprintId\u002Fstages](\u002Fdocs\u002Fscrum\u002Fstages\u002Fcreate) creates a column and returns it re-read in full, including the defaults Bitrix24 substitutes. [PATCH \u002Fv1\u002Fscrum\u002Fstages\u002F:stageId](\u002Fdocs\u002Fscrum\u002Fstages\u002Fupdate) renames, recolours and reorders a column.\n\nPlatform-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.\n\nMoving 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.\n\n### FIX-0824-17: ACCOUNT_FROZEN is now documented on server creation\n\nThe `402` response of [POST \u002Fv1\u002Finfra\u002Fservers](\u002Fdocs\u002Finfra\u002Fservers\u002Fcreate) 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.\n\nBecause of the omission, a client generated from `\u002Fv1\u002Fopenapi.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.\n",null,{},1794739476295]