# Изменения API: 10 августа 2026

[← Журнал изменений](/docs/changelog) · [Август 2026](/docs/changelog/2026-08)

### NEW-0810-1: выдача ссылки-приглашения отмечается в журнале доступа портала

Ответ [POST /v1/infra/servers/:id/access-tokens](/docs/infra/access-tokens) не изменился — меняется то, что происходит на стороне портала.

**Было**

Выдача ссылки с `mode=share-url` не оставляла следа в надзорном слое портала: администратор не видел, кто и когда открыл приложение ссылкой.

**Стало**

После успешной выдачи ссылки платформа записывает смену открытости в журнал портала, а если ссылка не требует входа в Битрикс24 (`identityBound=false`) и приложение до этого не было открыто наружу — отправляет администраторам портала сообщение в чат-бот со ссылкой на список открытых приложений.

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

Формат запроса, ответа и коды ошибок не изменились — менять клиент не нужно. Учитывайте, что каждая выдача открытой ссылки теперь видима администратору портала.

### BC-0810-2: ошибка фильтра в POST /v1/{entity}/batch стала ошибкой подвызова, а не всего запроса

> Поддержка старого формата до: 04.02.2027

**Было**

Один неверный ключ фильтра в любом подвызове [POST /v1/{entity}/batch](/docs/batch) отменял
весь запрос: ответ `400`, код в `error.code`, результаты остальных подвызовов
отбрасывались. Глобальный [POST /v1/batch](/docs/batch) вёл себя иначе — клал ошибку рядом с
конкретным подвызовом и выполнял остальные.

**Стало**

Обе поверхности ведут себя одинаково. Ответ — `200`, код отказа лежит в `data[i].error.code`
для того подвызова, который его вызвал; остальные подвызовы выполняются и возвращают данные.
Сам набор отказов и их коды не изменились — изменился только радиус: `UNKNOWN_FILTER_FIELD`,
`INVALID_FILTER_OPERATOR`, `INVALID_FILTER_FIELD`, `UNSUPPORTED_FILTER`.

Прежний текст ошибки начинался с `Call at index N:` — теперь позиция подвызова видна по его
месту в массиве `data`, и префикс убран.

**Что делать интеграторам**

Если код читает отказ фильтра как `HTTP 400` с `error.code`, добавьте разбор `200` с
`data[i].error.code` — иначе подвызов, у которого фильтр не принят, будет прочитан как
успешный. Проверяйте наличие `error` у каждого элемента `data`, как это уже делается для
глобального `POST /v1/batch`.

### BC-0810-3: чтение через батч больше не обходит выключенную операцию сущности

> Поддержка старого формата до: 04.02.2027

**Было**

Сущность может выключать отдельную операцию — обычно потому, что универсальный
обработчик для неё неверен: настоящий список живёт на собственном маршруте с другим
конвертом, либо метод Битрикс24 не понимает фильтр и отдаёт таблицу целиком. Одиночные
маршруты это учитывали, запись через батч — тоже, а чтение через батч — нет. Поэтому
[POST /v1/{entity}/batch](/docs/batch) и [POST /v1/batch](/docs/batch) с `action` `list`,
`get`, `search` или `fields` отвечали `200` там, где та же операция на своём маршруте
отвечает `404`
— и отдавали ровно тот результат, ради отказа от которого операцию и выключили.

Отдельно: устаревший `GET /v1/{entity}/aggregate` вообще не спрашивал, есть ли у сущности
агрегация. У сущности, где все числовые поля — идентификаторы, `POST /v1/{entity}/aggregate`
отвечает `404`, а этот адрес отвечал `200`.

**Стало**

Оба батча отвечают на выключенную операцию `400` с кодом `ACTION_NOT_SUPPORTED` до вызова
Битрикс24: в per-entity батче это ответ всего запроса, в глобальном — ошибка конкретного
подвызова (остальные подвызовы выполняются). Устаревший `GET /v1/{entity}/aggregate`
регистрируется по тому же признаку, что и `POST`-версия, поэтому у сущности без агрегации
теперь `404` на обоих адресах.

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

