Для AI-агентов: markdown этой страницы — /docs-content/changelog/2026-08-21.md индекс документации — /llms.txt

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

← Журнал изменений · Август 2026

FIX-0821-1: iblockTypeId=structure принимается в /v1/lists

Было

iblockTypeId принимал только lists, lists_socnet и bitrix_processes. Значение structure (тип инфоблока графика отсутствий) давало 400 INVALID_IBLOCK_TYPE, хотя GET /v1/lists/:iblockId/type его возвращал.

Стало

structure входит в допустимый набор на всех маршрутах /v1/lists. Ответ Битрикс24 на этом типе (данные или 422/403) больше не подменяется нашим 400. Прочие неизвестные типы по-прежнему дают 400 INVALID_IBLOCK_TYPE. Значение по умолчанию не изменилось — lists.

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

Запросы к инфоблокам типа structure, включая штатный график отсутствий absence, теперь доходят до Битрикс24. Существующие интеграции с другими типами менять не нужно.

FIX-0821-2: currencyId и явный select невозвращаемых полей

Было

POST /v1/products и PATCH /v1/products/:id принимали валюту только под именем currency. Явный select поля с признаком notReturned: true принимался без предупреждения, хотя значения в ответе не было.

Стало

Методы записи товара принимают currencyId как дополнительное имя currency. Если переданы оба имени, используется currency, а в ответах по-прежнему приходит только currency. Дополнительное имя помечено как writeOnly и notReturned в /fields, /v1/guide и OpenAPI. Явный select любого невозвращаемого канонического имени теперь добавляет предупреждение UNKNOWN_SELECT_FIELD: это products.currencyId, tasks.realStatus, product-sections.sort, bank-details.entityTypeId, telephony-lines.serverName, bizproc-templates.templateData и catalog-products.iblockSection. Нативное имя Битрикс24 select=CURRENCY_ID по-прежнему выбирает читаемое поле products.currency. Поведение каждого имени описано в справочниках полей товаров, задач, разделов товаров, банковских реквизитов, линий телефонии, шаблонов бизнес-процессов и товаров каталога. Фильтрация по валюте не поддерживается и возвращает 400 UNSUPPORTED_FILTER.

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

Запросы чтения продолжают возвращать 200 и остальные выбранные поля, но теперь содержат предупреждение. Уберите невозвращаемые имена из select: для валюты используйте currency, для фактического статуса задачи — status.

FIX-0821-3: фильтр товаров по описанию больше не отклоняется

Было

GET /v1/products с filter[description] и POST /v1/products/search с тем же фильтром отвечали 400 UNSUPPORTED_FILTER, хотя описание сохранялось при создании товара.

Стало

Точное равенство и $in по полю description принимаются так же, как по name. Операторы, включая $contains, по-прежнему отвечают 400. Фильтры по price и currency не изменились.

FIX-0821-4: отказ при создании сотрудника без отдела называет поле, которое нужно передать

Было

POST /v1/users без departmentId на портале с установленным модулем extranet отвечал 422 с текстом no_extranet_field. Поля с таким именем нет ни в теле запроса, ни в выдаче GET /v1/users/fields, и ничто в ответе не указывало на отдел — по такому отказу нельзя было понять, что именно исправить. Сотрудник при этом не создавался.

Стало

Ответ дополнен подсказкой: она называет поле в обоих написаниях — UF_DEPARTMENT для прямого вызова и departmentId для обёртки POST /v1/users (оба принимаются), указывает источник значений GET /v1/departments, приводит корневой отдел как рабочий пример и упоминает POST /v1/users/invite, который подставляет отдел сам. Для внешнего пользователя названа альтернатива — EXTRANET вместе с SONET_GROUP_ID вместо отдела. Описание поля departmentId в справочнике полей теперь тоже говорит про это требование, поэтому условие видно до отправки запроса.

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

Действий не требуется: код ответа и структура конверта не изменились, добавилась только подсказка. Поле departmentId намеренно не сделано обязательным на стороне API Вайбкод — портал без модуля extranet принимает создание без отдела, и жёсткое требование сломало бы такие запросы.

NEW-0821-5: метаданные диалога Открытой линии через API

Добавлен эндпоинт POST /v1/openlines/dialogs/lookup — обёртка над методом Битрикс24 imopenlines.dialog.get. Возвращает карточку одного диалога Открытой линии (название, тип, линию, число сообщений, даты) по одному из идентификаторов: chatId, dialogId или sessionId. Переписку метод не отдаёт. Требует скоуп imopenlines.

В ответе есть производное поле lineId — идентификатор линии, разобранный из привязки диалога; он даёт вход в GET /v1/openline-configs/:id. Поиск по sessionId позволяет найти диалог прямо по идентификатору сессии из поля id ответа POST /v1/openlines/sessions/search.

BC-0821-6: структура в скалярном поле на записи отклоняется вместо тихой потери значения

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

