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

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

### FIX-0703-1: привязка размещения по ключу разработчика больше не возвращает 500 после цикла снятия и повторной публикации

**Было**

`POST /v1/placements/bind` для приложения, управляемого ключом разработчика (тип `local.*`), мог стабильно возвращать `500` (`BITRIX_UNAVAILABLE`, `INTERNAL_SERVER_ERROR`) при привязке размещения (например `CRM_DEAL_DETAIL_TAB` или `CRM_CONTACT_DETAIL_TAB`) после того, как приложение снимали с публикации и публиковали заново. Прежняя регистрация размещения на стороне Битрикс24 сохранялась, и попытка зарегистрировать поверх неё новую завершалась внутренней ошибкой. Повторные вызовы давали ту же ошибку.

**Стало**

Перед регистрацией размещения запрос сначала снимает его прежнюю регистрацию на стороне Битрикс24, поэтому привязка проходит успешно и после цикла снятия с публикации и повторной публикации. Менять вызов не нужно.

### FIX-0703-2: /v1/sites — фильтр по типу «база знаний» (KNOWLEDGE) и «группа» (GROUP) больше не игнорируется

**Было**

`POST /v1/sites/search` (а также `GET /v1/sites` и `POST /v1/sites/aggregate`) с `filter[type]=KNOWLEDGE` или `filter[type]=GROUP` молча возвращал обычные сайты-лендинги (`PAGE` / `STORE` / `VIBE`) вместо баз знаний или страниц групп. Причина на стороне Битрикс24: метод `landing.site.getList` привязывает фильтр по `TYPE` к внутренней области (`scope`), и без параметра `scope` типы `KNOWLEDGE` / `GROUP` не входят в область по умолчанию — фильтр по типу тихо отбрасывался. Обойти можно было только вручную, добавив `scope` (см. [Список сайтов](/docs/entities/sites/list)).

**Стало**

Если в фильтре указан один такой тип и `scope` не передан явно, Вайбкод сам подставляет соответствующую область (`type=KNOWLEDGE` → `scope=KNOWLEDGE`, `type=GROUP` → `scope=GROUP`) — и запрос возвращает именно базы знаний / страницы групп. Явно переданный `scope` всегда в приоритете и не переопределяется. Если тип задан списком или оператором (например `{"type":{"$in":["KNOWLEDGE","PAGE"]}}`), где одну область выбрать нельзя, в `meta.warnings` приходит подсказка с кодом `TYPE_REQUIRES_SCOPE`.

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

Действий не требуется. Запросы с `filter[type]=PAGE` / `STORE` / `VIBE` и запросы без фильтра по типу работают как раньше. `MAINPAGE` — это область, а не тип сайта (её сайты имеют тип `VIBE`), поэтому из фильтра по типу область `MAINPAGE` не выводится. Для `/v1/pages` поведение не изменилось.

### FIX-0703-3: агрегация страниц и сайтов снова возвращает count

**Было**

[POST /v1/pages/aggregate](/docs/entities/pages/aggregate) и [POST /v1/sites/aggregate](/docs/entities/sites/aggregate) возвращали `count: 0` и `meta.totalRecords: 0` даже при наличии страниц и сайтов — во всех формах: без фильтра, с фильтром, с выражением `count` и как верхний `count` при `groupBy`. Счётчики отдельных групп при `groupBy` при этом были корректными.

**Стало**

`count` и `meta.totalRecords` отражают фактическое число записей; верхний `count` при `groupBy` равен сумме счётчиков групп.

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

Действий не требуется — ответ стал корректным.

### NEW-0703-4: Параметры качества и таймстампов в расшифровке аудио

Расшифровка аудио [POST /v1/audio/transcriptions](/docs/ai/audio/transcriptions) принимает пять новых необязательных полей. Качество распознавания: `prompt` — контекстная подсказка (тема разговора, стиль, правильное написание терминов, до 2000 символов), `hotwords` — список спец-слов через запятую (редкие термины, бренды, имена, до 500 символов), `vad_filter` — фильтр тишины перед распознаванием (меньше галлюцинаций на записях с паузами). Управление результатом: `temperature` — температура декодера от 0 до 1, `timestamp_granularities[]` — детализация таймстампов `word`/`segment` (только с `response_format=verbose_json`; со значением `word` каждый сегмент дополняется массивом `words` с таймингом и вероятностью каждого слова). Поля передаются в `multipart/form-data` рядом с `file` и совместимы с OpenAI-контрактом. Невалидные значения отклоняются кодами `invalid_prompt`, `invalid_hotwords`, `invalid_temperature`, `invalid_vad_filter`, `invalid_timestamp_granularities`.

### FIX-0703-5: Приложения, созданные через API, корректно открываются как плейсменты

**Было**

Часть приложений, созданных через [POST /v1/apps](/docs/apps/create), не открывалась при вызове плейсмента в Битрикс24 — вместо интерфейса приложения пользователь видел ошибку распознавания приложения.

