# API changes: October 27, 2026

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

### BC-1027-1: List writes reject empty fields and tighten required schema keys

> Old format supported until: not provided

**Before**

The following operations forwarded `fields: {}` to Bitrix24:

- [POST /v1/lists](/docs/lists/lists/create)
- [PATCH /v1/lists/:iblockId](/docs/lists/lists/update)
- [PATCH /v1/lists/:iblockId/fields/:fieldId](/docs/lists/fields/update)
- [POST /v1/lists/:iblockId/sections](/docs/lists/sections/create)
- [PATCH /v1/lists/:iblockId/sections/:sectionId](/docs/lists/sections/update)
- [POST /v1/lists/:iblockId/elements](/docs/lists/elements/create)
- [PATCH /v1/lists/:iblockId/elements/:elementId](/docs/lists/elements/update)

For an element update, this request could clear all of its fields. The OpenAPI schemas for list-field operations accepted requests without keys required by Bitrix24.

**After**

These operations with `fields: {}` return `400 MISSING_REQUIRED_FIELDS` before calling Bitrix24. This also applies when updating a list with `messages` or `rights`. Non-empty objects are forwarded as before, including explicit empty field values.

In OpenAPI, [creating a list field](/docs/lists/fields/create) now requires non-empty strings `NAME`, `TYPE`, and `CODE` inside `fields`, while [updating a list field](/docs/lists/fields/update) requires a non-empty `TYPE` string. Clients and validators generated from the new schema may reject incomplete non-empty objects before sending a request. Bitrix24 already required these keys.

**What integrators should do**

Send at least one field that you intend to write. If no update is needed, do not send the request. For an element update, send the complete desired field set: it remains a full overwrite, and omitted fields are cleared. Explicit empty values valid for a field keep their prior behavior, for example `{"NAME":""}`.

When creating a field, send, for example, `{"fields":{"NAME":"Priority","TYPE":"S","CODE":"PRIORITY"}}`. When updating a field, always send its current `TYPE`, for example, `{"fields":{"TYPE":"S"}}`: an existing field's type cannot be changed. Check these keys and their non-empty values when regenerating OpenAPI clients.

### NEW-1027-2: Retry a server replacement without a second purchase

[POST /v1/applications/:id/replace-server](/docs/applications/replace-server) accepts an optional `Idempotency-Key` header when creating a new server. A retry with the same API key, header value and request body within 24 hours of the first call does not create a second paid server. If the replacement completed and the application still points to that server, the response carries the original result, `Idempotent-Replayed: true` and an empty `warnings` array.

If the previous outcome is unknown, the retry returns `409 IDEMPOTENCY_KEY_ALREADY_USED`. Check the application card and the servers in the cabinet before another purchase. Duplicate protection may expire after 24 hours. The `{ serverId }` form ignores the header. Calls without the header keep their existing behaviour.

### FIX-1027-3: Cowork tier recommendations account for seat windows

**Before**
`GET /v1/cowork/state` recommended the next tier even when it did not increase the seat's available windows.

**After**
`recommendation.upgrade.nextTier` and `tiers[].isNext` identify the first higher tier that increases at least one window without reducing the others. Partner windows and live demos are included; temporary boosts do not affect selection. No upgrade is recommended when no tier qualifies.

### BC-1027-4: HEAD no longer runs the GET operation on three routes

> Old format supported until: not provided

**Before**

Automatic `HEAD` could run the `GET` handler at the task comment attachment download, server SSH credentials, and app blueprint spec addresses. It had a separate request limit and could succeed after the `GET` limit was exhausted.

**After**

`HEAD` at these addresses returns HTTP `404` without running the handler. `GET` behavior is unchanged.

**What integrators should do**

Do not use `HEAD` to check these addresses. Call `GET` only when you need the content: it returns file bytes for an attachment and secret connection data for the SSH route. Do not store the SSH response in ordinary check logs.

**Affected endpoints:** [GET /v1/tasks/:taskId/comments/:id/files/:fileId/download](/docs/entities/task-comments/file-download), [GET /v1/infra/servers/:id/ssh](/docs/infra/access/ssh), [GET /v1/app/blueprints/:slug](/docs/app-blueprints).