Было

Запись сущности принимала в поле, объявленное скаляром, объект или массив и отвечала успехом. POST /v1/deals с телом {"title": {"a": 1}} возвращал 201, а в карточке сделки оказывалась строка Array: Битрикс24 приводит массив к строке именно так. Значение восстановить было нельзя, и ошибки клиент не видел.

Стало

Такой запрос отклоняется до вызова Битрикс24 — 400 с кодом INVALID_PARAMS и именем поля. Правило применяется к полям, объявленным как string, number, boolean, date и datetime, на записи сущностей по путям /v1/<entity>: создание и обновление, POST /v1/batch, пакетная запись по сущности и импорт.

Поведение, которое НЕ изменилось: число и логическое значение в строковом поле по-прежнему принимаются (Битрикс24 сохраняет 123456 и 1 — значение не теряется), null по-прежнему принимается, а поля, объявленные как object, array и многозначные, структуру принимали и принимают.

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

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

Границы названы явно. Имя, которого нет в схеме сущности (пользовательские поля UF_*, propertyNNN, опечатка), проверке не подлежит — у него нет объявленного типа. Форма отказа различается по поверхности, и различается охват. Общий пакетный вызов отклоняет только свой подвызов и кладёт отказ в data.errors["<id>"] отдельными полями code и message. Пакетная запись по одной сущности и импорт отклоняют весь запрос: 400 с кодом BATCH_ITEM_VALIDATION или IMPORT_ITEM_VALIDATION, а номер элемента и INVALID_PARAMS — внутри message. Поэлементных результатов в таком ответе нет, и в Битрикс24 не уходит ни одной записи. Несколько обособленных маршрутов записи проверку пока не проходят — адреса, комментарии задач, шаблоны документов, настройки открытых линий и товарные строки; там прежнее поведение сохраняется, и они закрываются отдельно.

FIX-0821-7: PATCH /v1/infra/servers/:id/access-policy сохраняет список доступа при смене политики

Было

При переключении PATCH /v1/infra/servers/:id/access-policy с NAMED_USERS или DEPARTMENT на любую другую политику список доступа (пользователи и отделы, добавленные через POST /access) стирался безвозвратно — хотя документация обещала, что записи сохраняются в базе и просто не применяются, пока политика не станет именной снова.

Стало

Список сохраняется при уходе с NAMED_USERS/DEPARTMENT — поведение снова соответствует документации.

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

Действий не требуется — поведение приведено в соответствие с уже опубликованной документацией.

BC-0821-8: занятость общего exec-канала галактики отдаётся как 409, а не 502

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

Было

POST /v1/infra/servers/:id/exec для приложения в галактике (kind: "GALAXY_APP") отвечал 502 с кодом EXEC_BUSY, когда общий exec-канал хоста был занят. Ни заголовка Retry-After, ни полей retryable / retryAfter в ответе не было, поэтому машинный клиент читал отказ как сбой шлюза и не повторял вызов. Тот же по смыслу отказ на POST /v1/infra/servers/:id/deploy при этом уже приходил как 409 с сигналом повтора.

Подсказка error.hint в ответах 409 EXEC_BUSY на галактических маршрутах предлагала расклинить канал вызовом POST /v1/infra/servers/:id/unstick. Владельцу приложения и владельцу хоста этот вызов недоступен по контракту — он отвечает 409 GALAXY_UNSTICK_UNSUPPORTED, потому что exec-канал общий для всех приложений хоста.

Стало

Занятость общего exec-канала хоста приходит как 409 с кодом EXEC_BUSY, заголовком Retry-After и полями retryable: true / retryAfter (секунды) — тем же контрактом, что и остальные отказы «занято». Прочие ошибки выполнения у приложения в галактике по-прежнему приходят со статусом 502.

На одном статусе 409 теперь живут два разных состояния, и они машинно различимы по наличию поля error.hint.autoExpiresInSeconds: лок самого приложения несёт его (остаток времени жизни лока), занятость общего канала хоста — нет. По recoveryAction их различать нельзя: у приложения в галактике и у самого галактического хоста это поле конкретного вызова не называет вовсе — только «подождать» и «повторить», — потому что снятие лока способно оборвать выполняющуюся операцию, а на общем хосте вместе с ней и команды соседних приложений. Машинный совет поэтому в обоих состояниях один — подождать и повторить по Retry-After.

⚠️ Сказанное относится к галактическим состояниям, а не к маршруту /exec целиком. На отдельной виртуальной машине (kind: "STANDALONE") recoveryAction того же 409 по-прежнему называет DELETE /v1/infra/servers/:id/lock, безусловно, — и вызов этот против идущего деплоя снимает пер-серверную сериализацию, на которую деплой опирается. Поэтому исполнять recoveryAction не читая error.hint.recovery нельзя ни на одном состоянии. Адрес снятия лока остаётся в error.hint.recovery, с подставленным идентификатором сервера, требованием ключа-владельца и оговоркой, что звать его следует, только убедившись, что ничего не выполняется.

