# API changes: October 13, 2026

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

### BC-1013-1: App address outside the platform: https only, not with an app or server key

> Old format supported until: not provided

**Before**

[POST /v1/apps](/docs/apps/create), [PATCH /v1/apps/{id}](/docs/apps/update) and [POST /v1/apps/{id}/publish](/docs/apps/publish) accepted any `http://` or `https://` address in `appUrl`. Any key allowed to change the app could publish it with an address outside the platform.

**After**

An address outside the platform must be a public `https://` address, otherwise the response is `400 APP_URL_UNSAFE`. An app can be published with an address not served by a live server of this account on the platform (an external host or a domain whose server is gone), or a published app switched to such an address, from the Vibecode dashboard or with a personal key. An app key, a [Connect partner](/docs/partner-connect) key, a server-linked key, a Cowork key, a key with a purpose, a management key and the working key of an agent or managed bot get `403 EXTERNAL_URL_ACTOR_NOT_ALLOWED`. When the capability is unavailable for the account, the response is `403 EXTERNAL_URL_DISABLED`. A concurrent change of the address or status gives `409 APP_URL_CONFLICT`. Edits that change neither the address nor the status, and address changes of an unpublished app, are not subject to the key check.

**What integrators should do**

Move app addresses outside the platform to `https://`. Publish such apps from the Vibecode dashboard or with a personal key. On `409 APP_URL_CONFLICT`, re-read the app and retry.

### FIX-1013-2: rotating a revoked API key is refused before a new key is created

**Before**

[POST /v1/keys/:id/rotate](/docs/management-keys) on a revoked API key (`vibe_api_`) started issuing a new key and ended with `500 KEY_ROTATION_FINALIZE_FAILED`. The new key stayed created, and rotating or deleting either key returned `409 KEY_ROTATION_RECOVERY_REQUIRED` until the new key was deleted.

**After**

Rotating a revoked API key returns `409 KEY_NOT_ACTIVE` right away. No new key is created and the original key is not changed. Rotating an active or blocked key works as before.

**Impact on integrators**

No changes are needed. The `409 KEY_NOT_ACTIVE` refusal is already documented for this method, and there is no extra key to delete after such an attempt.

### NEW-1013-4: appUserSignIn.setup slot in the /v1/me response

`data.capabilities` in the `GET /v1/me` response gains the `appUserSignIn` group with the `setup` slot — whether the key owner can use the setup of end-user sign-in for an app through the platform SDK. While the feature is not enabled, the slot comes back with `available: false` and `reason: "FEATURE_DISABLED"`. The other response fields do not change.

### NEW-1013-5: Server repair reports that the platform has no channel to the machine

When the platform cannot reinstall the agent on a server, repair now names the reason with the machine code `REPAIR_NO_TRANSPORT`. When the refusal is known up front, [POST /v1/infra/servers/{id}/repair](/docs/infra/lifecycle/repair) answers `422`: recreate such a server or restore it from a backup if one exists. When the platform could not get onto the server during the repair itself, [GET /v1/infra/servers/{id}/repair-status](/docs/infra/lifecycle/repair-status) returns `status: "failed"` and the `data.error` text starts with `REPAIR_NO_TRANSPORT:`. Retry the repair later, and contact support if the refusal persists. After such a refusal the repair does not put a server it woke back to sleep: the server stays on until its idle-sleep setting stops it or you put it to sleep yourself. Other repair failures carry their own error text. Existing requests keep working as before.

### NEW-1013-6: Application database copies

Galaxy applications now have SQLite copy history and manual database file copies:
`GET /v1/infra/servers/:id/db/backups` and `POST /v1/infra/servers/:id/db/backups`.
A manual request returns `202 QUEUED`; completion appears in history. Database info
shows backup capability and the latest completed copy of the default file.
Read-only keys can list copies; creating one requires write access.
[Create database copies](/docs/infra/database).

### NEW-1013-7: Long-running commands with durable results

Long-running commands: [`POST /v1/infra/servers/:id/exec?async=true`](/docs/infra/deploy/exec) returns `202` and `operationId`. A dropped wait does not lose the command result. Read the outcome and retained stdout/stderr through the existing [`GET /v1/infra/operations/:operationId`](/docs/infra/deploy/operation-status). Durable mode is available only on `STANDALONE`, with timeout up to 86400 seconds. Other server kinds, including `GALAXY_APP`, receive `400 DURABLE_EXEC_UNSUPPORTED_SERVER_KIND` without execution or synchronous fallback. Synchronous execution on Galaxy and standalone servers retains its 600-second limit.

### NEW-1013-8: Starting a sleeping server reports that no free capacity is available yet