### NEW-1027-5: Exhausted AI quota period in the response

For companies with daily, weekly and monthly AI limits, the `402 ai_quota_exhausted` response includes `error.window` (`DAY`, `WEEK` or `MONTH`) and the renewal time in `error.resetAt`. The `window_exhausted` reason means requests pause until the window resets; `unknown_reaction` requires contacting an administrator. Configured wallet usage retains the `wallet_empty`, `wallet_off` and `breaker` reasons.

Affected endpoints: `POST /v1/chat/completions`, `POST /v1/embeddings`, `POST /v1/images/generations` and `POST /v1/audio/transcriptions`.

`GET /v1/ai/quota` also returns `data.scheme` (`NEW` or `LEGACY`). For `NEW`, `data.windows` contains the company’s day, week and month: `kind`, `sizeVibes` (null means unlimited), `usedVibes`, `resetAt` and `reaction`. Existing fields and breakdowns remain available.

### NEW-1027-6: actions on a server being moved to another zone answer 409 SERVER_ZONE_MOVING

The platform can move a server to another availability zone together with its disk. During the move, usually 10–20 minutes, the server sleeps and is not woken. `POST /v1/infra/servers/{id}/start`, `/stop`, `/sleep-now`, `/reboot`, `/wake` and `/repair` on such a server answer `409 SERVER_ZONE_MOVING` and change nothing: the status, billing and machine stay as they were. `error.userMessage` carries text for a person. Retry the action after the move finishes.

### BC-1027-7: creating a standalone machine responds immediately, without SSH credentials

> Old format supported until: not provided

**Before**

`POST /v1/infra/servers` for a standalone machine waited for a prepared machine when one was available and answered `running` with `ip`, otherwise it answered `provisioning`. Every first response carried the platform's `ssh.privateKey` once (and `ssh.password` when present), and the documentation told you to save it. A cloud refusal answered `502 PROVIDER_ERROR`. Without an `Idempotency-Key` header the server record was removed and the quota was not spent; with one the record stayed with `status: "error"`. An account hold set during creation answered `403 SERVER_WAKE_BLOCKED`.

**After**

The answer always comes right away with `status: "provisioning"` and `ip: null`. `ssh.password` and `ssh.privateKey` are always `null`. A cloud refusal arrives later as `status: "error"` with the reason in `provisionError`. A hold set before the machine is ordered ends the same way: `status: "error"` with the reason in `provisionError`. A hold set after the machine was ordered leaves the server as `status: "sleeping"` (machine stopped) with an empty `provisionError`. An `error` record stays and counts toward the per-user server limit until it is deleted.

**What integrators should do**

Poll `GET /v1/infra/servers/:id` until the status is `running`, `error` or `sleeping`. On `error`, read `provisionError`, `DELETE` the record and create the server again. SSH access exists only once the server is in `OPEN` mode, which a person switches on in the cabinet (`PATCH /v1/infra/servers/:id/mode` to `OPEN` answers `403 DIRECT_NETWORK_CHANGE_REQUIRES_HUMAN` for any API key). After that `GET /v1/infra/servers/:id/ssh` returns the credentials. With an API key alone there is no SSH; to work with a Black Hole server use the Deploy API (`exec`, `upload`, `logs`).

### BC-1027-8: Publishing a post requires explicit recipients

> Old format supported until: not provided

**Before**

[POST /v1/posts](/docs/feed/posts/create) published to all employees when `recipients` was omitted or contained an empty array.

**After**

The `recipients` field is required. An omitted or empty array returns `400 MISSING_PARAMS`; an invalid type or recipient code returns `400 INVALID_PARAMS`. No post is published until the request is corrected. Accepted codes are `U<id>`, `SG<id>`, `D<id>`, `DR<id>` with a positive integer ID without leading zeros. `UA` is allowed only without other recipients. At most 100 distinct recipients and 1000 input array entries are accepted.

**What integrators should do**

Send the approved audience in every request. To publish to all employees, explicitly send `recipients: ["UA"]`. The response returns the post `id` and the supplied `recipients` array. If the dispatch outcome is unknown, check the Feed before publishing again.