Затронуты только те сущности и операции, где ответ и раньше был неверным. Проверить стоит
все четыре чтения — `list`, `get`, `search`, `fields`: у шести сущностей выключен именно
`search` при работающем `list`, поэтому пачка, которая раньше проходила целиком, теперь
вернёт `ACTION_NOT_SUPPORTED` на этом подвызове. Полный набор действий
сущности — в `operations.batch` ответа `GET /v1/guide` и в описании OpenAPI; `data.batch` в
`GET /v1/{entity}/fields` перечисляет только действия ЗАПИСИ и на вопрос про чтения не отвечает. У сущности, где выключено всё,
маршрут остаётся на месте, но любое действие отвечает `ACTION_NOT_SUPPORTED` — отказ
называет действие, чего `404` на адресе сказать не может.

### BC-0810-4: `filter`, переданный не объектом, отклоняется вместо тихой потери

> Поддержка старого формата до: 04.02.2027

> Как и в соседней записи про неизвестное имя поля, «старый формат» здесь означает неверный
> ответ, а не рабочий.

**Было**

`filter` — объект условий, но передать вместо него строку, число, булево значение или массив
никто не мешал. Строка и массив уходили в Битрикс24 как есть, число и булево превращались в
пустой отбор — и во всех случаях запрос отвечал `200` со ВСЕЙ коллекцией:

```
POST /v1/tasks/search   { "filter": [{ "responsibleId": 1 }] }   →  200, все задачи портала
```

**Стало**

Такой запрос отклоняется до вызова Битрикс24 — `400` с кодом `INVALID_FILTER_SHAPE`; в
сообщении сказано, что именно пришло вместо объекта, и показана правильная форма.

Действует на всех сущностях и на всех поверхностях, где `filter` приходит в теле: поиск,
агрегация и оба батча.

**Что делать интеграторам**

Передавайте `filter` объектом. В строке запроса это отдельная история: там условия пишутся
скобочной формой (`?filter[responsibleId]=1`), а `filter`, закодированный в JSON одной
строкой, с этой же поставки не отклоняется, а разбирается и применяется — раньше он молча
терялся и возвращал всю коллекцию.

### BC-0810-5: неизвестное имя поля в фильтре отклоняется ещё на пятнадцати сущностях

> Поддержка старого формата до: 04.02.2027

> До сих пор такой фильтр отвечал `200` и всей коллекцией — то есть «старый формат» здесь
> означает неверный ответ, а не рабочий.

**Было**

Фильтр по имени, которого у сущности нет, уходил в Битрикс24. Битрикс24 такой ключ не
отклоняет — он молча его выбрасывает и отвечает `200` со ВСЕЙ коллекцией. Опечатка в имени
поля поэтому выглядела как успешный запрос с неправдоподобно большим результатом:

```
GET /v1/tasks?filter[responsable]=1     →  200, все задачи портала
```

Так вели себя [задачи](/docs/entities/tasks/list), [пользователи](/docs/entities/users/list),
[рабочие группы](/docs/entities/workgroups/list), [реквизиты](/docs/entities/requisites/list),
[банковские реквизиты](/docs/entities/bank-details/list),
[шаблоны реквизитов](/docs/entities/requisite-presets/list),
[адреса](/docs/entities/addresses/list), [сайты](/docs/entities/sites/list),
[страницы](/docs/entities/pages/list), [комментарии таймлайна](/docs/entities/timelines/list),
[шаблоны бизнес-процессов](/docs/entities/bizproc-templates/list), настройки открытых линий и
элементы универсальных списков.

**Стало**

Такой запрос отклоняется до вызова Битрикс24 — `400` с кодом `UNKNOWN_FILTER_FIELD` и списком
доступных имён в сообщении — этот список и есть точный ответ на вопрос «по чему можно
фильтровать».

Проверяется только имя: операторы, диапазоны, `$in`/`$nin` и логика И работают как раньше.
Кроме объявленных полей принимаются пользовательские поля (`UF_*`, `ufCrm*`) и — у сущностей,
где он объявлен, — ключ `id`.

Отдельно: у [действий](/docs/entities/bizproc-activities/list) и
[роботов бизнес-процессов](/docs/entities/bizproc-robots/list) метод Битрикс24 не принимает
фильтр ни в каком виде, поэтому там отклоняется любой ключ фильтра — код `UNSUPPORTED_FILTER`.

