# API changes: June 24, 2026

[← Changelog](/docs/changelog) · [June 2026](/docs/changelog/2026-06)

### FIX-0624-1: galaxy app logs return container output

**Before**

[GET /v1/infra/servers/:id/logs](/docs/infra/deploy/logs) for a galaxy app (`kind=GALAXY_APP`) returned only the host system journal (`journalctl`), not the app container's own logs — you could not see the stdout/stderr of a crashed app.

**After**

For a galaxy app the endpoint reads the container's stdout/stderr (`docker logs`). The read is read-only: if the galaxy host is asleep or unreachable, the response is an empty `data.logs` plus `data.hint`, and the host is not woken. The `since` parameter for galaxy apps accepts only a duration (`10m`) or an RFC3339 timestamp — the human-readable `journalctl` forms ("1 hour ago") are allowed only for Black Hole servers.

### NEW-0624-2: GALAXY_APP_START_FAILED deploy error code

[POST /v1/infra/servers/:id/deploy](/docs/infra/deploy) for a galaxy app returns `502 GALAXY_APP_START_FAILED` when the app builds successfully but crashes or enters an OOM restart loop right after start. This is a distinct code from `GALAXY_APP_BUILD_FAILED` (a build error): it shows the build succeeded and the problem is at runtime (for example, exceeding the memory limit). The tail of the container logs is delivered in the `buildLog` field.

### FIX-0624-3: blocking server wake window raised to ~5 minutes

**Before**

A blocking wake — [POST /v1/infra/servers/:id/wake](/docs/infra/lifecycle/wake) with `?wait=true` and the auto-wake of a sleeping server on [POST /v1/infra/servers/:id/deploy](/docs/infra/deploy) — waited for readiness (status RUNNING plus a connected tunnel) for up to about 3 minutes, then returned `504 WAKE_TIMEOUT`.

**After**

The main wait phase is raised from ~3 to ~5 minutes, and including the reboot phase the full ceiling before `504` is about 6.5 minutes. A deeply cold host (for example, a galaxy that has slept for several days) gets enough time to boot and connect instead of hitting a false timeout. The error code, response shape, and the proxy-side ceiling are unchanged.

**Impact on integrators**

If your client sets its own timeout for these calls, budget about 6.5 minutes instead of 3. Everything else is unchanged — you do not need to rewrite the integration.

### NEW-0624-4: placement and graduateFrom parameters on server create

[POST /v1/infra/servers](/docs/infra/servers/create) gained two optional parameters. `placement` — `auto` (default, unchanged behavior) or `dedicated`: on an account with the `galaxies-only` placement model, the value `dedicated` creates a standalone virtual machine instead of a Galaxy application, passing the same checks as a normal server create — the `serverCreation` policy and the per-user server quota. `graduateFrom` takes the identifier of your Galaxy application (`kind=GALAXY_APP`): after the dedicated server is created, that application is deleted. `graduateFrom` is owner-scoped — a foreign or non-Galaxy identifier returns `404` and deletes nothing.

This is additive: without `placement`, or with `placement: "auto"`, the request behaves exactly as before.

In addition, when a Galaxy application fails with OOM, the response of [POST /v1/infra/servers/:id/deploy](/docs/infra/deploy) with the code `502 GALAXY_APP_START_FAILED` now carries a structured hint `error.hint` with `recoveryAction: "graduate-to-dedicated-vm"` — how to re-create the application on a dedicated server via `placement: "dedicated"` and `graduateFrom`. The hint is added only when the failure cause is OOM (exceeding the container memory limit), not a plain crash.

### FIX-0624-5: server creation with code in source.content accepts archives up to 500 MB

**Before**

[POST /v1/infra/servers](/docs/infra/servers/create) with an inline archive in `source.content` (one-shot Galaxy app creation) returned `413 FST_ERR_CTP_BODY_TOO_LARGE` for archives above ~750 KB, even though the documented limit for `source.content` is 500 MB per request body. The route inherited the global 1 MB body limit.

**After**

The route accepts a request body up to 500 MB — matching `POST /v1/infra/servers/:id/deploy` and `POST /v1/infra/servers/:id/upload`. The documented limit now actually applies.

### NEW-0624-6: group requisites by tax IDs (INN/OGRN/KPP) in aggregate

[POST /v1/requisites/aggregate](/docs/entities/requisites/aggregate) now accepts `groupBy` on the requisite's string identifiers: `rqInn`, `rqKpp`, `rqOgrn`, `rqOgrnip`, `rqOkpo`, `rqVatId`, `rqResidenceCountry`, `rqCompanyName`, plus `presetId`, `entityTypeId`, `active`. Previously grouping by these fields returned `400 INVALID_PARAMS` with an empty list of available fields.

Grouping by `rqInn` is the fastest way to find duplicate requisites in a single call: groups with `count > 1` hold the repeated values. Existing calls (`groupBy` on `entityTypeId`/`presetId`) keep working unchanged. Numeric functions (`sum`/`avg`/`min`/`max`) remain unavailable on these string fields — they are for grouping only.

### FIX-0624-7: a sleeping server's availableActions includes wake/start; repair-status reports `running` immediately

