# API changes: October 19, 2026

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

### BC-1019-1: Adding storage access requires a personal key

> Old format supported until: not provided

**Before**

Editing `scopes` could add `vibe:storage` to an application key or a key of unknown origin, granting access to the owner's files.

**After**

Manually adding storage through `PATCH /v1/keys/:id`, a management key or MCP returns `403 KEY_STORAGE_SCOPE_REQUIRES_PERSONAL_KEY`. The same restriction applies when editing paired-key permissions through `PATCH /v1/apps/:id`. Existing storage access may be retained unchanged or removed; renaming and other edits remain available. A concurrent operation may return `409 KEY_OPERATION_IN_PROGRESS`.

For `POST /v1/keys` and `POST /v1/apps`, an application key or a key of unknown origin does not grant storage by default; explicitly requesting it returns the same 403 before creating the key or application. OAuth issuance for partner applications continues to return `400 CONNECT_STORAGE_SCOPE_UNAVAILABLE`. System-issued Cowork keys and their replacements retain storage access; previously removed access is not restored. Partner application keys do not receive storage during replacement.

**What integrators should do**

Create a new personal key with storage access. On `409 KEY_OPERATION_IN_PROGRESS`, reload the key or application and retry using its current scopes.

### FIX-1019-2: Connect revokes the presented Cowork device key

**Before**

`POST /v1/connect/revoke` with `client_id=cowork-desktop` and a key issued to that client returned HTTP 200 but left the key active.

**After**

The `POST /v1/connect/revoke` response remains HTTP 200. The presented device key is revoked and subsequent requests using it are rejected. Keys for other devices stay active. Unknown, foreign and already revoked tokens still return HTTP 200 without disclosing key state. `DELETE /v1/cowork/key` also remains available for revoking the device's own key.

**Impact on integrators**

The existing revocation request now disconnects the presented device; signing in again is required to continue using it. Request and response formats are unchanged.

### FIX-1019-3: deployments recognise links to platform storage

When creating an application or deploying through `source.url`, platform bucket links are recognised both with a dedicated bucket hostname and with the bucket name in the path. The source version is linked to the deployment in both forms. When link deployments on shared servers are available to your account, links to other buckets are rejected: save the archive as a source version first and use `source.versionId`.

### NEW-1019-4: Explicit early refusal on repeated JSON

[POST /v1/chat/completions](/docs/ai/chat/completions) accepts `repetition_guard: "off" | "abort"`. Omitting the option or sending `"off"` preserves existing behavior. Explicit `"abort"` stops a request when a heuristic detects repeated JSON before generation ends. It requires `response_format` of type `json_object` or `json_schema`, no declared tools and a streaming-capable model even for a synchronous response. Incompatible requests receive `400 invalid_request` before inference. Detection returns `422 reasoning_repetition` to a synchronous client, or one `error` event and one `data: [DONE]` to a streaming client with HTTP `200`. Discard partial content. Legitimate repetitive arrays can cause false refusals, so leave the option off for them. See the [JSON response documentation](/docs/ai/chat/json) for conditions and the SDK example.

### FIX-1019-5: a server start from error that never becomes ready returns the server to error

**Before**

[POST /v1/infra/servers/{id}/start](/docs/infra/lifecycle/start) moved a server in `error` to `provisioning`. If the machine never came up, the server ended in `sleeping` once the wait expired, the error reason disappeared from the response, and charges for the sleeping server resumed.

**After**

A start from `error` that never completes returns the server to `error` with its previous reason, and charges do not resume. A start from `sleeping` still returns the server to `sleeping` once the wait expires.

**Impact on integrators**

No action required. After a failed start of a server in `error`, polling [GET /v1/infra/servers/{id}](/docs/infra/servers/get) shows `error` instead of `sleeping`.

### NEW-1019-6: graduating a galaxy application to a dedicated server keeps its custom domain

