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

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

### NEW-0702-1: фильтр и сортировка задач по реальному статусу (realStatus)

`GET /v1/tasks`, `POST /v1/tasks/search` и `POST /v1/tasks/aggregate` теперь принимают поле `realStatus` в `filter` (а список и поиск — ещё и в `sort`) — фильтрация по фактически сохранённому статусу задачи: 1 — новая, 2 — ждёт выполнения, 3 — выполняется, 4 — ожидает контроля, 5 — завершена, 6 — отложена, 7 — отклонена. Раньше `filter[realStatus]` молча игнорировался и запрос возвращал весь набор.

В отличие от `filter[status]`, который на стороне Bitrix24 работает как виртуальный (мета-)фильтр (значения −1 просрочена, −2 не просмотрена, −3 почти просрочена) и не совпадает со значением поля `status` в ответе, `realStatus` фильтрует именно по хранимому статусу. Поле доступно только для чтения (статус меняется через `status`) и участвует только в `filter`/`sort` — в ответе реальный статус задачи уже отдаётся в поле `status`.

### FIX-0702-2: создание приложения переиспользует упавший одноимённый слот

**Было**

Повторный [POST /v1/infra/servers](/docs/infra/servers/create) с тем же `name` после неудачного деплоя создавал новый слот приложения. Упавшие слоты накапливались и удалялись автоочисткой только через 7 дней.

**Стало**

Если у владельца ключа на портале уже есть слот с тем же `name` в статусе `error` (или созданный, но так и не получивший ни одного деплоя), повторный вызов возвращает этот же слот: его `id` сохраняется, ошибка и лог сборки сбрасываются, статус возвращается в `provisioning` — деплойте в него. Слоты, в которые ни разу не отправляли код, теперь удаляются автоочисткой через 24 часа вместо 7 дней (слоты с упавшей сборкой по-прежнему хранятся 7 дней вместе с логом сборки).

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

Изменений в запросах не требуется. Если ваш сценарий пересоздавал слот с тем же именем после ошибки, вы начнёте получать прежний `id` вместо нового — это ожидаемо: деплой в возвращённый слот работает как обычно. Слоты других пользователей портала и работающие приложения под переиспользование не попадают.

### FIX-0702-3: ключи «только чтение» больше не пишут через /v1/bots

**Было**

Ключ API в режиме «только чтение» (`accessMode: READONLY`) мог выполнять операции записи через эндпоинты бота ([POST /v1/bots](/docs/bots/management/create), отправка и удаление сообщений, добавление участников в чат, регистрация и удаление бота и другие) — вызов возвращал 200 вместо 403. Остальные проксирующие поверхности Битрикс24 такие записи уже блокировали.

**Стало**

Запись через `/v1/bots/*` ключом «только чтение» возвращает 403 с кодом `WRITE_BLOCKED_READONLY_KEY`. Операции чтения не затронуты, включая получение контекста сообщения ([GET /v1/bots/:botId/messages/:messageId/context](/docs/bots/messages/context)) и скачивание файла ([GET /v1/bots/:botId/files/:fileId](/docs/bots/files/download)).

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

Если бот-интеграции нужна запись — переключите ключ в режим «чтение и запись» в разделе /keys.

### FIX-0702-4: include=storage у папок теперь резолвится

**Было**

`GET /v1/folders/:id?include=storage` (и список `GET /v1/folders?parentId=...&include=storage`) не добавляли `_included` в ответ, хотя `GET /v1/folders/fields` объявляет для связи `storage` признак `includable: true`.

**Стало**

Связанное хранилище резолвится: в ответе появляется `_included.storage` с карточкой хранилища, найденной по `storageId`. Связь описана в [GET /v1/folders/fields](/docs/entities/folders/fields).

### FIX-0702-5: PAGE_BACKGROUND_WORKER: привязка больше не падает с 500

**Было**

`POST /v1/placements/bind` для placement `PAGE_BACKGROUND_WORKER` подставлял обязательный для Битрикс24 параметр `options.errorHandlerUrl` только когда вызов шёл через OAuth-сессию. Если приложение привязывалось по ключу разработчика или на коробочном портале, параметр не добавлялся и Битрикс24 отвечал 500 (`BITRIX_UNAVAILABLE`, «Field errorHandlerUrl is empty»), хотя остальные placement привязывались нормально.