**Before**

For a sleeping server with no tunnel (`SLEEPING` + `blackholeStatus: DISCONNECTED` — the normal state of a stopped server) the `availableActions` field in the `422 SERVER_WRONG_STATE` response and in `GET /v1/me` (`infra.unhealthyServers`) listed only `["repair","delete"]` — no obvious way to bring the server back. Separately: right after [POST /v1/infra/servers/:id/repair](/docs/infra/lifecycle/repair), a [repair-status](/docs/infra/lifecycle/repair-status) poll in the first milliseconds could return `{status:"idle"}`, and the poll loop exited prematurely.

**After**

`availableActions` for any sleeping server now contains `["wake","start","repair","delete"]` — both actions are genuinely accepted by the `/wake` and `/start` endpoints. And `repair-status` sets `running` synchronously when the repair starts, so the very first poll sees `running`, not `idle`. Existing calls keep working unchanged.

### FIX-0624-8: stage-history?entityType=invoice now returns smart-invoice history (31)

**Before**

[GET /v1/stage-history](/docs/stage-history)`?entityType=invoice` returned the history of the deprecated old invoice (entityTypeId 5, status-based: `statusId`/`statusSemanticId`). The current smart invoice (31) was reachable only under `entityType=new-invoice`. A client working with invoices via `/v1/invoices` (type 31) who queried history under `invoice` got a foreign, deprecated type.

**After**

`entityType=invoice` returns the current smart invoice's history (entityTypeId 31, stage-based: `stageId`/`stageSemanticId`/`categoryId`) — consistent with `/v1/invoices`. The `new-invoice` key is kept as an alias for 31 for backward compatibility, so nothing needs to change.

### NEW-0624-9: bitrix/embeddings text embeddings endpoint

An OpenAI-compatible [POST /v1/embeddings](/docs/ai/embeddings) endpoint converts text into vector representations (embeddings) for semantic search, clustering, deduplication, and finding similar CRM records. The `bitrix/embeddings` model is free and platform-provided — no provider key of your own is required. The `input` field accepts a string or an array of strings, and the response is returned in the raw OpenAI format: an `object` field set to `list`, a `data` array of objects shaped like `{ object: "embedding", embedding, index }`, and a `usage` block. The optional `encoding_format` (`float` or `base64`) and `dimensions` parameters are supported. The list of available models and their capabilities is at [GET /v1/models](/docs/ai/models/list), and the embeddings model has the `embeddings` capability set.

### FIX-0624-10: calendar event field types now match real responses

**Before**

[GET /v1/calendar-events/fields](/docs/entities/calendar-events/fields) declared `rrule` as `string` and `dateCreate` and `updatedAt` as `datetime`, while on read `rrule` comes back as an object and `dateCreate` and `updatedAt` come back as a string in the account's regional format (not ISO 8601). The schema listed an `ownerType` field that responses never return. The `rrule` object carried internal keys `~UNTIL` and `UNTIL_TS`, and recurring-event list items carried an internal `RINDEX` key.

**After**

`/fields` declares `rrule` as `object` and `dateCreate` and `updatedAt` as `string`. The phantom `ownerType` field is removed from the schema. The internal keys `~UNTIL`, `UNTIL_TS`, and `RINDEX` no longer reach responses.

**Impact on integrators**

Documented fields did not change — a client that read only them keeps working. Use `from` and `to` (ISO 8601) for an absolute timestamp. Do not parse `dateCreate` and `updatedAt` with a fixed parser — their format depends on the account's regional settings.

### NEW-0624-11: provisionReason field in the server responses

[GET /v1/infra/servers](/docs/infra/servers/list) and [GET /v1/infra/servers/:id](/docs/infra/servers/get) now return a provisionReason field with the value oom, crash or null — a structured reason for a galaxy app failure. Previously it was exposed only on the dashboard session routes, so the Vibecode API had to parse the free-text provisionError. The oom value signals to graduate the app to a dedicated server: create one with placement set to dedicated and graduateFrom. The field is optional and additive — existing integrations keep working unchanged.

### FIX-0624-12: the graduation signal fires for any galaxy app memory shortage

**Before**

A Galaxy app that ran out of container memory — both one that hit the limit and kept restarting at the edge and one that exhausts memory right at startup (for example, loading a big model) — was classified as an ordinary crash: [GET /v1/infra/servers/:id](/docs/infra/servers/get) returned provisionReason crash, and the [POST /v1/infra/servers/:id/deploy](/docs/infra/deploy) 502 GALAXY_APP_START_FAILED response carried no graduation hint. Conversely, a non-OOM crash-loop (an unhandled exception) could be wrongly marked oom.

**After**

A real memory shortage in any shape — an instant boot-OOM or a grow-into-the-limit loop — now reliably yields provisionReason oom and an error.hint with recoveryAction graduate-to-dedicated-vm. Build errors and apps that never started (a broken start command) stay crash with no graduation.

**Impact on integrators**

No action needed: the field value and the hint now reflect the memory shortage more accurately. An agent can reliably detect provisionReason oom for any memory exhaustion and graduate the app to a dedicated server.
