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

Изменения API: 24 сентября 2026

← Журнал изменений · Сентябрь 2026

NEW-0924-2: Признак множественности у полей портала в описании полей сущности

В ответе GET /v1/{entity}/fields (например, GET /v1/deals/fields) у поля, которое пришло с портала, появился ключ multiple: true, если Битрикс24 сообщает, что поле принимает несколько значений, — например, у множественного пользовательского поля ufCrm_*. Значение такого поля при создании и изменении записи передавайте массивом. Отсутствие ключа multiple не означает, что поле одиночное: признак не выводится у полей, которые платформа описывает сама, и у полей, для которых портал множественность не сообщил.

BC-0924-3: Сортировка документов CRM принимает только один уровень скобок

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

Было

GET /v1/crm-documents принимал под именем поля сортировки второй уровень скобок. Написания order[updateTime][]=desc и order[updateTime][0]=desc отвечали HTTP 200 и сортировали выдачу так, будто передано order[updateTime]=desc — то есть за вызывающего досочинялась сортировка, которой он не писал. Написание order[updateTime][x]=desc отвечало HTTP 500.

Стало

Запись сортировки обязана нести направление, а не структуру. Второй уровень скобок под именем поля — order[updateTime][x]=desc, order[updateTime][]=desc, order[updateTime][0]=desc — возвращает HTTP 400 INVALID_ORDER до обращения к Битрикс24. Одноуровневое написание order[updateTime]=desc и регистр направления работают как прежде. Неизвестное направление по-прежнему отбрасывается без отказа, а написание, которое разбору не поддаётся вовсе — order=desc, order[]=desc, третий уровень скобок, — по-прежнему оставляет выдачу без сортировки.

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

Передавайте сортировку одним уровнем скобок: order[updateTime]=desc. Если строка запроса собирается из массива или индексированного списка, приведите её к этому виду: прежние написания order[updateTime][]=desc и order[updateTime][0]=desc теперь отказываются, а не сортируют.

FIX-0924-5: суточная норма вызовов считается по закрытым часам

Было

Заголовки X-RateLimit-Used и X-RateLimit-Remaining были описаны как учитывающие и вызовы текущего часа — с точностью до минуты.

Стало

Оба заголовка считают израсходованное за сегодня по закрытым часам: вызовы текущего часа попадают в счёт после его окончания, поэтому заголовки отстают от факта до 70 минут и в начале часа могут не показывать уже сделанные вызовы. Размер суточной нормы, заголовок X-RateLimit-Quota и код отказа QUOTA_EXCEEDED не менялись, вызов в пределах нормы по-прежнему отвечает HTTP 200. Клиенту менять ничего не нужно; если остаток нужен точно, учитывайте собственные вызовы текущего часа на своей стороне.

FIX-0924-6: справочник агрегации в GET /v1/guide описывает POST-агрегацию и поля числовых функций по типу

Было

Блок operations.aggregate в GET /v1/guide описывал устаревший GET …/aggregate с параметрами op и field и называл aggregatableFields источником поля для sum/avg/min/max. Для элементов смарт-процессов (/v1/items/:entityTypeId) он указывал путь GET /v1/items/:entityTypeId/aggregate, которого нет. Сообщение 400 INVALID_PARAMS о неизвестном поле в POST …/aggregate перечисляло тот же список aggregatableFields вместо числовых полей.

Стало

operations.aggregate описывает POST …/aggregate с массивом aggregate[]. Поле для sum/avg/min/max — любое поле с типом number из …/fields или числовое пользовательское поле там, где сущность их поддерживает (есть ключ ufSupport). aggregatableFields — поля для groupBy. Сообщение 400 INVALID_PARAMS перечисляет числовые поля сущности, а у сущности без числовых полей говорит This entity declares no number-typed field.. У сущностей, где пользовательских полей нет, ключа ufSupport больше нет, и справочник с openapi.json их не обещает. Ответ GET /v1/guide по-прежнему HTTP 200, код и статус ошибки агрегации прежние.

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