**Стало**

Для `PAGE_BACKGROUND_WORKER` значение `options.errorHandlerUrl` по умолчанию подставляется равным `handler` независимо от способа привязки. Явно переданный `options.errorHandlerUrl` по-прежнему имеет приоритет. В ответе поле `options` теперь отражает применённое значение (с подставленным `errorHandlerUrl`).

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

Действий не требуется — вызов, который раньше возвращал 500, теперь проходит.

### FIX-0702-6: POST /search сообщает об отсутствии обязательных параметров чистой ошибкой

**Было**

`POST /v1/{entity}/search` для сущностей, чей метод списка Битрикс24 требует обязательные параметры, при их отсутствии не проверял этого и передавал запрос в Битрикс24 как есть. Наружу утекала сырая ошибка Битрикс24 (`BITRIX_ERROR`, например «Invalid value of parameter [ `$id` ]» или «Не задан обязательный параметр `type`»), тогда как у эквивалентного `GET`-списка та же ситуация давала понятный `400 MISSING_REQUIRED_PARAMS`. Затрагивало [POST /v1/calendar-events/search](/docs/entities/calendar-events/search) (нужен `type`), [POST /v1/files/search](/docs/entities/files) (нужен `folderId`) и [POST /v1/folders/search](/docs/entities/folders) (нужен `parentId`).

**Стало**

`POST /v1/{entity}/search` проверяет обязательные параметры до вызова Битрикс24 — так же, как это давно делает `GET`-список. При отсутствии параметра приходит `400` с кодом `MISSING_REQUIRED_PARAMS` и перечнем недостающих полей, без обращения к Битрикс24. Обязательный параметр можно передать в `filter`, а параметр-родитель (`folderId` для файлов, `parentId` для папок) — также на верхнем уровне тела запроса.

### NEW-0702-7: Цена research в самоописании ключа и сумма к пополнению в ответе 402

[GET /v1/me](/docs/keys-auth) теперь отдаёт `cost` у каждого провайдера в блоке `webResearch.providers[]` — по образцу блока `webSearch`. Поле несёт цену режима research в Ꝟ (`cost.research`) и валюту (`cost.currency`), так что агент видит стоимость глубокого поиска прямо в самоописании ключа, без отдельного вызова.

Ответ `402` при недостатке средств (`INSUFFICIENT_BALANCE`, а также `BILLING_FROZEN`) на [POST /v1/search](/docs/search/run) и [POST /v1/research](/docs/search/research) теперь содержит поле `required` — сумму в Ꝟ, необходимую для запроса. Прежние поля `userMessage` и `hint` не изменились.

Клиентам со строгой валидацией схемы по `additionalProperties` нужно учесть новые поля ответа.

### NEW-0702-8: POST /v1/triggers/fire поддерживает счета (SmartInvoice)

Эндпоинт [POST /v1/triggers/fire](/docs/automation/triggers/fire) принимает новое значение `entityType` — `invoice`. Передайте `entityType: "invoice"` и `entityId` счёта (его выдаёт [GET /v1/invoices](/docs/entities/invoices)), чтобы запустить триггер автоматизации по смарт-счёту. Прежние значения (`deal`, `lead`, `contact`, `company`, `quote`, `item`) работают как раньше.

Раньше запустить триггер по счёту было нельзя, а попытка через `entityType="item"` с `entityTypeId=31` отклонялась сообщением, которое уводило в тупик. Теперь `item` с зарезервированным `entityTypeId` (в том числе 31) подсказывает перейти на соответствующий `entityType` — для счёта это `invoice`.

### NEW-0702-9: GET /v1/ai/usage отдаёт длительность аудио по моделям транскрибации

[GET /v1/ai/usage](/docs/ai/consumption/usage) в блоке `byModel[]` теперь возвращает поле `audioSeconds` — суммарное количество секунд аудио, переданных на транскрибацию по каждой модели за выбранный период. Поле заполняется для вызовов speech-to-text (Whisper) и равно `0` для текстовых моделей, где длительность аудио неприменима.

Поле аддитивное, существующие интеграции продолжают работать без изменений.