Тем же контрактом ответило и чтение журнала. GET /v1/infra/servers/:id/logs у приложения в галактике идёт через тот же общий exec-канал хоста, и при занятом канале отвечал 200 с пустым списком logs — то есть утверждал, что у приложения нет вывода. Теперь занятость приходит как 409 с Retry-After, а прочие сбои чтения — как 502 с кодом агента.

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

Клиенту, который ветвился по HTTP-статусу и считал 502 на /exec терминальным сбоем, надо перестать это делать: занятость теперь приходит как 409 и её следует повторять с интервалом из Retry-After. Клиенту, который читал error.code, менять нечего. Если ваш сценарий вызывал POST /v1/infra/servers/:id/unstick по подсказке платформы — на галактических серверах он не работал и раньше, замените его повтором вызова, а при устойчивом отказе обращайтесь в поддержку. Если вы разводите два состояния 409 на /exec в коде — сверяйтесь с наличием error.hint.autoExpiresInSeconds, а не с текстом recoveryAction.

BC-0821-9: пакет по одной сущности объясняет, что сделал с select

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

Было

POST /v1/{entity}/batch с действием list применял select к ответу, но молчал обо всём, что при этом отбросил. Имя, которого у сущности нет, просто исчезало: запись приходила суженной, а объяснения не было нигде — ни ошибки, ни предупреждения. У одиночного списка и у глобального пакета такое имя перечисляется предупреждением, и только у этой двери отбор полей был полностью безмолвным.

Стало

Подвызов несёт своё meta.warnings с кодом UNKNOWN_SELECT_FIELD и именем поля — ровно той же формы, что у одиночного списка. Предупреждение принадлежит СВОЕМУ подвызову: соседние элементы пакета своё meta не получают, и пустым массивом ключ не приезжает — сказать нечего, значит ключа нет.

Сущности, у которых незнакомое имя отвечает ошибкой (сегодня это события календаря), теперь отклоняют такой подвызов и здесь — UNKNOWN_SELECT_FIELD до вызова Битрикс24. Отказ per-call, как в глобальном пакете: падает только этот элемент, остальные сорок девять выполняются. Раньше на этой двери жёсткий отбор не срабатывал вовсе.

Значение * по-прежнему означает «вернуть все поля»: отбора нет, и незнакомое имя рядом с ним ничего не отклоняет. Предупреждение при этом приходит: select вида *,titel вернёт все поля и скажет, что второе имя ничего не значит, — ровно как на одиночном списке и в общем пакете.

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

Аддитивная половина ничего не ломает: meta — новый необязательный ключ рядом с data и total. Ломающая — жёсткий отбор: подвызов, который раньше отвечал суженной записью и кодом 200, на событиях календаря теперь отвечает error в своём слоте. Окна поддержки нет намеренно: прежнее поведение и было дефектом — запрошенное имя молча пропадало, и отличить это от «поля нет в записи» было нечем. Проверьте обработчики, которые считали отсутствие ошибки признаком того, что все имена из select распознаны.

NEW-0821-10: транскрипт сессии Открытой линии через API

Добавлен эндпоинт POST /v1/openlines/sessions/history — обёртка над методом Битрикс24 imopenlines.session.history.get. Возвращает переписку последней сессии чата Открытой линии по его идентификатору: сообщения, участников и метаданные файлов одним ответом. Требует скоуп imopenlines.

Вход только по идентификатору чата (chatId, принимается и форма chat2043). По нему берётся последняя сессия чата. Пагинации у метода нет — транскрипт приходит целиком. Для постраничного чтения сообщений остаётся GET /v1/chats/:dialogId/messages.

Эндпоинт включается платформой Вайбкод постепенно: пока он не включён, вызов отвечает 403 OPENLINES_HISTORY_DISABLED — это признак того, что возможность ещё не активирована, а не ошибка интеграции.

NEW-0821-11: мультипарт-деплой galaxy-приложения хранит архив в хранилище исходников

Multipart-выкладка galaxy-приложения больше не собирает архив целиком в памяти платформы: там, где включено депонирование multipart, архив уезжает версией в хранилище исходников и попадает на хост по подписанной ссылке. Где хосту разрешено забирать архив самому, распознанный tar.gz он скачивает сам — со сверкой размера и контрольной суммы, записанных за версией, — и тогда причина неудачной загрузки приходит отдельным кодом UPLOAD_DOWNLOAD_FAILED / UPLOAD_EXTRACT_FAILED / UPLOAD_NO_SPACE в хвосте buildLog; ZIP и нераспознанный формат едут прежним путём, через агента. Предел на размер архива в теле запроса при этом не меняется — тело по-прежнему проходит через платформу. Версия остаётся в депо и тогда, когда деплой провалился: её видно в списке версий и можно выложить повторно по source.versionId.