When there is temporarily no free capacity to start a sleeping server that has its own machine (any kind except `GALAXY_APP`), [POST /v1/infra/servers/{id}/wake](/docs/infra/lifecycle/wake) with `wait=true` answers `503` with the code `WAKE_NO_CAPACITY`. A deploy that wakes such a sleeping server ends the same way, and so does [POST /v1/infra/servers/{id}/start](/docs/infra/lifecycle/start) for such a server in the `error` status. Calls that do not wait, that is `/wake` without `wait=true` and `/start` for a sleeping server, answer as before, and the server soon returns to the `sleeping` status with `WAKE_NO_CAPACITY` in the `provisionErrorCode` field of the [GET /v1/infra/servers/{id}](/docs/infra/servers/get) response. The server data is kept. Automatic start attempts for that server pause for ten minutes, and during that time `/wake` answers `503 WAKE_NO_CAPACITY` at once. A server of kind `GALAXY_APP` runs on a shared machine, and only that machine's pause applies to it: until the pause ends, `/wake` and `/start` of the app answer `503 WAKE_NO_CAPACITY` at once. The app's other answers and fields do not change. Retry the request later. Existing requests keep working as before.

### BC-1013-9: Offer filters by date are rejected

> Old format supported until: not provided

**Before**

[GET /v1/catalog-offers](/docs/entities/catalog-offers/list), [POST /v1/catalog-offers/search](/docs/entities/catalog-offers/search), [POST /v1/catalog-offers/aggregate](/docs/entities/catalog-offers/aggregate) and the legacy `GET /v1/catalog-offers/aggregate` accepted a filter on `dateCreate`, `timestampX`, `dateActiveFrom`, and `dateActiveTo` and passed it to Bitrix24. The Bitrix24 method does not apply date filters, so the `200` response contained every offer in the catalog and both aggregates were computed over the whole catalog instead of the requested period. A list sub-call for offers in either batch route behaved the same way. A wide date range in search was also split into windows, each window returned the same rows, and the response carried a false `WINDOW_TRUNCATED` warning.

**After**

A filter on any of these four fields is rejected before the Bitrix24 call. The single routes and both aggregates answer `400 UNKNOWN_FILTER_FIELD`. In a list sub-call of a batch the same code arrives in that sub-call's own error field, and the remaining sub-calls still run. Offer search no longer splits into time windows. Filters on other fields work as before, the date fields are still returned in the response, and an aggregate without a date filter is computed as before.

**What integrators should do**

Remove date fields from offer filters on every endpoint listed below, including list sub-calls of a batch. To select offers by date, request them without a date filter and select by `dateCreate` or `timestampX` from the response. Compute a per-period aggregate on your side from those same rows — the aggregate has no date selection, and its response carries no rows to select from.

**Affected endpoints:** [GET /v1/catalog-offers](/docs/entities/catalog-offers/list), [POST /v1/catalog-offers/search](/docs/entities/catalog-offers/search), [POST /v1/catalog-offers/aggregate](/docs/entities/catalog-offers/aggregate), the legacy `GET /v1/catalog-offers/aggregate`, [POST /v1/{entity}/batch](/docs/batch), [POST /v1/batch](/docs/batch).

### FIX-1013-10: an unreadable plan on server creation answers only 403

**Before**

[POST /v1/infra/servers](/docs/infra/servers/create) in some cases answered `PORTAL_TARIFF_UNREADABLE` with status `402`, although the code table promises `403` for it. A client branching on the status took such a refusal for a paywall and offered a purchase that does not clear it.

**After**

The code arrives only with status `403`: `details.requiredTariffs` is empty, buying a plan does not clear the refusal, and the remedy is named in `userMessage`. Paywall codes (`INT_TARIFF_REQUIRED`, `INT_VIBE_PLUS_REQUIRED`, the trial and billing ones) still answer `402`. The `201` response on a successful create is unchanged.

**Impact on integrators**

A client that reads the refusal by `error.code` needs no change. Branching on the status no longer mistakes this refusal for a paywall.

### FIX-1013-11: service fields respect the catalog

**Before**

[GET /v1/catalog-services/fields](/docs/entities/catalog-services/fields) returned only static fields with the `fields_partial` warning, even when `iblockId` was supplied.

**After**

When `iblockId` is supplied and Bitrix24 metadata is retrieved successfully, the response includes catalog properties without the `fields_partial` warning. Without `iblockId` or when metadata is unavailable, the response still contains static fields and the warning.

**Impact on integrators**

Supply the catalog’s `iblockId` to retrieve its properties.

### FIX-1013-12: Checklist reports a missing task

**Before**

Routes `/v1/tasks/:taskId/checklist` and `/v1/tasks/:taskId/checklist/:itemId`, including `complete` and `renew` actions, returned `422 BITRIX_ERROR` when Bitrix24 reported `TASK_NOT_FOUND_OR_NOT_ACCESSIBLE`.

**After**

This refusal returns `404 TASK_NOT_FOUND`. A missing item still returns `404 NOT_FOUND`. Scope refusals and throttling keep their status codes.

### NEW-1013-13: Atlas token exchange after a Bitrix24 account registers anew in Atlas

