# API changes: October 21, 2026

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

### NEW-1021-1: python312 runtime on Python 3.12 from the Ubuntu 24.04 archive

The [`GET /v1/infra/runtimes`](/docs/infra/deploy/runtimes) catalog adds the `python312`, `python312-pg`, `python312-mysql`, `python312-redis` and `python312-rag` runtimes. On a dedicated virtual machine Python 3.12 comes from the Ubuntu 24.04 archive, and the app's packages live in a separate platform environment: the `python`, `pip` and `pip3` commands run in it, while `python3` and `python3.12` stay the system interpreter without the app's packages. So for `python312*` write `python app.py` in the `start` field, not `python3 app.py`. In Galaxy the runtime is built from the official `python:3.12-slim` image, where both commands work. The `python311*` runtimes stay in the catalog and work as before.

### BC-1021-2: Neutral image identifiers and names

> Old format supported until: not provided

**Before**

[GET /v1/infra/providers/:providerId/images](/docs/infra/providers/images) could return internal OS build identifiers and names.

**After**

For Bitrix24 Cloud images that previously returned an internal build identifier, `id` now contains the `ubuntu-2404-lts` family and `name` is `Ubuntu 24.04 LTS`. The response remains HTTP 200 with the same fields. Other image values are unchanged.

**What integrators should do**

Pass the returned `data[].id` as `image` when creating a server. Do not infer the OS from the internal identifier format or parse the `name` string. Previously returned identifiers remain accepted when creating a server.

### NEW-1021-3: APP_DB_BUSY reports that the galaxy host is starting

The `409 APP_DB_BUSY` response to an application database read gains an optional `details.hostState` field. It equals `waking` while the galaxy host is starting after sleep or creation, and is absent when the host is busy with another operation. The field arrives in responses of [`GET /v1/infra/servers/{id}/db`](/docs/infra/database/info), [`GET /v1/infra/servers/{id}/db/schema`](/docs/infra/database/schema), [`GET /v1/infra/servers/{id}/db/tables/{table}/rows`](/docs/infra/database/rows) and `POST /v1/infra/servers/{id}/db/query`. The error code, `Retry-After` and the `retryable` flag stay the same: retry the request as before and show the user that the server is starting.

### FIX-1021-4: an oversized request to a model: images for bitrix are downscaled, a size refusal is 413 instead of 502

**Before**

[POST /v1/chat/completions](/docs/ai/chat/completions) with a `bitrix/*` model and a body over the model cluster limit answered `502 ai_provider_unavailable`, the same as a model failure. Repeating the same request got `502` again. Other AI methods, for example [POST /v1/embeddings](/docs/ai/embeddings) and [POST /v1/audio/transcriptions](/docs/ai/audio/transcriptions), answered the same `502` instead of a size refusal when the provider itself refused the request by size.

**After**

When the body contains `data:` images and exceeds the limit, the platform downscales them itself and sends the request to the model. A body still over the 2 MiB limit after that gets `413 ai_payload_too_large`, and the message states the request size and the limit in effect. When the platform is already downscaling many images at once, the response is `429 ai_image_resize_busy` with a `Retry-After` header. The request is not sent to the model and nothing is charged. With `stream: true` both refusals arrive as an error frame with the same code inside a `200` response, and the pause for `ai_image_resize_busy` arrives as the `retryAfter` field of the frame. When the provider itself refused the request by size, any AI method, models on your own provider key included, answers `413 ai_payload_too_large` with `providerStatusCode: 413`. Image downscaling and the check before the model call apply only to chat with `bitrix/*` models.

**Impact on integrators**

Requests within the limit work as before. Requests with large images go through with no change on the client side. Retrying a `413` will not help, after a `429` retry after `Retry-After`, in a stream after `retryAfter` from the error frame. To control the quality yourself, downscale images to 1500 pixels on the long side. Details — [image analysis](/docs/ai/chat/vision).

### NEW-1021-5: Connector catalog groups, session modes and metadata

[Connector list](/docs/connectors-host) `GET /v1/connectors` accepts `group=all|connected|own|available` and `mode=cowork|code`. Selection happens before pagination. `connected` contains entries with a connection, `available` contains the remaining visible entries, and `own` is currently empty. Group counts apply the other filters except `group` and `view`. Start at the first page when changing group or mode; omitted `group` and `all` share cursors. Supplier session mode does not change the access policy read/write mode.

Service-company and publisher fields match the card: service-company data includes the supplier-provided name and URL, or null when absent; publisher includes its name and URL. The required `categories` field contains nonempty visible catalog categories before search, filters and pagination, including responses without list parameters. `sort=popular` uses the number of companies with an active connection, excluding internal Bitrix24 accounts; counts refresh daily. Explicit pages include tool counts and popularity indicators. Connected connectors do not receive a popularity badge.