### BC-0702-10: categories: code и isDefault помечены read-only (были phantom-writable)

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

**Было**

`GET /v1/categories/:entityTypeId/fields` объявлял `code` и `isDefault` записываемыми (`readonly: false`), но запись этих полей в `crm.category.add`/`update` молча игнорировалась (значения не сохранялись, ответ `200`).

**Стало**

Оба поля помечены `readonly: true`. `/fields` теперь честно показывает их как read-only, а попытка записать `code` или `isDefault` возвращает `400 READONLY_FIELD` вместо тихой потери данных.

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

Раньше передача `code`/`isDefault` в теле `POST`/`PATCH` `/v1/categories/:entityTypeId` принималась (`200`, значения молча игнорировались). Теперь такой запрос возвращает `400 READONLY_FIELD`. Уберите `code` и `isDefault` из тела запросов create/update категорий — на запись эти поля больше не принимаются.

### BC-0702-11: telephony-lines: поле crmAutoCreate нормализовано в boolean и появилось в /fields

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

**Было**

`GET /v1/telephony-lines/fields` отдавал только `number`, `serverName`, `name`. Поле автосоздания CRM протекало в ответах списка сырым UPPER-именем `CRM_AUTO_CREATE` строкой `"Y"`/`"N"` — единственное UPPER-поле среди camelCase, и его не было в `/fields`. На запись camelCase `crmAutoCreate` молча отбрасывался.

**Стало**

Поле объявлено как `crmAutoCreate` (boolean). Теперь оно присутствует в `/fields`, в ответах `list` приходит нормализованным (`true`/`false`) вместо сырого `"Y"`/`"N"`, а на `create`/`update` принимается camelCase boolean (сырое UPPER-имя ещё принимается на запись для совместимости). Клиенты, читавшие `data[].CRM_AUTO_CREATE`, должны перейти на `data[].crmAutoCreate` (boolean).

### NEW-0702-12: workgroups: раскрыта операция aggregate и groupBy по полям

**Было**

`POST /v1/workgroups/aggregate` работал, но нигде не был заявлен: операции не было в машинном индексе `/v1/guide`, а `groupBy` возвращал `400` на любом поле (`Available: .`), потому что список агрегируемых полей был пуст.

**Стало**

Объявлен список агрегируемых полей: `membersCount` (числовые sum/avg/min/max) плюс категориальные `active`, `isProject`, `ownerId` для группировок. Теперь операция видна в `/v1/guide` и `/fields`, а `groupBy` по этим полям работает.

### FIX-0702-13: /fields: полнота метаданных у doc-templates и bookings

**Было**

`GET /v1/doc-templates/fields` не содержал полей `isDefault` и `productsTableVariant`, хотя они приходят в ответах списка. У `GET /v1/bookings/fields` обязательные `resourceIds` и `datePeriod` не были помечены `required`, поэтому их обязательность не была видна в схеме.

**Стало**

`doc-templates`: объявлены `isDefault` и `productsTableVariant` (только чтение) — теперь состав `/fields` совпадает с ответами. `bookings`: `resourceIds` и `datePeriod` помечены `required: true`, обязательность видна в `/fields`.

### FIX-0702-14: orders: /fields синхронизирован с ответом, убран псевдо-ключ order, companyId фильтруется

**Было**

`GET /v1/orders/fields` содержал лишний псевдо-ключ `order` (артефакт разбора `sale.order.getFields`) и не содержал полей, реально приходящих в ответах: `companyId`, `clients`, `dateMarked`, `personTypeXmlId`, `statusXmlId`, `version`. Из-за отсутствия `companyId` в схеме фильтр по нему падал с `UNKNOWN_FILTER_FIELD`.

**Стало**

Состав `/fields` теперь собирается из схемы: псевдо-ключ `order` убран, объявлены шесть недостающих полей (`companyId` — записываемое число; `clients` — объект, только чтение, приходит в `get`; `dateMarked`/`personTypeXmlId`/`statusXmlId`/`version` — только чтение). Фильтр и сортировка по `companyId` теперь работают.

### FIX-0702-15: users: limit > 50 теперь работает, meta.hasMore честный

**Было**

