# API changes: October 24, 2026

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

### FIX-1024-1: actions on a server being created answer 409 SERVER_CREATING

**Before**

`POST /v1/infra/servers/{id}/start` and `/wake` on a server that was still being created could answer `422 VM_MISSING` and move the server to an error state mid-creation. Other actions on such a server changed its status while creation was running.

`POST /v1/infra/servers` with galaxy placement, while the application host was still being created, started a second host.

`DELETE /v1/infra/servers/{id}` on a server with no virtual machine attached yet reported `not-applicable` in the `cloudDelete` field, although a machine could appear later.

If the platform put the account on hold while the server was being created, it still bought a paid machine for it.

**After**

`POST /v1/infra/servers/{id}/start`, `/stop`, `/sleep-now`, `/reboot`, `/wake` and `/repair` on a server that is still being created answer `409 SERVER_CREATING` and change nothing: the status, billing and the machine stay as they were. `error.userMessage` carries a human-readable text.

`POST /v1/infra/servers` with galaxy placement, while the application host is still being created, answers `503 GALAXY_HOST_CREATING` with a `Retry-After` header and creates nothing — no second host is started.

`DELETE /v1/infra/servers/{id}` on a server that is still being created and has no virtual machine attached yet answers `cloudDelete: "deferred"`: no request went to the cloud, and the platform deletes the machine if one appears. When a machine is already attached, the response carries the usual cloud delete outcome (`confirmed`, `already-gone`, `failed`).

When the platform puts the account on hold while the server is being created, `POST /v1/infra/servers` answers `403 SERVER_WAKE_BLOCKED`: no paid machine is bought, and the server record stays in `ERROR` with the hold reason in `provisionErrorCode`.

**Impact on integrators**

Retry an action on a server being created once `GET /v1/infra/servers/{id}` shows that creation has finished. On `503 GALAXY_HOST_CREATING`, retry after the number of seconds in `Retry-After`. Read `deferred` in `cloudDelete` as "the platform deletes the machine". On `403 SERVER_WAKE_BLOCKED`, lift the hold and create the server again.

### NEW-1024-2: Bitrix24 entity operations with company credentials

Company credentials support Bitrix24 entity operations, including `/v1/users`, `/v1/departments` and `/v1/tasks`, within the current consent. Supported entity reads, writes, search, fields, aggregation, imports and batches carry `x-company-access: true` in OpenAPI. The `include` parameter and custom fields are available. A missing scope returns `403 SCOPE_MISSING`; use `RECONNECT` with updated consent to add scopes.

OAuth-only entities and separate custom routes remain closed with `403 CONNECT_COMPANY_ROUTE_FORBIDDEN`. Windowed search is unavailable: use `autoWindow: false` for ordinary search. Public issuance of company credentials remains closed; AI and storage availability are checked separately.

### NEW-1024-3: Notifications and workday reads with Company credentials

Company credentials can send notifications through `POST /v1/notifications`, read notifications and settings, and read workday information, records and reports through `/v1/workday/*` within the current Bitrix24 administrator's consent. The inbox and workday status/settings without `userId` refer to that administrator. Implicit notification settings also require `user`; records requires one of `user_brief`, `user_basic`, or `user`; time-control/users requires `department`. Missing consent returns 403 `SCOPE_MISSING`. Other operations in these sections remain closed to Company credentials; the Company connection documentation lists the available reads.

Webhook URL masking in `/v1/notifications` responses now applies to all keys, including personal keys: strings containing secret webhook URLs are replaced entirely with `[REDACTED]`.

### BC-1024-4: storage validates the file content type more strictly

> Old format supported until: not provided

**Before**

[POST /v1/storage/objects/multipart/create](/docs/storage/upload/multipart-create) accepted any non-empty string in `contentType` and stored it as is. For `PUBLIC` objects only HTML, JavaScript and SVG types were rejected. A comma-separated value such as `text/plain,text/html`, as well as XML, XHTML and `unknown/unknown`, passed, and a browser could open such a public file as a page.

**After**