**Стало**

Созданные приложения корректно резолвятся и открываются как плейсмент-виджеты в Битрикс24. Ответ создания не изменился — приложение сразу пригодно для публикации и привязки плейсментов.

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

Ничего менять не нужно. Ранее не открывавшиеся приложения нужно пересоздать (удалить и создать заново) — новое приложение открывается корректно.

### NEW-0703-6: удаление ключа блокируется при привязанном агенте или боте

[DELETE /v1/keys/:id](/docs/keys-auth) теперь возвращает `409` с кодом `KEY_HAS_LINKED_AGENT`, если ключ является управляющим ключом живого AI-агента или управляемого бота.

**Было**

Удаление такого ключа осиротляло агента и каскадно удаляло бота вместе с его токеном — идентичность бота в Bitrix24 терялась безвозвратно, без предупреждения.

**Стало**

Тело ответа: `{ success: false, error: { code: "KEY_HAS_LINKED_AGENT", message, details: { linkedAgentCount, linkedBotCount, agents: [{ id, name, status }] } } }`. Перед удалением перепривяжите ресурсы к другому ключу либо удалите сам агент/бот; для восстановления доступа осиротевшему агенту используйте кабинетное действие «Восстановить доступ». Проверка идёт до синхронизации с Bitrix24 — при `409` учётные данные на стороне Bitrix24 не затрагиваются. Сиблинг существующего `KEY_HAS_ACTIVE_SERVERS`.

### NEW-0703-7: История изменений задачи и стадии канбана

Добавлены два метода только для чтения (скоуп `task`). `GET /v1/tasks/:taskId/history` возвращает историю изменений задачи целиком за один вызов: смены стадий канбана, перемещения в спринт и бэклог, статусы и другие события. Фильтр по типу события — `?field=STAGE` (несколько типов через запятую, например `?field=STAGE,MOVE_TO_SPRINT`); сортировка — `?order=asc` или `?order=desc` (по умолчанию по возрастанию даты создания). Каждая запись содержит `id`, `createdDate`, `field`, объект `value` с прежним и новым значением и `user` с идентификатором автора. `GET /v1/tasks/stages/:entityId` возвращает текущие колонки канбана рабочей группы (`N`) или личного плана (`0`).

### FIX-0703-8: bizproc-activities: понятная ошибка вместо «Wrong handler URL» при отсутствии handler

**Было**

POST /v1/bizproc-activities без поля `handler` (или с URL обработчика, ошибочно переданным в поле `handlerUrl`) возвращал непрозрачную ядровую ошибку `422 BITRIX_ERROR: Wrong handler URL`.

**Стало**

Поля `code`, `name`, `handler` проверяются до вызова Битрикс24: при отсутствии `handler` метод возвращает `400 MISSING_REQUIRED_FIELDS` с сообщением `Body field "handler" is required to create bizprocActivity`, подсказывая правильное имя поля. Успешные вызовы с корректным полем `handler` не затронуты.

### FIX-0703-9: POST /v1/batch — ответы update и delete теперь нормализованы, как create и get

**Было**

В глобальном пакетном вызове [POST /v1/batch](/docs/batch) подвызов update возвращал ответ в сырой обёртке (вложенный объект вместо плоской записи), а подвызов delete возвращал пустой массив без признака успеха. Это расходилось с create и get в том же эндпоинте и с одиночным PATCH /v1/{entity}/:id, которые отдают плоскую нормализованную запись.

**Стало**

Подвызов update возвращает плоскую нормализованную запись (camelCase-поля) — как create, get и одиночный PATCH. Подвызов delete возвращает признак успеха вида { id, deleted: true }.

### FIX-0703-10: POST /v1/{entity}/batch — create, update и delete снова работают для сущностей CRM

**Было**

По-сущностный пакетный вызов [POST /v1/{entity}/batch](/docs/batch) с действием create, update или delete для сделок, контактов, компаний, лидов, предложений и счетов возвращал по каждому элементу ошибку «Could not find value for parameter {entityTypeId}», и запись не создавалась, не менялась и не удалялась. Одиночные вызовы (POST /v1/{entity}) и глобальный POST /v1/batch на тех же сущностях при этом работали.

**Стало**

По-сущностный пакетный create, update и delete для этих сущностей выполняется корректно — так же, как одиночные вызовы и глобальный пакетный эндпоинт.

### FIX-0703-11: Пропуск поля model в чате снова подставляет модель по умолчанию

**Было**

[POST /v1/chat/completions](/docs/ai/chat/completions) без поля `model` возвращал `400 no_default_model` на порталах, где модель по умолчанию не была явно назначена, — даже когда на портале была доступная бесплатная модель. При этом `GET /v1/me` мог показывать в `defaultModel` модель, которую нельзя вызвать.

**Стало**

Если поле `model` не передано, запрос автоматически берёт первую доступную для вызова модель портала — как и описано в документации. `GET /v1/me` в поле `defaultModel` теперь всегда показывает вызываемую модель, ту же самую, которую подставит чат.

