# Изменения API: 24 июня 2026

[← Журнал изменений](/docs/changelog) · [Июнь 2026](/docs/changelog/2026-06)

### FIX-0624-1: логи galaxy-приложения отдают вывод контейнера

**Было**

[GET /v1/infra/servers/:id/logs](/docs/infra/deploy/logs) для galaxy-приложения (`kind=GALAXY_APP`) возвращал только системный журнал хоста, а не логи самого контейнера приложения — увидеть stdout/stderr упавшего приложения было нельзя.

**Стало**

Для galaxy-приложения эндпоинт читает stdout/stderr контейнера. Чтение read-only: если хост-галактика спит или недоступен, ответ — пустой `data.logs` плюс `data.hint`, хост не будится. Параметр `since` для galaxy-приложений принимает только длительность (`10m`) или метку RFC3339 — человекочитаемые формы `journalctl` («1 hour ago») допустимы лишь для Black Hole-серверов.

### NEW-0624-2: код ошибки GALAXY_APP_START_FAILED при деплое

[POST /v1/infra/servers/:id/deploy](/docs/infra/deploy) для galaxy-приложения возвращает `502 GALAXY_APP_START_FAILED`, когда приложение успешно собралось, но упало или ушло в OOM-перезапуск сразу после старта. Это отдельный код от `GALAXY_APP_BUILD_FAILED` (ошибка сборки): по нему видно, что сборка прошла, а проблема в рантайме (например, превышение лимита памяти). Хвост логов контейнера приходит в поле `buildLog`.

### FIX-0624-3: окно блокирующего пробуждения сервера увеличено до ~5 минут

**Было**

Блокирующее пробуждение — [POST /v1/infra/servers/:id/wake](/docs/infra/lifecycle/wake) с `?wait=true` и автопробуждение спящего сервера при [POST /v1/infra/servers/:id/deploy](/docs/infra/deploy) — ждало готовности (статус RUNNING плюс подключённый туннель) примерно до 3 минут, после чего возвращало `504 WAKE_TIMEOUT`.

**Стало**

Основная фаза ожидания увеличена с ~3 до ~5 минут, а с учётом фазы перезагрузки полный потолок до `504` — около 6.5 минуты. Глубоко «остывший» хост (например, спавшая несколько дней галактика) успевает загрузиться и подключиться, а не получает ложный таймаут. Код ошибки, форма ответа и потолок со стороны прокси прежние.

**Влияние на интеграторов**

Если клиент задаёт собственный таймаут на эти вызовы, заложите около 6.5 минуты вместо 3. Прочее поведение прежнее, переписывать интеграцию не нужно.

### NEW-0624-4: параметры placement и graduateFrom при создании сервера

[POST /v1/infra/servers](/docs/infra/servers/create) получил два необязательных параметра. `placement` — `auto` (по умолчанию, поведение прежнее) или `dedicated`: на портале с моделью размещения `galaxies-only` значение `dedicated` создаёт не приложение Galaxy, а отдельную виртуальную машину, проходя те же проверки, что и обычное создание сервера — политику `serverCreation` и квоту серверов на пользователя. `graduateFrom` принимает идентификатор вашего приложения Galaxy (`kind=GALAXY_APP`): после создания выделенного сервера это приложение удаляется. `graduateFrom` ограничен владельцем — чужой или не-Galaxy идентификатор вернёт `404`, ничего не удаляя.

Это аддитивно: без `placement` или с `placement: "auto"` запрос ведёт себя в точности как раньше.

Кроме того, при OOM-падении приложения Galaxy ответ [POST /v1/infra/servers/:id/deploy](/docs/infra/deploy) с кодом `502 GALAXY_APP_START_FAILED` теперь содержит структурную подсказку `error.hint` с `recoveryAction: "graduate-to-dedicated-vm"` — как пересоздать приложение на выделенном сервере через `placement: "dedicated"` и `graduateFrom`. Подсказка добавляется только когда причина падения — OOM (превышение лимита памяти контейнера), а не обычный краш.