Creating a dedicated server in place of a galaxy application — [POST /v1/infra/servers](/docs/infra/servers/create) with `placement: "dedicated"` and `graduateFrom` — keeps the application's custom domain: the name moves to the created server together with its verification, the DNS and TXT records stay as they are, and the domain does not have to be attached again.

The `201` response of that call gained an optional top-level `warningCodes` field — machine-readable codes for the `warnings` lines, so a client can branch without parsing prose. The field is present only when there is something to report, and the set is open-ended: tolerate a code you do not know instead of treating it as an error.

The first such code is `GRADUATION_DOMAIN_REGISTRY_PENDING`: the domain already belongs to the new server but does not open yet. The neighbouring `warnings` line names the domain and the single call that finishes the job — `POST /v1/infra/servers/{id}/domain/verify` on the new server. The DNS records need no changes.

Custom application domains are available only to Bitrix24 accounts in the pilot programme for now, so everything above applies to them alone. Elsewhere a galaxy application has no custom domain, and the response of this call does not change.

### NEW-1019-7: Recover a bot registration after a response without an ID

For `POST /v1/bots` registrations in `webhook` mode, the Vibecode API now confirms the saved URL write from the Bitrix24 acknowledgement and returns `data.botId` when the other bot properties are verified. If an earlier registration remains pending, call `POST /v1/bots/registrations/:code/recover` with the same key and code. Success returns `data.botId`; the action checks the existing bot and does not register another one. For a `409`, retry after `Retry-After` or contact support if verification does not finish.

### NEW-1019-8: links to new Open Channel pages in `GET /v1/guide`

The `openLines.docs` object in the `GET /v1/guide` response gains seven new links: `crmMembersCreate`, `crmMembersDelete`, `crmMessages`, `crmLead`, `sessionsSearch`, `sessionsIntercept` and `sessionsJoin`. They point to separate method pages: add and remove a CRM chat employee, send a message to the client, create a lead from an inquiry, search sessions, intercept a dialog and join a dialog. The existing `openLines.docs` keys stay in place, and the response remains HTTP 200.

### FIX-1019-9: Server reuse hint explains how to create a second application

**Before**

When reusing a server, the [POST /v1/infra/servers](/docs/infra/servers/create) response identified the already bound server but did not explain how to create a second application.

**After**

The `hint` field explains: for a second application, create a separate application card with its own API key and use that key for the new application.

**Impact on integrators**

Existing requests need no changes. The server reuse rule and response fields are preserved.

### NEW-1019-10: navigation URLs in the Cowork connector list

For Cowork, `GET /v1/connectors` returns `manageUrl` to manage connections, `addUrl` for the catalog, and `addOwnUrl: null`; use `addUrl` when the value is `null`. The card URL in `items[].webUrl` changes to `/extensions/connectors/<slug>`. URLs are absolute and open in the system browser. Responses for Application keys are unchanged.

### FIX-1019-11: first Node.js 20 deploy on a new server no longer waits for system updates

**Before**

[POST /v1/infra/servers/:id/deploy](/docs/infra/deploy/deploy) with a `runtime` from the `node20` family installed the `unzip` package on the server. On a freshly created server the operating system was running background updates at that moment, and the deploy ended with `RUNTIME_PREREQUISITES_LOCK_TIMEOUT` or `RUNTIME_PREREQUISITES_TIMEOUT`. The same wait happened before a `.zip` was extracted in a deploy and in [POST /v1/infra/servers/:id/upload](/docs/infra/deploy/upload).

**After**

The `node20` runtime no longer requires `unzip`: the server agent extracts `.zip` archives itself. On a server with a current agent, deploys and `.zip` uploads neither install `unzip` nor wait for background updates. The `UNZIP_PREFLIGHT_FAILED` code and the `EXEC_BUSY` tied to that step remain only for servers with an older agent.

**Impact on integrators**

Retrying a deploy on a new server is no longer needed. No request changes are required.