### FIX-0703-12: include по связанным сущностям снова возвращает сами сущности, а не null

**Было**

`GET /v1/deals/:id?include=contact,company` возвращал `_included.company` = `null`, а `_included.contacts` — только метаданные связи (`sort`/`isPrimary`/`roleId`) без полей самой сущности, хотя сделка ссылалась на существующие компанию и контакты.

**Стало**

`_included.company` содержит полный объект компании, а `_included.contacts` — полные объекты контактов (`id`, `name`, …) вместе с метаданными связи. Исправление затрагивает `include` по всем CRM-сущностям (`deals`, `leads`, `quotes` и другим).

### FIX-0703-13: поиск сделок отклоняет неизвестное поле фильтра вместо тихой отдачи всех строк

**Было**

[GET /v1/deals](/docs/entities/deals/list) и [POST /v1/deals/search](/docs/entities/deals/search) с неизвестным полем фильтра (опечатка в имени, поле не из схемы) молча пропускали его в Битрикс24, который игнорирует незнакомые ключи фильтра и возвращает весь набор сделок с ответом `200`. Клиент, отправивший фильтр с ошибкой в имени поля, получал не пустой результат и не `400`, а полную таблицу — как будто фильтр применился.

**Стало**

Неизвестное поле фильтра теперь отклоняется до вызова Битрикс24 ответом `400` с кодом `UNKNOWN_FILTER_FIELD` и списком доступных полей в сообщении — как уже делают `contacts`, `companies`, `leads`, `quotes`, `invoices` и `items`. Объявленные поля (включая псевдонимы вроде `amount`), пользовательские поля (`UF_CRM_*` и `ufCrm*`) и `id` работают как прежде.

### FIX-0703-14: Каталог: список и поиск отдают чистый 400 при отсутствии iblockId

**Было**

Список и поиск [GET /v1/catalog-products](/docs/entities/catalog-products/list), [POST /v1/catalog-products/search](/docs/entities/catalog-products/search), [GET /v1/catalog-sections](/docs/entities/catalog-sections/list) и [POST /v1/catalog-sections/search](/docs/entities/catalog-sections/search) без `iblockId` в фильтре доходили до Битрикс24 и возвращали мутный `422 BITRIX_ERROR` («Field iblockId is not specified in the filter»).

**Стало**

Каталожные список и поиск требуют `iblockId` в фильтре — при отсутствии сразу возвращается `400 MISSING_REQUIRED_FILTER` с примером, запрос до Битрикс24 не доходит.

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

Менять ничего не нужно — корректные запросы (с `filter[iblockId]`) работают как прежде. Изменились только код и ясность ошибки для запросов, которые и так не выполнялись.

### FIX-0703-15: Контакты — реальные поля дат createdTime/updatedTime вместо фантомных createdAt/updatedAt

**Было**

[GET /v1/contacts/fields](/docs/entities/contacts/fields) объявлял поля `createdAt` и `updatedAt`, но в ответах контактов они никогда не появлялись — Битрикс24 отдаёт даты под ключами `createdTime`/`updatedTime`, и именно они были в теле контакта. При этом фильтр и `select` по `createdTime` (имя, которое клиент реально видит в ответе) отклонялись как неизвестное поле, а по фантомному `createdAt` — «работали», хотя само поле в ответе не читалось.

**Стало**

Схема объявляет реальные ключи `createdTime` и `updatedTime` (тип datetime, только чтение): они присутствуют в `/fields`, фильтр и `select` по ним работают, а значение нормализуется к ISO-8601 в UTC. Фантомные `createdAt`/`updatedAt` больше не объявлены — фильтр или `select` по ним возвращает `400 UNKNOWN_FILTER_FIELD`.

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

Чтение не меняется — ключи `createdTime`/`updatedTime` и раньше были в теле ответа, теперь ещё и нормализованы. Если вы фильтровали или проецировали контакты по `createdAt`/`updatedAt`, замените имена на `createdTime`/`updatedTime`.

### FIX-0703-16: Список открытых линий теперь учитывает параметр limit

**Было**

[GET /v1/openline-configs](/docs/openlines/config/list) и одноимённый поиск игнорировали `limit`: нижележащий метод Битрикс24 возвращает весь набор конфигураций, а обёртка отдавала все строки. Поле `hasMore` при этом было неверным — `false`, даже когда за пределами запрошенного `limit` оставались ещё записи.

**Стало**

Ответ обрезается до `limit` на стороне обёртки. `hasMore: true`, когда Битрикс24 вернул больше записей, чем запрошенный `limit` (есть следующая страница), иначе `false`. `total` — число записей в текущем окне.

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

Ответ на запрос с `limit` теперь содержит не больше `limit` записей. Клиенты, полагавшиеся на возврат всего набора без учёта `limit`, увидят усечённый список — используйте `offset` для следующей страницы.