Полное описание — [Фильтрация и поиск](/docs/filtering#неизвестное-имя-поля-в-фильтре).

**Что делать интеграторам**

Сверьте имена полей в своих фильтрах со списком из сообщения об ошибке. Запрос, который
раньше «работал», но возвращал больше записей, чем должен был, теперь ответит `400` с точным
указанием, какое имя не найдено — это и есть его исходная ошибка. Остальные фильтры не
затронуты.

### FIX-0810-6: нехватка места на общем хосте — отдельный повторяемый отказ деплоя, а не поломка приложения

**Было**

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

**Стало**

Тот же случай возвращает `502 GALAXY_LOW_DISK` с признаком `retryable: true` и структурированным полем `error.hint`: причина, что сделать и предупреждение не удалять слот. Приложение не помечается сломанным — слот, контейнер и его том с данными целы, а уже работающая версия обслуживает трафик дальше. Повторять деплой имеет смысл после того, как на хосте освободили место: само оно не освобождается, поэтому немедленный повтор упирается в тот же отказ. Новый код перечислен в машинном описании контракта деплоя, которое отдают [GET /v1/me](/docs/quickstart) и `GET /v1/openapi.json`.

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

Менять ничего не нужно: успешные деплои не затронуты. Ветку на `GALAXY_APP_BUILD_FAILED` оставьте — она по-прежнему приходит на настоящих ошибках сборки, а у нехватки места теперь есть отдельный код, по которому видно, что дело не в исходниках. Автоматический повтор бывает только там, где платформа сама пересобирает уже существующее приложение: там попытки идут без участия клиента, пока не истечёт отведённый на ожидание бюджет. При создании приложения сразу с исходниками отказ приходит сразу и не повторяется — решение о повторе остаётся за вами.

### FIX-0810-7: Открытие из каталога Битрикс24 предупреждает, что приложение не авторизовано

**Было**

Приложение, открытое из каталога Битрикс24 пользователем, который ещё не выдал ему доступ, запускалось как обычно, но шлюз не проставлял заголовок `X-Vibe-Authorization`. Вызовы к API отвечали `401`, и приложение показывало текст, который наша же документация предписывала для `401`, — «откройте приложение из меню Битрикс24». Совет был тупиковым: пользователь именно так и открыл, а открытие из каталога доступ не выдаёт.

**Стало**

Такой запуск платформа перехватывает и показывает экран с кнопкой «Авторизовать приложение»; второй путь — один раз открыть приложение через встройку в меню Битрикс24. Там же есть неприметная ссылка «открыть без авторизации» на тот же адрес запуска — приложение, которому сессия не нужна, открывается как прежде. Экран показывается только там, где кнопке есть куда вести: облачный портал, ключ приложения и зарегистрированное OAuth-приложение. Во всех остальных случаях запуск идёт как раньше.

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

Менять код не нужно, и ни один запуск не становится недоступным. Стоит поправить только текст своей ошибки на `401`: у неё две причины — истёкшая сессия и не выданный доступ, — поэтому «откройте из меню» как единственная формулировка вводит пользователя в заблуждение. Рекомендация обновлена в разделе [Среда выполнения приложения](/docs/infra/app-runtime).

### NEW-0810-8: список документов CRM появился в машинной схеме OpenAPI

Эндпоинт [GET /v1/crm-documents](/docs/entities/documents/crm-list) теперь описан в схеме OpenAPI, которую отдаёт `/v1/openapi.json`. Сам вызов работал и раньше, но клиенты и ИИ-агенты, которые строят интеграцию по машинному описанию, считали его несуществующим. В описании указаны обязательный параметр `entityTypeId`, необязательные `entityId`, `select`, `order` и `start`, требуемый доступ `crm`, форма ответа с массивом документов и блоком `meta` с полями `total`, `start` и `next`, а также коды отказа `MISSING_PARAMS`, `INVALID_ENTITY_ID`, `INVALID_START`, `TOKEN_MISSING` и `SCOPE_DENIED`. Параметр размера страницы эндпоинт не принимает и в описании его нет: за следующей страницей идут со значением `meta.next` в `start`. Поведение самого эндпоинта не изменилось.

### FIX-0810-9: при входе по прямой ссылке приложение получает имя и токен посетителя

**Было**

Приложение, открытое по прямой ссылке на свой адрес (а не плиткой из Битрикс24), получало имя посетителя из его учётной записи на платформе Вайбкод, а не из карточки сотрудника: участник нескольких Битрикс24 видел имя, под которым он записан в другом из них. Заголовок `X-Vibe-Authorization` на этом пути не приходил вовсе — приложение не могло обратиться в Битрикс24 от лица посетителя.

**Стало**

`X-Vibe-User-Name` и `X-Vibe-User-Name-Encoded` несут имя из карточки сотрудника того Битрикс24, которому принадлежит приложение — как и при открытии плиткой. Токен доступа `X-Vibe-Authorization` резолвится по номеру сотрудника, поэтому приходит и здесь.

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

Формат заголовков не изменился, менять клиент не нужно. Если карточку сотрудника прочитать не удалось, имя остаётся прежним, из учётной записи на платформе Вайбкод: пустым заголовок не приходит.

### FIX-0810-10: пользовательские поля счёта

**Было**

Пользовательские поля счёта нельзя было прочитать или создать ни одним путём.
[GET /v1/userfields/invoices](/docs/userfields/smart-processes) отвечал ошибкой `UNKNOWN_ENTITY`, а
[GET /v1/items/31/userfields](/docs/userfields/smart-processes) — ошибкой доступа от Битрикс24,
потому что счёт адресовался так же, как обычный смарт-процесс.

**Стало**

Оба пути работают и дают одинаковый результат: шесть операций (список, справочник типов,
чтение, создание, изменение, удаление) над пользовательскими полями счёта. Путь
`/v1/userfields/invoices` добавлен для тех, кому удобнее обращаться по имени сущности, а не по
числовому идентификатору типа.

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

Менять ничего не нужно. Речь идёт о счетах в текущем виде; счета старого образца через API
по-прежнему недоступны.

### BC-0810-11: Справочник полей товарных позиций описывает то, что реально приходит в ответах

> Поддержка старого формата до: не предусмотрена

**Было**

[GET /v1/deals/{id}/products/fields](/docs/entities/deals/products-fields) отдавал набор полей Битрикс24 как есть, и он расходился с ответами самих товарных позиций сразу в трёх местах. Сумма скидки называлась в справочнике `discountSum`, а в данных и при записи — `discount`. Внешний код позиции и цена в валюте отчёта приходили в каждой строке, но в справочнике отсутствовали. Владелец строки, тип владельца и склад, наоборот, были в справочнике, но из ответов вырезались.

Хуже того, клиент, сгенерировавший запись по этому справочнику, отправлял `discountSum` — обёртка это имя не распознавала, отвечала `201 Создано` и молча выбрасывала скидку. То же происходило с любым другим неизвестным полем: ответ об успехе, данные не записаны.

**Стало**

Справочник собирается из тех же таблиц, по которым формируются сами ответы, поэтому разъехаться они больше не могут. Скидка называется `discount` — как в данных, при записи и в документации. Прежнее имя `discountSum` при этом никуда не делось: оно осталось устаревшим псевдонимом, по-прежнему приходит в справочнике и по-прежнему принимается при записи, поэтому код, написанный по старому списку полей, продолжает работать — с той разницей, что скидка теперь действительно записывается, а не теряется молча. В самих товарных позициях приходит только `discount`. Добавлены `priceAccount` и `xmlId`, которые Битрикс24 возвращает в строках, но в своём справочнике не описывает. Поля `ownerId`, `ownerType` и `storeId` теперь приходят в ответах [списка](/docs/entities/deals/products-get) и [одной позиции](/docs/entities/deals/products-get-single); `storeId` равен `null`, если складской учёт выключен.

Признаки `isReadOnly` и `isRequired` описывают контракт этого API, а не контракт Битрикс24: `ownerId`, `ownerType`, `customized` и `measureName` помечены только для чтения (записать их через обёртку нельзя), а у `ownerId` и `ownerType` снят признак обязательности — они берутся из адреса запроса. У `id` появилось пояснение: как атрибут он только для чтения, а в элементах [PUT /products](/docs/entities/deals/products-set) он принимается. **Уточнение 18.08.2026:** живая проверка показала, что возврат `id` идентичность строки не сохраняет — позиция, поля которой не изменились, сохраняет свой `id` и без `id` в теле, а изменённая приходит с новым `id`. Правка позиции с сохранением идентификатора идёт через `PATCH /v1/deals/:id/products/:rowId`.

Запись с неизвестным именем поля больше не отвечает успехом: [POST](/docs/entities/deals/products-add), [PUT](/docs/entities/deals/products-set) и [PATCH](/docs/entities/deals/products-update) возвращают `400 INVALID_PARAMS` и перечисляют записываемые поля. Поля только для чтения по-прежнему принимаются и игнорируются, поэтому объект, прочитанный через GET, можно отправить обратно без чистки.

Поле `id` в теле принимается только в элементах [PUT /products](/docs/entities/deals/products-set). При [создании](/docs/entities/deals/products-add) и [правке](/docs/entities/deals/products-update) оно отбрасывается: строку там задаёт адрес запроса, а тело с `id` уже существующей строки — ровно то, что получается, если отправить обратно объект, прочитанный через GET.

Признак `taxIncluded` при записи снова принимается булевым: `true` и `false` уходят в Битрикс24 как `Y` и `N`. Раньше булево значение отправлялось как есть, и налог по строке фактически оставался незаданным — то есть строка, прочитанная через GET и отправленная обратно, теряла этот признак. Кто обходил это, посылая `"Y"` и `"N"` строками, ничего не заметит: такая форма принимается по-прежнему.

Если Битрикс24 отдал неполные метаданные, справочник всё равно приходит полным, но ответ дополняется предупреждением `meta.warnings[].code = "fields_partial"` — раньше такой ответ был неотличим от нормального. Текст предупреждения различает два случая: метаданных не пришло вовсе или не описана только часть полей (тогда он их перечисляет).

**Что делать интеграторам**

**Ломается запись с посторонним ключом в теле.** Проверьте, что при создании и правке товарной позиции вы не отправляете ничего сверх записываемых полей: своих служебных пометок, остатков внутренней модели, имён Битрикс24 в верхнем регистре (`PRICE_ACCOUNT`, `XML_ID`). Раньше такой запрос отвечал `201 Создано` и молча выбрасывал значение — теперь он отвечает `400 INVALID_PARAMS` и перечисляет, что принимается. Окна поддержки у прежнего поведения нет намеренно: оно и было дефектом, из-за которого заявку завели, а держать его параллельно значит держать тихую потерю данных. Полный список записываемых полей приходит в ответе на отказ и в [справочнике полей](/docs/entities/deals/products-fields).

Остальное менять не нужно. `discountSum` продолжает и приходить, и приниматься — перейти на `discount` можно без спешки, это имя приходит в самих товарных позициях, тогда как псевдоним живёт только в справочнике. Ветвитесь на `isReadOnly` или `isRequired` — сверьтесь с новыми значениями у `ownerId`, `ownerType`, `customized` и `measureName`. Заменяете строки целиком — учтите, что идентификаторы изменённых позиций меняются: перечитайте набор через GET после записи.

### FIX-0810-12: подбор сотрудников по серверу больше не пустует из-за свежего ключа без доступа к Bitrix24

**Было**

Когда управляющий ключ сервера не давал доступа к Bitrix24, `GET /v1/infra/servers/{id}/b24-users`
и подбор сотрудников в интерфейсе переходили к личным ключам владельца сервера, но проверяли
только один — самый свежий подходящий. Если у него не было ни вебхука, ни токена установленного
приложения, ответ приходил пустым (`data: []` с подсказкой), хотя у владельца был другой активный
ключ с нужными правами. Ключи, которые платформа выпускает сама под задачи без обращений к
Bitrix24, всегда оказываются самыми свежими, поэтому подбор мог не работать постоянно.

**Стало**

Проверяются все подходящие личные ключи владельца, от свежего к старому, и используется первый,
для которого действительно есть доступ к Bitrix24. Ключи без доступа пропускаются, к Bitrix24
по-прежнему уходит один запрос. Требования к ключу не смягчены: как и раньше, годится только
активный неистёкший личный ключ владельца сервера в том же портале, не привязанный к приложению.

Заодно исправлена подсказка в поле `hint`: раньше она называла только неавторизованное приложение
и отозванный ключ, из-за чего активный ключ выглядел отозванным. Теперь третьей причиной названо
отсутствие доступа к Bitrix24 у ключей и подсказано действие — выпустить личный ключ с нужными
правами. Форма ответа не изменилась.

### FIX-0810-13: привязка места встраивания называет отказ в правах установки вместо общей ошибки шлюза

**Было**

Битрикс24 отказывал в установке встройки, и проверить состояние подписки в этот момент не удавалось — [POST /v1/placements/bind](/docs/apps/placements/bind) отвечал `502 BITRIX_UNAVAILABLE` и складывал код Битрикс24 в `details`. Названного кода в ответе не было, а вместе с ним и подсказки, что делать дальше. Отказ приходил и на аккаунт с оформленной подпиской.

**Стало**

Когда проверку выполнить не удалось, а аккаунт уже числится подписанным в Вайбкод, тот же отказ приходит как `403 B24_EMBEDDING_INSTALL_DENIED` с `details.remedy` равным `install-rights`. Ссылка на оформление не передаётся: подписка есть, не хватает права ставить локальные приложения. Если действующей подписки нет ни по одному из источников, ответ остаётся `502 BITRIX_UNAVAILABLE`.

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

Менять ничего не нужно. Ветка обработки `502 BITRIX_UNAVAILABLE` продолжает работать для остальных отказов, а этот сценарий уходит из неё в `403`. Повторять запрос в нём бессмысленно — нужно, чтобы ключ разработчика принадлежал пользователю с правом ставить локальные приложения и с доступом к приложению.

### BC-0810-14: команды, выкладка и загрузка файлов по id машины-галактики больше не выполняются

> Поддержка старого формата до: 07.08.2026

**Было**

Галактика — это одна машина, на которой в контейнерах живут приложения нескольких ключей одного аккаунта Битрикс24. Список серверов отдаёт как сами приложения (`kind=GALAXY_APP`), так и несущую их машину (`kind=GALAXY`), и вызов [POST /v1/infra/servers/:id/exec](/docs/infra/deploy/exec), [POST /v1/infra/servers/:id/deploy](/docs/infra/deploy/deploy) или [POST /v1/infra/servers/:id/upload](/docs/infra/deploy/upload) с id несущей машины выполнялся на ней самой — то есть за пределами контейнера вызывающего.

**Стало**

Тот же вызов с id машины вида `GALAXY` отвечает отказом: команды — `403 GALAXY_HOST_EXEC_FORBIDDEN`, выкладка и загрузка файлов — `400 GALAXY_HOST_NOT_A_DEPLOY_TARGET`. Текст отказа называет замену: работать с приложением по его собственному id (`kind=GALAXY_APP`). Для машин вида `STANDALONE` и для приложений галактики ничего не изменилось.

**Что делать интеграторам**

Возьмите из списка серверов строку своего приложения (`kind=GALAXY_APP`) и обращайтесь по её id. Если сценарий опирался на доступ к самой машине ради свободного места, эта величина теперь доступна как данные, а не как результат команды.

Окна поддержки прежнего поведения нет: отказ действует с момента выката. Причина в том, что прежнее поведение открывало доступ к машине, на которой стоят контейнеры других ключей, — держать такой доступ полгода ради совместимости нельзя.

### NEW-0810-15: занятость диска машины-галактики видна в списке серверов

Строка машины-галактики (`kind=GALAXY`) в [GET /v1/infra/servers](/docs/infra/servers/list) и в карточке сервера теперь несёт четыре поля: `diskTotalMb` и `diskFreeMb` — размер и свободное место в мебибайтах, `diskState` — оценка (`ok`, `warning`, `critical` или `unknown`, если замера ещё не было), `diskProbedAt` — время замера в ISO-8601.

Обе границы оценки платформа держит с запасом: `warning` означает «место кончается», `critical` — что свободного места меньше, чем платформа считает безопасным; обе зажигаются раньше, чем выкладке действительно перестанет хватать места. Замер обновляется сам, пока машина не спит; у спящей показывается последнее известное значение вместе с его временем.

Для машин вида `STANDALONE` и для приложений галактики (`kind=GALAXY_APP`) все четыре поля равны `null`: у первых диск не измеряется, у вторых своего диска нет.

### NEW-0810-16: агентская модель bitrix/bitrixgpt-5.6-agent

[GET /v1/models](/docs/ai/models/list) отдаёт новую агентскую модель `bitrix/bitrixgpt-5.6-agent` с контекстом 1 048 576 токенов. Модель поддерживает потоковую выдачу, вызов инструментов (`tools`) и структурированный ответ по схеме — `response_format` с `type: "json_schema"`. Публичный идентификатор модели входит в список `ai.structuredOutputs.models` в ответе [GET /v1/me](/docs/keys-auth/me).

Модель добавлена в каталог и ничего не заменяет: прежние вызовы работают без изменений.

**Затронутые эндпоинты:** [GET /v1/models](/docs/ai/models/list), [POST /v1/chat/completions](/docs/ai/chat/completions), [GET /v1/me](/docs/keys-auth/me)

### NEW-0810-17: bitrix/bitrixgpt-5.5-agent помечена устаревшей

Ответы [POST /v1/chat/completions](/docs/ai/chat/completions) на модели `bitrix/bitrixgpt-5.5-agent` теперь несут заголовки `Deprecation: true`, `X-Model-Replacement: bitrix/bitrixgpt-5.6-agent` и `Link` со ссылкой на преемника (`rel="successor-version"`).

Модель продолжает работать без ограничений и остаётся в выдаче [GET /v1/models](/docs/ai/models/list). Дата отключения не назначена — заголовок `Sunset` не отдаётся, и менять в интеграции ничего не требуется. Преемник для новых интеграций — `bitrix/bitrixgpt-5.6-agent`.

### FIX-0810-18: временный сбой транзакции базы больше не отдаёт 500 с внутренним кодом движка

**Было**

Если транзакция в базе закрывалась или истекала до конца операции, запрос отвечал `500` и клал в тело внутренний код движка — `{"error":{"code":"P2028"}}`. Кода нет ни на одной странице документации, заголовка `Retry-After` в ответе не было, и по ответу нельзя было понять, что запрос стоит повторить. Чаще всего это видели на `DELETE /v1/apps/{id}`: приложение оставалось на месте, а повтор выглядел бессмысленным.

**Стало**

Тот же класс отказа отвечает `503` с кодом `DB_TRANSIENT`, полем `error.retryAfter` и заголовком `Retry-After` — та же посадка на повтор, что у `POOL_EXHAUSTED`. Изменение при таком отказе не применяется ни частично, ни полностью, поэтому прямой повтор через несколько секунд безопасен. На маршрутах AI (`/v1/ai/*`, `/v1/chat/*`, `/v1/audio/*`, `/v1/models`) код приходит в нижнем регистре — `db_transient` — в конверте, совместимом с OpenAI. Внутренний код движка в теле ответа больше не встречается.

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

Менять ничего не нужно. Если ваш обработчик считал `500` окончательным отказом — теперь этот случай приходит как `503` с указанным сроком и попадает в вашу ветку повторов. Отдельная обработка кода `DB_TRANSIENT` не требуется: достаточно уважать `Retry-After` на любом `503`.

### FIX-0810-19: preserveEnv не теряет .env, если выкладка упала после очистки каталога

**Было**

При `cleanDeploy: true` вместе с `preserveEnv: true` существующий `.env` читался до очистки
каталога, но записывался обратно только на шаге `env` — уже после установки рантайма и
зависимостей. Если выкладка обрывалась раньше, [POST /v1/infra/servers/:id/deploy](/docs/infra/deploy/deploy)
отвечал `DEPLOY_FAILED`, а каталог оставался без `.env` совсем. Настройки приложения
приходилось заливать заново.

**Стало**

Сохранённая копия возвращается на диск при любом обрыве выкладки после очистки — на установке
зависимостей, на рантайме, на загрузке архива, на самой очистке, а также при разрыве связи с
сервером. Восстановление идёт по мере возможности и не добавляет отдельного шага в ответ.
Правило приоритета не изменилось: переданный в этом же запросе `env` по-прежнему побеждает, а
явный пустой `env: {}` означает «очистить» и сохранённую копию не возвращает. Успешная выкладка
работает как раньше, включая подстановку часового пояса для расписаний пробуждения. Флаг
по-прежнему только для отдельной виртуальной машины (`kind: "STANDALONE"`).

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

Менять на своей стороне ничего не нужно. Форма ответа `DEPLOY_FAILED` и набор шагов в
`data.steps` не изменились. Если вы обходили этот дефект — заливали `.env` вручную после каждой
неудачной выкладки — обходной путь больше не нужен.