Если клиент читал из справочника params.op и params.field, переходите на params.aggregate и вызывайте POST …/aggregate. Вызовы устаревшего GET …/aggregate продолжают работать как раньше.

NEW-0924-7: расписание, на котором рождаются новые машины

Администратор аккаунта Битрикс24 может отметить расписание работы, на котором рождаются новые машины: PUT /v1/work-schedules/:id/default с телом {"audience": "machines", "enabled": true}. Отметок две: machines — для серверов и приложений в галактике, agents — для агентов и ботов. Вторая отдельная, потому что агент на расписании вне окна спит и не отвечает на сообщения до начала следующего окна. У каждой стороны отмечено не больше одного расписания: новая отметка переезжает с прежнего, "enabled": false её снимает.

Сервер, созданный через POST /v1/infra/servers без runMode, рождается на отмеченном расписании. Явный runMode, включая IDLE, по-прежнему сильнее отметки, а уже созданные машины свой режим не меняют.

В каждой строке библиотеки GET /v1/work-schedules появились поля defaultForNewMachines и defaultForNewAgents. Отметку меняет только администратор, остальные получают 403 ADMIN_ONLY.

FIX-0924-8: режим работы, названный при создании, доезжает до приложения в галактике

Было

POST /v1/infra/servers принимал блок runMode, но когда машина размещалась в галактике, блок молча выбрасывался: приложение рождалось в режиме по умолчанию. Расписание, которого в аккаунте нет, в этом случае тоже не отвергалось.

Стало

Блок runMode применяется и к приложению в галактике. Ненайденное или пустое расписание отвергается до создания, как и у отдельного сервера: 400 WORK_SCHEDULE_NOT_FOUND или 400 WORK_SCHEDULE_EMPTY, приложение при этом не создаётся.

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

Интеграция, которая передаёт runMode, получает названный режим без отдельного вызова PATCH /v1/infra/servers/:id/run-mode. Расписание, которого нет, теперь отвергается и при размещении в галактике, как документация и обещала.

FIX-0924-9: агрегация отвечает об ошибке портала так же, как список

Было

POST /v1/{entity}/aggregate и устаревший GET /v1/{entity}/aggregate отдавали отказ Битрикс24 без пояснений, привязанных к вызванному методу: тело ошибки приходило без поля hint с известным ограничением метода и без поля warning о том, что та же ошибка уже повторялась. Список и поиск по той же сущности на тот же отказ отвечали с этими полями. Из-за этого один и тот же отказ портала выглядел у клиента по-разному в зависимости от того, какой адрес его вызвал.

Стало

Обе двери агрегации отвечают об одной причине тем же кодом и с теми же пояснениями, что GET /v1/{entity} и POST /v1/{entity}/search. В теле ошибки появляются hint с известным ограничением вызванного метода Битрикс24 и warning, когда отказ повторяется. Успешные ответы агрегации не изменились, коды успешных ответов прежние.

NEW-0924-10: новый код отказа `agent_turn_loop_detected` для зациклившегося хода агента

POST /v1/chat/completions получил код отказа agent_turn_loop_detected (409) для зациклившегося хода агента. Сейчас отказ не действует: такие запросы обслуживаются как прежде, код ничего не меняет в работе существующих интеграций. О включении отказа будет объявлено отдельной записью типа BC с датой.

Условие отказа после включения: в messages после последнего сообщения с ролью user накопилось 15 и более ответов модели с ролью assistant без tool_calls. Считаются все такие ответы после последнего сообщения user, а не только идущие подряд: вызовы инструментов между ними счёт не сбрасывают. Сами ответы с tool_calls в счёт не входят, поэтому ход, в котором модель на каждом шаге вызывает инструменты, условие не задевает. Обращение к модели по такому запросу не выполняется, и петля не расходует лимит. Чтобы продолжить, отправьте новое сообщение пользователя — счёт начинается заново.

FIX-0924-11: пустой `fields` в теле бот-запроса больше не съедает плоские поля

Было

