[{"data":1,"prerenderedAt":7},["ShallowReactive",2],{"docs-changelog\u002F2026-06-24":3,"docs-tabs-changelog\u002F2026-06-24":6},{"content":4,"lastmod":5},"# API changes: June 24, 2026\n\n[← Changelog](\u002Fdocs\u002Fchangelog) · [June 2026](\u002Fdocs\u002Fchangelog\u002F2026-06)\n\n### FIX-0624-1: galaxy app logs return container output\n\n**Before**\n\n[GET \u002Fv1\u002Finfra\u002Fservers\u002F:id\u002Flogs](\u002Fdocs\u002Finfra\u002Fdeploy\u002Flogs) for a galaxy app (`kind=GALAXY_APP`) returned only the host system journal, not the app container's own logs — you could not see the stdout\u002Fstderr of a crashed app.\n\n**After**\n\nFor a galaxy app the endpoint reads the container's stdout\u002Fstderr. 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.\n\n### NEW-0624-2: GALAXY_APP_START_FAILED deploy error code\n\n[POST \u002Fv1\u002Finfra\u002Fservers\u002F:id\u002Fdeploy](\u002Fdocs\u002Finfra\u002Fdeploy) 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.\n\n### FIX-0624-3: blocking server wake window raised to ~5 minutes\n\n**Before**\n\nA blocking wake — [POST \u002Fv1\u002Finfra\u002Fservers\u002F:id\u002Fwake](\u002Fdocs\u002Finfra\u002Flifecycle\u002Fwake) with `?wait=true` and the auto-wake of a sleeping server on [POST \u002Fv1\u002Finfra\u002Fservers\u002F:id\u002Fdeploy](\u002Fdocs\u002Finfra\u002Fdeploy) — waited for readiness (status RUNNING plus a connected tunnel) for up to about 3 minutes, then returned `504 WAKE_TIMEOUT`.\n\n**After**\n\nThe 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.\n\n**Impact on integrators**\n\nIf 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.\n\n### NEW-0624-4: placement and graduateFrom parameters on server create\n\n[POST \u002Fv1\u002Finfra\u002Fservers](\u002Fdocs\u002Finfra\u002Fservers\u002Fcreate) 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.\n\nThis is additive: without `placement`, or with `placement: \"auto\"`, the request behaves exactly as before.\n\nIn addition, when a Galaxy application fails with OOM, the response of [POST \u002Fv1\u002Finfra\u002Fservers\u002F:id\u002Fdeploy](\u002Fdocs\u002Finfra\u002Fdeploy) 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.\n\n### FIX-0624-5: server creation with code in source.content accepts archives up to 500 MB\n\n**Before**\n\n[POST \u002Fv1\u002Finfra\u002Fservers](\u002Fdocs\u002Finfra\u002Fservers\u002Fcreate) 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.\n\n**After**\n\nThe route accepts a request body up to 500 MB — matching `POST \u002Fv1\u002Finfra\u002Fservers\u002F:id\u002Fdeploy` and `POST \u002Fv1\u002Finfra\u002Fservers\u002F:id\u002Fupload`. The documented limit now actually applies.\n\n### NEW-0624-6: group requisites by tax IDs (INN\u002FOGRN\u002FKPP) in aggregate\n\n[POST \u002Fv1\u002Frequisites\u002Faggregate](\u002Fdocs\u002Fentities\u002Frequisites\u002Faggregate) 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.\n\nGrouping 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`\u002F`presetId`) keep working unchanged. Numeric functions (`sum`\u002F`avg`\u002F`min`\u002F`max`) remain unavailable on these string fields — they are for grouping only.\n\n### FIX-0624-7: a sleeping server's availableActions includes wake\u002Fstart; repair-status reports `running` immediately\n\n**Before**\n\nFor 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 \u002Fv1\u002Fme` (`infra.unhealthyServers`) listed only `[\"repair\",\"delete\"]` — no obvious way to bring the server back. Separately: right after [POST \u002Fv1\u002Finfra\u002Fservers\u002F:id\u002Frepair](\u002Fdocs\u002Finfra\u002Flifecycle\u002Frepair), a [repair-status](\u002Fdocs\u002Finfra\u002Flifecycle\u002Frepair-status) poll in the first milliseconds could return `{status:\"idle\"}`, and the poll loop exited prematurely.\n\n**After**\n\n`availableActions` for any sleeping server now contains `[\"wake\",\"start\",\"repair\",\"delete\"]` — both actions are genuinely accepted by the `\u002Fwake` and `\u002Fstart` 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.\n\n### FIX-0624-8: stage-history?entityType=invoice now returns smart-invoice history (31)\n\n**Before**\n\n[GET \u002Fv1\u002Fstage-history](\u002Fdocs\u002Fstage-history)`?entityType=invoice` returned the history of the deprecated old invoice (entityTypeId 5, status-based: `statusId`\u002F`statusSemanticId`). The current smart invoice (31) was reachable only under `entityType=new-invoice`. A client working with invoices via `\u002Fv1\u002Finvoices` (type 31) who queried history under `invoice` got a foreign, deprecated type.\n\n**After**\n\n`entityType=invoice` returns the current smart invoice's history (entityTypeId 31, stage-based: `stageId`\u002F`stageSemanticId`\u002F`categoryId`) — consistent with `\u002Fv1\u002Finvoices`. The `new-invoice` key is kept as an alias for 31 for backward compatibility, so nothing needs to change.\n\n### NEW-0624-9: bitrix\u002Fembeddings text embeddings endpoint\n\nAn OpenAI-compatible [POST \u002Fv1\u002Fembeddings](\u002Fdocs\u002Fai\u002Fembeddings) endpoint converts text into vector representations (embeddings) for semantic search, clustering, deduplication, and finding similar CRM records. The `bitrix\u002Fembeddings` 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 \u002Fv1\u002Fmodels](\u002Fdocs\u002Fai\u002Fmodels\u002Flist), and the embeddings model has the `embeddings` capability set.\n\n### FIX-0624-10: calendar event field types now match real responses\n\n**Before**\n\n[GET \u002Fv1\u002Fcalendar-events\u002Ffields](\u002Fdocs\u002Fentities\u002Fcalendar-events\u002Ffields) 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.\n\n**After**\n\n`\u002Ffields` 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.\n\n**Impact on integrators**\n\nDocumented 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.\n\n### NEW-0624-11: provisionReason field in the server responses\n\n[GET \u002Fv1\u002Finfra\u002Fservers](\u002Fdocs\u002Finfra\u002Fservers\u002Flist) and [GET \u002Fv1\u002Finfra\u002Fservers\u002F:id](\u002Fdocs\u002Finfra\u002Fservers\u002Fget) now return a provisionReason field with the value oom, crash or null — a structured reason for a galaxy app failure. Previously clients 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.\n\n### FIX-0624-12: the graduation signal fires for any galaxy app memory shortage\n\n**Before**\n\nA 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 \u002Fv1\u002Finfra\u002Fservers\u002F:id](\u002Fdocs\u002Finfra\u002Fservers\u002Fget) returned provisionReason crash, and the [POST \u002Fv1\u002Finfra\u002Fservers\u002F:id\u002Fdeploy](\u002Fdocs\u002Finfra\u002Fdeploy) 502 GALAXY_APP_START_FAILED response carried no graduation hint. Conversely, a non-OOM crash-loop (an unhandled exception) could be wrongly marked oom.\n\n**After**\n\nA 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.\n\n**Impact on integrators**\n\nNo 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.\n",null,{},1794739467323]