### FIX-0624-5: создание сервера с кодом в source.content принимает архивы до 500 МБ

**Было**

[POST /v1/infra/servers](/docs/infra/servers/create) с inline-архивом в `source.content` (одношаговое создание приложения Galaxy) возвращал `413 FST_ERR_CTP_BODY_TOO_LARGE` уже на архивах больше ~750 КБ, хотя в документации поля `source.content` заявлен лимит 500 МБ на тело запроса. Маршрут наследовал глобальный лимит тела 1 МБ.

**Стало**

Маршрут принимает тело до 500 МБ — как и `POST /v1/infra/servers/:id/deploy` и `POST /v1/infra/servers/:id/upload`. Лимит из документации теперь действует на самом деле.

### NEW-0624-6: группировка реквизитов по ИНН/ОГРН/КПП в aggregate

[POST /v1/requisites/aggregate](/docs/entities/requisites/aggregate) теперь принимает `groupBy` по строковым идентификаторам реквизита: `rqInn`, `rqKpp`, `rqOgrn`, `rqOgrnip`, `rqOkpo`, `rqVatId`, `rqResidenceCountry`, `rqCompanyName`, а также `presetId`, `entityTypeId`, `active`. Раньше группировка по этим полям возвращала `400 INVALID_PARAMS` с пустым списком доступных полей.

Группировка по `rqInn` — самый быстрый способ найти дубли реквизитов одним вызовом: группы с `count > 1` содержат повторяющиеся ИНН. Прежние вызовы (`groupBy` по `entityTypeId`/`presetId`) работают без изменений. Числовые функции (`sum`/`avg`/`min`/`max`) по этим строковым полям по-прежнему недоступны — они только для группировки.

### FIX-0624-7: availableActions спящего сервера показывает wake/start; repair-status сразу `running`

**Было**

Для спящего сервера без туннеля (`SLEEPING` + `blackholeStatus: DISCONNECTED` — обычное состояние остановленного сервера) поле `availableActions` в ответе `422 SERVER_WRONG_STATE` и в `GET /v1/me` (`infra.unhealthyServers`) содержало только `["repair","delete"]` — без очевидного способа поднять сервер. Отдельно: сразу после [POST /v1/infra/servers/:id/repair](/docs/infra/lifecycle/repair) опрос [repair-status](/docs/infra/lifecycle/repair-status) в первые миллисекунды мог вернуть `{status:"idle"}`, и цикл опроса завершался преждевременно.

**Стало**

`availableActions` для любого спящего сервера теперь содержит `["wake","start","repair","delete"]` — оба действия реально принимаются эндпоинтами `/wake` и `/start`. А `repair-status` выставляет `running` синхронно при старте ремонта, поэтому первый же опрос видит `running`, а не `idle`. Прежние вызовы продолжают работать без изменений.

### FIX-0624-8: stage-history?entityType=invoice теперь отдаёт историю смарт-счёта (31)

**Было**

[GET /v1/stage-history](/docs/stage-history)`?entityType=invoice` возвращал историю упразднённого старого счёта (entityTypeId 5, status-based: `statusId`/`statusSemanticId`). Текущий смарт-счёт (31) был доступен только под ключом `entityType=new-invoice`. Клиент, работающий со счетами через `/v1/invoices` (тип 31), запросив историю под `invoice`, получал чужой упразднённый тип.

**Стало**

`entityType=invoice` отдаёт историю текущего смарт-счёта (entityTypeId 31, stage-based: `stageId`/`stageSemanticId`/`categoryId`) — в одном ряду с `/v1/invoices`. Ключ `new-invoice` сохранён как алиас на 31 для обратной совместимости, ломать ничего не нужно.

### NEW-0624-9: эндпоинт эмбеддингов bitrix/embeddings