Тело {"fields": [], "command": "help", "title": "Help"} — так сериализуется пустой словарь, например в PHP через json_encode([]) — принималось за формат Битрикс24 и уходило в портал как fields: []. Присланные command и title терялись молча, без предупреждения в ответе. То же на PATCH /v1/bots/{botId} и PATCH /v1/bots/{botId}/chats/{dialogId}, причём там пустую обёртку изображали ещё и null, false, 0 и пустая строка: запрос уезжал в портал как есть, портал отвечал 200, и ничего не менялось.

Стало

Пустая обёртка fields обёрткой не считается — тело читается как плоское и доезжает до портала целиком. Затронуты POST /v1/bots/{botId}/commands, PATCH /v1/bots/{botId}/commands/{commandId}, PATCH /v1/bots/{botId} и PATCH /v1/bots/{botId}/chats/{dialogId}. Непустая обёртка по-прежнему передаётся без изменений. Два следствия: ключ fields больше не попадает в warning.droppedFields, а неизвестный ключ верхнего уровня при разворачивании отбрасывается — до портала он всё равно не доезжал.

NEW-0924-12: отказ в создании приложения из Коворка говорит, откроет ли дверь пробный период Маркета

Отказ POST /v1/cowork/applications «подписки нет» у аккаунта подписочной модели — 402 MARKETPLACE_REQUIRED — теперь несёт необязательное поле error.details.activation. Это блок той же формы, что activation в GET /v1/cowork/state, но посчитанный для этой двери: marketTrial.available: true значит, что одноразовый пробный период Маркета откроет создание приложений. Включается он прежней ручкой POST /v1/cowork/activate-market-trial с явным подтверждением человека.

Значения not_required_for_data здесь не бывает: для чтения данных подписка не нужна, а для создания приложений — нужна. Аккаунту на бесплатном тарифе Битрикс24 пробный период не предлагается: REST там недоступен, и период сгорел бы впустую. У аккаунта тарифной модели доступа поля нет: пробный период Маркета ему доступа не откроет, а путь покупки тарифа в теле отказа уже есть. Другие отказы этой двери поля не несут: пробный период снимает только отсутствие подписки, а подписку, которую не удалось прочитать, лечит переподключение приложения под главным администратором. Поля нет и тогда, когда строку аккаунта прочитать не удалось; остальное тело отказа не меняется.

FIX-0924-14: Запрос событий бота с явным offset ниже сохранённого больше не сдвигает курсор

Было

GET /v1/bots/{botId}/events с явным offset ниже сохранённой позиции (например, offset=0 для отладки) сдвигал сохранённый курсор, если в ответе были события. Следующий обычный запрос без offset уходил с новой позицией, Битрикс24 удалял отданные отладочному запросу события как подтверждённые, и основной цикл бота их не получал.

Стало

Явный offset ниже сохранённой позиции возвращает события, но курсор не сдвигает, и в ответе приходит persisted: false. Явный offset, равный сохранённой позиции или больше неё, сдвигает курсор как раньше. Подтверждённые события Битрикс24 удаляет, поэтому offset=0 показывает только события, ещё не подтверждённые в очереди, а не всю историю.

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

Менять ничего не нужно. Отладочный запрос с offset=0 больше не отнимает события у основного цикла, листание по nextOffset работает как раньше.

NEW-0924-15: resubscribe сообщает режим событий на стороне Битрикс24

Бот в режиме fetch получает события, только пока такой же режим стоит у него на стороне Битрикс24. Это значение авторитетное, и оно может разойтись с тем, что хранит платформа Вайбкод, — тогда опрос GET /v1/bots/{botId}/events успешен, ошибок нет, а очередь остаётся пустой сколько угодно долго.

Ответ POST /v1/bots/{botId}/resubscribe теперь несёт три новых поля. b24EventMode — режим, который Битрикс24 держал ДО вызова (null, если портал его не сообщил). diverged — расходился ли он с полем eventMode, которое хранит платформа. hint — что вызов сделал на самом деле и что проверять дальше.