`GET /v1/users?limit=500` возвращал только 50 записей, хотя `meta.total` показывал больше. `meta.hasMore` всегда был `false` — документированная пагинация по `hasMore` молча теряла данные за первой страницей.

**Стало**

Многостраничная загрузка у этой сущности не включалась. Теперь при `limit > 50` записи догружаются постранично через `start`, а `meta.hasMore` отражает реальное наличие следующих записей.

### FIX-0702-16: POST /v1/batch отклоняет отключённые операции записи и прокидывает обязательные параметры списка

**Было**

Глобальный [POST /v1/batch](/docs/batch) с действием create, update или delete для сущности, у которой эта операция отключена (например openline-configs — запись вынесена в отдельные роуты), выполнял вызов напрямую в Bitrix24 в обход нормализации и мог тихо создать или изменить запись. Отдельно: действие list или search для сущности с обязательными параметрами метода (например calendar-events — type и ownerId) возвращало AUTO_PAGINATION_FAILED «missing required parameter», хотя прямой запрос списка с теми же параметрами работал. Кроме того, batch-list для folders и files отправлял родительскую папку под именем parentId или folderId, которое метод disk.folder.getchildren игнорирует, поэтому список тихо возвращался не по той папке; а batch-list для calendar-events с лишним ключом filter молча прокидывал его в Bitrix24, и метод возвращал весь календарь без ошибки.

**Стало**

Отключённая операция записи в под-вызове отклоняется с кодом ACTION_NOT_SUPPORTED до обращения к Bitrix24 — так же, как в POST /v1/{entity}/batch. Обязательные параметры списка и параметры верхнего уровня метода прокидываются в Bitrix24 с исходными именами, поэтому batch-list работает так же, как прямой список, а при их отсутствии возвращается понятный MISSING_REQUIRED_PARAMS вместо сырой ошибки Bitrix24. Для folders и files родительская папка приводится к имени id, которого ждёт метод, поэтому batch-list возвращается по нужной папке. Для сущностей, у метода которых нет конверта filter (calendar-events), лишний ключ filter теперь отклоняется с кодом UNSUPPORTED_FILTER до обращения к Bitrix24 — так же, как в прямом списке.

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

Ничего менять не нужно. Если под-вызов batch раньше опирался на выполнение отключённой операции записи — переведите его на выделенный роут сущности. Для batch-list по сущностям с обязательными параметрами (calendar-events) передавайте type и ownerId в params под-вызова. Если batch-list для calendar-events использовал filter — уберите его или перенесите в параметры верхнего уровня, иначе под-вызов вернёт UNSUPPORTED_FILTER.

### NEW-0702-17: GET /:entity/fields отдаёт label и description полей

Ответ `GET /v1/{entity}/fields` теперь по каждому полю может нести человекочитаемое короткое имя `label` и пояснение `description` по-русски — раньше поле описывалось только парой `{type, readonly}`. Это позволяет ИИ-агенту и интерфейсу показывать название и назначение поля, не обращаясь к документации. Поля добавлены для сущностей: Отделы, Смарт-процессы, Хранилища, Папки, Файлы, Рабочие группы, Шаблоны документов, Бронирования, События календаря, Задачи, Реквизиты, Сотрудники. Для Сотрудников дополнительно исправлена подстановка подписей: `GET /v1/users/fields` теперь возвращает настоящие названия полей Битрикс24 из `user.fields` вместо технических кодов. Изменение аддитивное: новые ключи появляются дополнительно к прежним, существующие вызовы продолжают работать без изменений.

### FIX-0702-18: ключ только со скоупами vibe:* теперь выписывается, а не падает

**Было**

Создание ключа авторизации `POST /v1/keys`, у которого все запрошенные права — внутренние права платформы Вайбкод `vibe:*` (например только `vibe:infra`), на портале с режимом dev-key (коробочная Битрикс24 или подключённый облачный портал) отклонялось с `502 DEVKEY_MINT_FAILED`. Права `vibe:*` не передаются в Битрикс24, поэтому набор прав для вебхука Битрикс24 оказывался пустым, и Битрикс24 отклонял выписку, требуя хотя бы одно право.

**Стало**

Ключ только с правами `vibe:*` теперь выписывается успешно. Вебхук Битрикс24 для него не создаётся — он не нужен, такой ключ не обращается к REST Битрикс24, — а ключ работает с внутренними возможностями платформы Вайбкод по своим правам.

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