Появился OpenAI-совместимый эндпоинт [POST /v1/embeddings](/docs/ai/embeddings) — преобразование текста в векторные представления (эмбеддинги) для семантического поиска, кластеризации, дедупликации и поиска похожих карточек CRM. Модель `bitrix/embeddings` бесплатная и платформенная, свой ключ провайдера не требуется. В поле `input` принимается строка или массив строк, ответ возвращается в сыром OpenAI-формате: поле `object` со значением `list`, массив `data` с объектами вида `{ object: "embedding", embedding, index }` и блок `usage`. Поддерживаются необязательные параметры `encoding_format` (`float` или `base64`) и `dimensions`. Список доступных моделей и их возможностей — [GET /v1/models](/docs/ai/models/list), у модели эмбеддингов выставлена возможность `embeddings`.

### FIX-0624-10: типы полей календарных событий приведены к реальным ответам

**Было**

[GET /v1/calendar-events/fields](/docs/entities/calendar-events/fields) объявлял `rrule` как `string`, а `dateCreate` и `updatedAt` — как `datetime`, хотя на чтение `rrule` приходит объектом, а `dateCreate` и `updatedAt` — строкой в формате региональных настроек портала (не ISO 8601). В схеме числилось поле `ownerType`, которого в ответах нет. В объекте `rrule` приходили служебные ключи `~UNTIL` и `UNTIL_TS`, а в элементах списка повторяющихся событий — служебный ключ `RINDEX`.

**Стало**

`/fields` объявляет `rrule` как `object`, а `dateCreate` и `updatedAt` — как `string`. Фантомное поле `ownerType` убрано из схемы. Служебные ключи `~UNTIL`, `UNTIL_TS` и `RINDEX` больше не попадают в ответы.

**Влияние на интеграторов**

Документированные поля не изменились — клиент, читавший только их, продолжает работать. Для абсолютной метки времени используйте `from` и `to` (ISO 8601). Значения `dateCreate` и `updatedAt` не разбирайте фиксированным парсером — их формат зависит от региональных настроек портала.

### NEW-0624-11: поле provisionReason в ответе серверов

[GET /v1/infra/servers](/docs/infra/servers/list) и [GET /v1/infra/servers/:id](/docs/infra/servers/get) теперь возвращают поле provisionReason со значением oom, crash или null — структурный признак причины ошибки galaxy-приложения. Раньше приходилось разбирать свободный текст provisionError. Значение oom — сигнал к «выпуску» приложения на выделенный сервер: создайте сервер с параметрами placement равным dedicated и graduateFrom. Поле необязательное и аддитивное — прежние интеграции работают без изменений.

### FIX-0624-12: graduation-сигнал срабатывает при любой нехватке памяти galaxy-приложения

**Было**

Приложение Galaxy, которому не хватило памяти контейнера — и упёршееся в лимит с перезапусками у предела, и исчерпавшее память сразу на старте (например, грузит большую модель), — классифицировалось как обычный крэш: [GET /v1/infra/servers/:id](/docs/infra/servers/get) возвращал provisionReason crash, а ответ [POST /v1/infra/servers/:id/deploy](/docs/infra/deploy) с 502 GALAXY_APP_START_FAILED шёл без graduation-подсказки. И наоборот, не-OOM краш-луп (необработанное исключение) мог ошибочно помечаться oom.

**Стало**

Реальная нехватка памяти в любой форме — и мгновенная на старте, и постепенный рост до лимита — надёжно даёт provisionReason oom и error.hint с recoveryAction graduate-to-dedicated-vm. Сборочные ошибки и приложения, которые вообще не стартовали (битая команда запуска), остаются crash без graduation.

**Влияние на интеграторов**

Менять ничего не нужно: значение поля и подсказка теперь точнее отражают нехватку памяти. Агент может надёжно ловить provisionReason oom для любого исчерпания памяти и «выпускать» приложение на выделенный сервер.
