[{"data":1,"prerenderedAt":7},["ShallowReactive",2],{"docs-changelog\u002F2026-08-23":3,"docs-tabs-changelog\u002F2026-08-23":6},{"content":4,"lastmod":5},"# API changes: August 23, 2026\n\n[← Changelog](\u002Fdocs\u002Fchangelog) · [August 2026](\u002Fdocs\u002Fchangelog\u002F2026-08)\n\n### BC-0823-1: OpenAPI no longer offers create-only fields in PATCH\n\n> Old format supported until: not provided\n\n**Before**\n\nFields accepted by the API only when creating a record appeared in `GET \u002Fv1\u002Fopenapi.json` as ordinary PATCH body properties. A client generated from that schema could send them on update and receive `400 READONLY_FIELD`.\n\n**After**\n\nFor entities with create-only fields, PATCH uses a separate input schema without those fields. Other entities keep using their existing PATCH input schema. In both cases, the POST input schema preserves the create contract.\n\n**What integrators should do**\n\nRegenerate the SDK from the new OpenAPI schema and use the type referenced by each PATCH `requestBody`. Affected entities use `UpdateInput`; other entities keep `Input`. Remove fields allowed only during creation from update payloads; POST continues to use `Input`.\n\n### NEW-0823-2: several employees can work on one application's code\n\nA server owner can now assemble a development team: employees of the account work with the server\nusing their own personal keys, with no key handover and no server rebinding. The Developer\nrole gets deploy, exec, upload, logs and the source depot; the Admin role additionally manages\nthe machine: lifecycle (stop, start, reboot, sleep schedule, repair), settings and security,\nplan and disk, backups, the custom domain, the catalog card, the application audience and the\ncosts. Team membership, server deletion, access links and key rebinding stay with the owner.\nTeam membership is edited by the owner or a Bitrix24 account administrator on the Collaboration tab.\n\nAccess comes from membership, not from the key, so removing somebody from the team closes\ntheir access immediately.\n\nA team member's deploy differs from the owner's in three ways. Environment variables are\npreserved: the `env` field of their request is not applied (the response carries a warning),\nand the variables already set on the application survive the deploy — including galaxy\napplications, where every deploy used to wipe them. The Bitrix24 catalog card and the release\nannouncement stay with the owner: `displayName`, `description` and the `changelog`\nannouncement sent by a Developer are ignored with a warning, while the version note itself is\nstill stored in the source depot.\n\nThere is also an overwrite guard: the `baseVersionId` field in the body of\n[POST \u002Fv1\u002Finfra\u002Fservers\u002F:id\u002Fdeploy](\u002Fdocs\u002Finfra\u002Fdeploy\u002Fdeploy) (\"this is the source version I\nbased my work on\", e.g. `v12`). If a newer version has appeared in the depot, the deploy is\nrefused with `SOURCE_VERSION_STALE`, carrying the current version number and a download link —\ninstead of silently overwriting.\n\nThe declared version is checked for existence: a number ahead of the depot is refused with\n`BASE_VERSION_NOT_FOUND` and the current version number — otherwise any non-existent number\nwould switch the guard off.\n\nOn a server whose owner has assembled a development team the field is required as soon as the\ndepot holds any version: a deploy without it answers `BASE_VERSION_REQUIRED` and names the\ncurrent version. A blind deploy over a colleague's changes is therefore refused even when\nnobody knew about the guard. On a server without a team the field stays optional and a deploy\nwithout it behaves exactly as before. So that the version number has somewhere to come from,\nthe version-download response now carries a `versionId` field next to the link — see\n[Source code storage](\u002Fdocs\u002Fsource-storage).\n\nA `409 EXEC_BUSY` refusal now names whoever is holding the server: `error.hint.holder` carries\nthe employee name, the kind of operation and when it started, and `error.hint.reason` begins with\nthat name. A background platform operation has no human behind it, so `holder.name` comes back\nempty there. The field is additive — the existing fields of the refusal are unchanged.\n\nA team member now sees the server in the API instead of working with it blind.\n[GET \u002Fv1\u002Finfra\u002Fservers](\u002Fdocs\u002Finfra\u002Fservers) also returns the servers whose development team\nthe caller belongs to: those rows carry an `access` block with `via: \"collaborator\"`, the\nrole, the allowed actions and the endpoints open to them, while the key's own rows carry\n`access.via: \"owner\"`. `GET \u002Fv1\u002Finfra\u002Fservers\u002F:id` answers a member with `200` and a reduced\ncard (no IP, no SSH access, no managing key; costs and the sleep threshold follow the role)\ninstead of the former `404`. `GET \u002Fv1\u002Fme` lists the memberships in `infra.collaboratorServers`.\nWaking the machine, [POST \u002Fv1\u002Finfra\u002Fservers\u002F:id\u002Fwake](\u002Fdocs\u002Finfra\u002Flifecycle\u002Fwake), is open to\nthe Developer role as well — the matrix promised it before, but the call answered `404`.\nSearching for an employee to configure the audience,\n[GET \u002Fv1\u002Finfra\u002Fservers\u002F:id\u002Fb24-users](\u002Fdocs\u002Finfra\u002Faccess\u002Fb24-users), is open to the Admin role —\nit used to answer a refusal even though that same role already configures the audience itself.\n\nAdditionally: a team admin can now perform, via their own personal API key, every server\noperation their role allows — lifecycle control (stop, start, reboot, sleep, manual repair,\nwake schedules, metrics), settings (SSH access, port, Bitrix24 event subscriptions, switching the\n`BLACKHOLE`\u002F`OPEN` mode via [PATCH \u002Fv1\u002Finfra\u002Fservers\u002F:id\u002Fmode](\u002Fdocs\u002Finfra\u002Faccess\u002Fmode)), the\ncatalog card ([PATCH \u002Fv1\u002Finfra\u002Fservers\u002F:id](\u002Fdocs\u002Finfra\u002Fservers\u002Fupdate) — name and description),\nand access audience (access policy, user\u002Fdepartment access list). Previously these operations returned `403`\u002F`404` via a\nmember's V1 key regardless of role — they only worked from the Vibecode dashboard. V1 membership\nlists can now return a page: `GET \u002Fv1\u002Finfra\u002Fservers` accepts optional `page` and `limit`\nand returns a true `total` alongside. Without the parameters the response is unchanged and\ncomplete — the contract stays as published. In `\u002Fv1\u002Fme` the `infra.collaboratorServers`\nblock gained a `total` field.\n\nDeleting source versions stays with the owner: `DELETE \u002Fv1\u002Finfra\u002Fservers\u002F:id\u002Fsources\u002F:versionId`\nand the bulk `POST \u002Fv1\u002Finfra\u002Fservers\u002F:id\u002Fsources\u002Fcleanup` answer a team member of any role with\n`403 NOT_AUTHORIZED`. Listing, downloading, depositing and tagging remain open to them.\n\nA member's deploy that must preserve the environment refuses to run when the environment cannot\nbe read: instead of silently deploying with an empty environment it answers\n`502 GALAXY_PRESERVED_ENV_UNREADABLE` with a `retryable` marker. The application keeps running\nits previous version.\n\nA role refusal is now distinct from \"no such server\". A management operation not covered by\nthe member's role answers `403 SERVER_ROLE_FORBIDDEN`; `error.hint` carries their role, the\nrole required, the denied action and the endpoints that are open to them. For an unrelated\nkey the existence of the server stays hidden — it still gets a `404`.\n\nAn app whose owner has been deleted survives only while its team still has an admin — someone\nwho can take it over. A team of developers alone does not hold the app: nobody can manage it,\nso it is cleaned up like any other ownerless app.\n\nThe `appUrl` field in [GET \u002Fv1\u002Finfra\u002Fservers](\u002Fdocs\u002Finfra\u002Fservers), `GET \u002Fv1\u002Finfra\u002Fservers\u002F:id`\nand `GET \u002Fv1\u002Fme` (the `infra.collaboratorServers` block) no longer promises a team member a\nlink they are not allowed to open. Previously the field came back non-empty as soon as the\nserver had a subdomain, regardless of whether the application's audience actually let that\nparticular person open it — following such a link answered with a refusal. Now `appUrl` is\nempty whenever the audience (`accessPolicy`) does not open the application to every account\nemployee and the member has no personal access grant. There is one exception: a member whose\naccess comes through a department grant does not see the link yet even though they could open\nthe application — for now the server's owner or team admin has to hand it to them directly.\n\n### FIX-0823-3: OAuth metadata and the welcome page point at the platform public URLs\n\n**Before**\n\nOAuth metadata (`GET \u002F.well-known\u002Foauth-authorization-server`) could advertise `http:\u002F\u002Flocalhost:3000` in `issuer` and the endpoint URLs — an address no client can reach.\n\nThe \"Documentation\" \u002F \"Home\" buttons of the welcome page at `GET \u002Fv1\u002Fme` could lead to a dashboard other than the one the page was opened from.\n\n**After**\n\nOAuth metadata advertises the platform public domain.\n\nThe welcome page buttons lead to the dashboard of the platform the page was opened from.\n",null,{},1794739476185]