Действий не требуется: прежде падавший запрос теперь возвращает созданный ключ.

### FIX-0702-19: пагинация /v1/storages — limit больше 50 отдаёт все записи, meta.hasMore корректен

**Было**

`GET /v1/storages` с `limit` больше 50 возвращал максимум 50 записей, а `meta.hasMore` был всегда `false` — даже когда в портале записей больше. Клиент с `?limit=50` при 489 хранилищах видел `hasMore: false` и не знал, что нужно запросить следующую страницу. То же на `POST /v1/storages/search` и в `/v1/batch`.

**Стало**

`limit` больше 50 проходит авто-пагинацию (как у остальных списков) и отдаёт запрошенное число записей, а `meta.hasMore` равен `(offset + число записей) < meta.total` и для `limit` не больше 50. Изменение распространяется на `GET /v1/storages`, `POST /v1/storages/search` и список `storages` в `/v1/batch`.

Примечание: корректный расчёт `meta.hasMore` для ответов списка при `limit` не больше 50 теперь распространяется на все сущности (`GET /v1/{entity}` и `POST /v1/{entity}/search`), а не только на `storages` — ранее на этом пути `meta.hasMore` был всегда `false`.

### FIX-0702-20: infra: кириллица в displayName при создании приложения

**Было**

При [POST /v1/infra/servers](/docs/infra) с кириллическим `displayName` название могло сохраниться как последовательность знаков вопроса (`??????`) — повреждение кодировки при передаче в Битрикс24.

**Стало**

Название передаётся в кодировке UTF-8, кириллица сохраняется корректно.

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

Действий не требуется. Кириллические названия больше не искажаются.

### FIX-0702-21: items: фильтрация по полям связи parentId<N>

**Было**

Фильтр по динамическому полю связи (например `parentId2` — связанная сделка) на [GET /v1/items/:entityTypeId](/docs/entities/items/list) и [POST /v1/items/:entityTypeId/search](/docs/entities/items/search) отклонялся с `400 UNKNOWN_FILTER_FIELD`, хотя поле присутствует в `GET /v1/items/:entityTypeId/fields` и возвращается в ответах.

**Стало**

Поля вида `parentId<N>` принимаются в фильтре и передаются в запрос как есть. Найти смарт-процесс, связанный с конкретной родительской сущностью, теперь можно напрямую через обёртку items.

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

Действий не требуется. Запросы, ранее получавшие `400`, теперь отрабатывают.

### FIX-0702-22: смарт-процессы: сохранение списка значений и названия пользовательского поля

**Было**

На [POST /v1/items/:entityTypeId/userfields](/docs/userfields/smart-processes) поле-список (`userTypeId: enumeration`) создавалось, но варианты значений не сохранялись (список приходил пустым), а название поля, переданное строкой, в интерфейсе оставалось пустым.

**Стало**

Варианты значений принимаются как в `enum`, так и в `list` и корректно сохраняются. Название, переданное строкой, автоматически оборачивается в языковую карту и заполняет подписи в форме, колонке и фильтре.

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

Действий не требуется. Ранее «молча терявшиеся» значения списка и название теперь сохраняются.

### FIX-0702-23: req-family: /fields у адресов и preset-fields отдают ключи в camelCase

**Было**

`GET /v1/addresses/fields` и `GET /v1/requisite-presets/:presetId/fields/schema` возвращали описание полей с сырыми ключами в UPPER_SNAKE_CASE (`TYPE_ID`, `ADDRESS_1`, `FIELD_NAME`, `IN_SHORT_LIST`), хотя данные этих сущностей (`GET /v1/addresses`, список полей пресета) уже приходили в camelCase — схема не совпадала с реальными именами в данных.

**Стало**

Оба эндпоинта нормализуют ключи описания в camelCase (`typeId`, `address1`, `fieldName`, `inShortList`), как и весь остальной V1. Внутренние дескрипторы поля (`type`, `isRequired`, `isReadOnly`, `title`) не меняются.

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

Ключи в ответе `/fields` теперь совпадают с именами полей в данных. Клиент, читавший camelCase-имена из данных, получает согласованную схему; действий не требуется.