### FIX-1021-6: The Deploy API operation limit is counted per API key and server

**Before**

Requests with no key, an invalid key or another valid key consumed a shared server counter. The owner could therefore receive `429 RATE_LIMITED` even when making very few requests to the server. This affected [POST /v1/infra/servers/:id/exec](/docs/infra/deploy/exec), [POST /v1/infra/servers/:id/upload](/docs/infra/deploy/upload), [POST /v1/infra/servers/:id/deploy](/docs/infra/deploy/deploy), [POST /v1/infra/servers/:id/icon](/docs/infra/app-icon) and [GET /v1/infra/servers/:id/logs](/docs/infra/deploy/logs).

**After**

The counter is kept separately for each API-key-and-server pair. Requests with no key or an invalid key do not consume the owner's limit. Another valid key uses its own counter. The threshold is unchanged: the effective value is returned in the `x-ratelimit-limit` header.

**Impact on integrators**

No integration changes are required. When your key exceeds its own threshold, the response still contains `429 RATE_LIMITED` in the same format. Retry the request after the interval specified in the `Retry-After` header.

### FIX-1021-7: Request and response examples in the API reference

**Before**

Some examples showed invented response fields or requests rejected by the API. The OAuth instructions suggested opening a URL containing the secret application key in the browser.

**After**

Examples follow the current handlers. For OAuth sign-in, the application server obtains the authorization URL and the browser opens only the returned URL without the secret key.

Response schemas describe the existing bots, infra and models fields. Template creation keeps server metadata and its download URL, booking fields correctly indicate writability, and the port configuration example uses an allowed application port.

**Impact on integrators**

Use the updated examples. API behavior is unchanged. Keep the secret application key on the server.

### FIX-1021-8: OpenAPI describes the fields for creating a time entry

**Before**

The body schema for `POST /v1/tasks/{taskId}/time` advertised `commentText`, `dateStart`, and `dateStop`, which the handler does not save, and did not mark `seconds` as required.

**After**

The schema describes required `seconds` and optional `comment`, `userId`, and `createdDate`. The `createdDate` field accepts `YYYY-MM-DD` and ISO 8601 with or without a time zone offset. Request handling is unchanged: the description now matches the fields already supported. Regenerating a client from OpenAPI gives it these field names and required `seconds`.

### FIX-1021-9: bot registration promises a retry only where it helps

**Before**

`POST /v1/bots` and `POST /v1/bots/registrations/{code}/recover` answered any refusal caused by the registration state with HTTP 409 and a `Retry-After: 5` header, even when a retry could not help. The `error.code` field could carry an internal code that the documentation does not describe.

**After**

The codes described for `POST /v1/bots` keep their code and text. `BOT_REGISTRATION_CONTEXT_CHANGED` and `BOT_REGISTRATION_PROJECTION_CONFLICT` no longer carry `Retry-After`. `BOT_EFFECT_DESIRED_STATE_NOT_PROVED` carries `Retry-After`: the time until the next scheduled check when the registration is waiting for it, otherwise 30 seconds. On `BOT_RECOVERY_IN_PROGRESS` the header is unchanged. On `BOT_DOMAIN_REREGISTRATION_REQUIRED` it is unchanged for the response that carries `data` (a saved bot row kept with the address-move marker); a move detected during the registration itself arrives with the same code but without `data` and without `Retry-After` — that refusal is also cleared by a later retry, not by support. Other refusals arrive in public classes. On `POST /v1/bots` these are `BOT_EFFECT_IN_PROGRESS` with the same `Retry-After` rule while the registration is still being reconciled with Bitrix24, and `BOT_UNAVAILABLE` without `Retry-After` when the registration state must be repaired by support. On `POST /v1/bots/registrations/{code}/recover` these are `BOT_REGISTRATION_RECOVERY_PENDING` with the same `Retry-After` rule and `BOT_UNAVAILABLE` without the header. The `error.details.registrationRef` field stays in both recovery responses. The codes and the header rules are described in the `409` response of both methods in the OpenAPI schema `GET /v1/openapi.json?scope=imbot`.

**Impact on integrators**

No action is needed. A client that handles `409` retries when `Retry-After` is present; the one refusal worth retrying without the header is `BOT_DOMAIN_REREGISTRATION_REQUIRED` without `data` — a re-registration already running after an address change. On `BOT_UNAVAILABLE`, contact support and pass `registrationRef` when the response carries it.