Различать это важно: Битрикс24 перепривязывает события только при РЕАЛЬНОЙ смене режима. Если режимы уже совпадали, вызов ничего не перепривязал, и прежний ответ { resubscribed: true } читался как выполненное восстановление. Теперь такой случай назван прямо, а причину пустой очереди подсказка предлагает искать выше очереди — в составе участников чата и в том, упоминают ли бота, если он отвечает только на упоминания.

Подсказка в ответе GET /v1/bots/{botId}/events после серии пустых опросов переписана по тому же разбору: она помечает eventMode как значение платформы и отправляет за авторитетным в resubscribe.

NEW-0924-16: вход в задеплоенное приложение по ключу десктопа Коворка

Новый эндпоинт POST /v1/cowork/app-login принимает адрес задеплоенного приложения и возвращает тот же адрес с добавленным параметром __gw_token и сроком его жизни expiresIn. Встроенный браузер Cowork/Code, открыв такой адрес, входит в приложение от имени владельца ключа, с его номером пользователя в Битрикс24, без формы авторизации. Токен открывает только это приложение. Эндпоинт принимает только ключ десктопа Cowork/Code со скоупом vibe:cowork. Неточный адрес приложения отклоняется кодом 400 INVALID_APP_URL, любой исход проверки доступа — единым кодом 404 APP_NOT_AVAILABLE, неизвестный номер пользователя в Битрикс24 — кодом 409 B24_USER_UNKNOWN.

BC-0924-17: методы списков проверяют ключ до чтения тела и без ключа отвечают 401

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

Было

На всех методах /v1/lists/* ключ проверялся после того, как платформа прочитала и разобрала тело запроса. Поэтому запрос без ключа или с неверным ключом получал ответ о теле, а не о ключе: 400 INVALID_JSON_BODY на неразобранном JSON и 413 PAYLOAD_TOO_LARGE на теле больше 1 МБ, например на POST /v1/lists/:iblockId/elements. Сервер при этом читал тело целиком для любого отправителя.

Стало

Ключ проверяется первым, до чтения тела. Запрос без ключа или с неверным ключом на любом методе /v1/lists/* получает 401 независимо от размера и содержимого тела, а само тело не читается. Это закрывает возможность заставить сервер читать крупное тело без ключа — условие, при котором запись элемента смогла принять тело до 40 МиБ. Ответы на запросы с корректным ключом не изменились.

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

Ничего, если ключ передаётся. Если код различает ответы на запрос без ключа или с неверным ключом по кодам 400 или 413, заменить эту проверку на 401.

FIX-0924-18: файл в свойстве элемента списка больше не упирается в 1 МБ

Было

Значение свойства типа «Файл» у элемента списка едет в теле запроса как base64, а тело записи элемента было ограничено 1 МБ. Практический потолок одного файла — около 750 КБ: POST /v1/lists/:iblockId/elements и PATCH /v1/lists/:iblockId/elements/:elementId с файлом крупнее отвечали 413 PAYLOAD_TOO_LARGE, и запись не выполнялась. Тот же файл в поле сделки или контакта проходил.

Стало

Тело создания и обновления элемента списка ограничено 40 МиБ, как у записи сущностей CRM, — это чуть меньше 30 МиБ исходного файла после base64. Остальные методы списков и пакетные вызовы (POST /v1/batch) сохраняют прежний потолок 1 МБ, поэтому крупный файл отправляйте одиночным вызовом.

Запись элемента с телом крупнее 1 МБ делит общий лимит одновременно обрабатываемых крупных тел с записью сущностей CRM: когда он занят, приходит 429 LARGE_BODY_BACKEND_BUSY с заголовком Retry-After: 5, запрос не выполнялся, и его нужно повторить.

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

Действий не требуется: запрос, который раньше получал 413, теперь выполняется. Вызов в Битрикс24 ограничен 15 секундами и не повторяется, поэтому файл у самой границы на медленном аккаунте может получить BITRIX_TIMEOUT — оставляйте запас.