A Bitrix24 account registered anew in Atlas gets a new `tid`, and its people arrive with new `sub` values. `POST /v1/connect/atlas/token` with a token of the same issuer and the new `tid` moves the pinned identity of the Bitrix24 account user to the new registration and issues the key when the Bitrix24 account confirms that the user number is still held by the same person. If that cannot be confirmed, the response is `403` `atlas_identity_changed` with a new `details.reason` value: `atlas_tenant_changed_unverified`. If the Bitrix24 account names another holder of the number, the response is `403` `atlas_identity_changed` with `details.reason` `portal_occupant_changed`. If the identity is pinned under another issuer, or the token carries the same `tid` with another `sub`, the response is still `403` `atlas_identity_changed` with `details.reason` `atlas_subject_changed`. `POST /v1/connect/atlas/renew` does not move the pin: after the move, a key issued under the previous registration is not renewed, and a new exchange is needed.

### BC-1013-14: Missing work schedules return an error

> Old format supported until: not provided

**Before**

[`GET /v1/workday/schedule`](/docs/workday/schedule) returned HTTP 200 with `data: []` for a missing or deleted schedule.

**After**

The request returns HTTP 404 with code `ENTITY_NOT_FOUND`. An existing schedule is still returned in `data`.

**What integrators should do**

Detect a missing schedule by HTTP 404 and `error.code` rather than an empty `data` value.

### FIX-1013-15: Batch file and folder lists honor the parent folder

**Before**

`list` calls in `POST /v1/files/batch` and `POST /v1/folders/batch` lost the supplied folder identifier and received a Bitrix24 error.

**After**

The batch list reads the specified folder: `folderId` for files, `parentId` for folders. Send the parameter in `calls[].params` or `calls[].params.filter`. If no non-empty scalar parameter can be resolved, `MISSING_REQUIRED_PARAMS` appears in `data[i].error` within an HTTP 200 response. Other sub-calls continue. With a scalar direct parameter supplied, an array, object or `null` in the matching `filter` key causes the sub-call error `INVALID_FILTER_OPERATOR`. The same restriction applies to file and folder `list` calls in the global `POST /v1/batch`.

**Impact on integrators**

Valid requests need no changes. Check each sub-call for errors. See [Batch calls](/docs/batch).

### FIX-1013-16: catalog batch lists respect field selection

**Before**

The `list` action in `POST /v1/catalog-products/batch`, `POST /v1/catalog-services/batch`, `POST /v1/catalog-skus/batch` and `POST /v1/catalog-offers/batch` could return a per-call `CALL_FAILED` error about required selection fields even when `filter.iblockId` was supplied.

**After**

Omitting `select` or using `select: ["*"]` returns the same reduced field set as the single list and search endpoints. Explicit `select` uses the same field-name mapping. Required fields for explicit selection remain required, and a failed sub-call does not prevent other calls from completing.

**Impact on integrators**

List requests without `select` need no changes. When selecting fields explicitly, include `id` and `iblockId`.

### FIX-1013-17: Validation of bot message, command and file IDs

**Before**

Invalid `messageId`, `commandId` and `fileId` in the `/v1/bots/:botId/...` path were forwarded to Bitrix24 as zero, a fractional number or `null`. The refusal depended on the Bitrix24 account response.

**After**

Vibecode returns `400 INVALID_PARAMS` before calling Bitrix24. The path ID must be a positive integer from `1` to `9007199254740991`, without a sign, leading zeros, fraction, exponent or whitespace. String `dialogId` handling is preserved.


**Impact on integrators**

Valid positive IDs are forwarded as before. On `400 INVALID_PARAMS`, correct the path segment named in the error.

**Affected endpoints:** [GET /v1/bots/:botId/messages/:messageId](/docs/bots/messages/get), [PATCH /v1/bots/:botId/messages/:messageId](/docs/bots/messages/update), [DELETE /v1/bots/:botId/messages/:messageId](/docs/bots/messages/delete), [GET /v1/bots/:botId/messages/:messageId/context](/docs/bots/messages/context), [POST /v1/bots/:botId/messages/:messageId/reactions](/docs/bots/ui/reaction-add), [DELETE /v1/bots/:botId/messages/:messageId/reactions](/docs/bots/ui/reaction-delete), [PATCH /v1/bots/:botId/commands/:commandId](/docs/bots/commands/update), [DELETE /v1/bots/:botId/commands/:commandId](/docs/bots/commands/delete), [POST /v1/bots/:botId/commands/:commandId/answer](/docs/bots/commands/answer), [GET /v1/bots/:botId/files/:fileId](/docs/bots/files/download).

### FIX-1013-18: mail date filters accept timezone offsets

**Before**

In [GET /v1/mail/messages](/docs/mail/messages/list), date filters with an offset without a colon or an unencoded `+` sign were refused. Dates with `Z` depended on the Bitrix24 mail module version.

**After**

The `dateFrom` and `dateTo` parameters accept a `YYYY-MM-DD` date and a full date-time with `Z` or an offset such as `+03:00` / `+0300`. The offset is converted to the format with a colon before forwarding to Bitrix24. Fractional seconds may contain 3 or 6 digits.

**Impact on integrators**

Encode `+` in the query string as `%2B`. Bare dates and other filter parameters are unaffected.