`contentType`, and the content type of the `file` part in [POST /v1/storage/objects/upload](/docs/storage/upload/direct), accept exactly one `type/subtype` media type with optional `;name=value` parameters, with no comma anywhere in the value — including inside a quoted parameter such as `name="report,2026.pdf"` — and no longer than 255 characters. Any other value returns `400 STORAGE_INVALID_CONTENT_TYPE`. The type is stored in canonical form: lowercase, with `charset` as the only parameter kept. For `PUBLIC` objects both uploads also return `415 STORAGE_FORBIDDEN_CONTENT_TYPE` for any XML (`*/xml`, `*+xml`), XSL, `multipart/*`, `message/*`, `unknown/unknown`, `application/unknown` and `*/*`.

The same check now runs on reads of objects already uploaded as `PUBLIC`, and it closes more than the list above: `contentType` used to store any non-empty string, so `404 STORAGE_OBJECT_NOT_FOUND` also hits a public object with a harmless type that does not parse — one with a comma in the value (including inside quotes) or longer than 255 characters. That `404` comes both from the public link and from [GET /v1/storage/objects/:key](/docs/storage/objects/get) together with `HEAD` on the same path. The bytes and the stored type stay as they are: the type of an already uploaded object is not repaired automatically.

A multipart session started before the change with such a type cannot be finished: [POST /v1/storage/objects/multipart/complete](/docs/storage/upload/multipart-complete) returns `415 STORAGE_FORBIDDEN_CONTENT_TYPE`. While such a session is open as a replacement of a public object, that object is served as `404` as well, even though its own type is allowed.

**What integrators should do**

Pass a single type without commas — including inside a quoted parameter — and no longer than 255 characters in `contentType` and as the `file` part type. Upload XML files and the other listed types as `PRIVATE` and serve them through your own server.

Audit the objects already uploaded as `PUBLIC`: the stored type is visible in [GET /v1/storage/objects](/docs/storage/objects/list). If the type is forbidden or does not parse as a single media type, that object is already unreadable both by its public link and by key. Re-upload the file under the same key with a valid type — the old link starts serving it again — or upload the file under a new key as `PRIVATE` and serve it through your own server. Replacing an object under the same key cannot change its visibility, so moving it to `PRIVATE` means exactly a new upload.

Abort a multipart session opened before the change with such a type via [POST /v1/storage/objects/multipart/abort](/docs/storage/upload/multipart-abort) and start the upload again with a valid type: the public object being replaced becomes available at its old link right after the abort, provided its own type is allowed.

### NEW-1024-5: solution event to the Bitrix24 account: POST /v1/solution-events

New endpoint [POST /v1/solution-events](/docs/applications/solution-event): a solution, with a key of its application, notifies the Bitrix24
account of an event, and workflows with the "Vibecode solution event" trigger start there on behalf of
the solution card owner. The answer is synchronous: `accepted`, `duplicate`, or an error with a code and,
where a retry helps, `Retry-After`. Until the feature is enabled for the account, the endpoint answers
`409 SOLUTION_EVENTS_NOT_ENABLED`.

### FIX-1024-6: A completed command response no longer precedes server release

**Before**

`POST /v1/infra/servers/:id/exec?stream=false` could complete its HTTP 200 JSON response before releasing the server, so the next sequential request received `409 EXEC_BUSY`. The same ordering affected Galaxy app exec responses, durable exec admission, JSON deployment, and pinned-port change refusals through `PATCH /v1/infra/servers/:id/port`.

**After**

These responses complete after releasing the server from the corresponding request. The synchronous exec response remains HTTP 200; port-change refusal codes remain 409/502. Durable exec admission still returns HTTP 202 without waiting for the command to finish: its channel stays occupied until the task completes. Another operation that is actually running can still cause `409 EXEC_BUSY`.

### FIX-1024-7: bot event polling no longer loses events after Bitrix24 restarts numbering

**Before**

A poll without `offset` sent the stored cursor to Bitrix24. Before reading, Bitrix24 deletes every bot event with a lower id. When Bitrix24 restarted event numbering, new events got ids below the cursor and were deleted before the bot received them.

**After**

[GET /v1/bots/{botId}/events](/docs/bots/events/polling) without `offset`, or with an `offset` equal to the stored cursor, reads the queue from the start. That read deletes nothing. Only the `nextOffset` of the events returned by the same request is acknowledged. After a numbering restart the returned `nextOffset` can be lower than before.

**Impact on integrators**

No changes to bot event polling requests are required. If an acknowledgement does not reach Bitrix24, the same events are delivered again, so event processing should be idempotent. Events deleted earlier cannot be recovered.
