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

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

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

BC-0914-1: освобождение канала может отказать для защиты работающей операции

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

Было

POST /v1/infra/servers/:id/unstick без force мог прервать длительную операцию, которую не обнаружила проверка перед сбросом канала.

Стало

Метод тщательнее проверяет занятость сервера. При обнаруженной блокировке операции он возвращает 409 OPERATION_IN_PROGRESS; если проверка недоступна — 503 LOCK_STATE_UNAVAILABLE. В обоих случаях канал не сбрасывается. force=true или force=1 сохраняет возможность намеренно прервать операцию.

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

Обрабатывайте оба отказа. При 409 OPERATION_IN_PROGRESS проверьте состояние операции и дождитесь её завершения. При 503 LOCK_STATE_UNAVAILABLE повторите запрос позже. Добавляйте force=true или force=1 только по осознанному решению прервать операцию, а не автоматически в ответ на отказ.

BC-0914-2: удаление и список объектов хранилища получили лимит запросов на портал

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

Было

DELETE /v1/storage/objects/{key} и GET /v1/storage/objects принимали запросы без ограничения частоты. Клиент, который повторял один и тот же вызов в цикле, мог часами держать тысячи запросов в минуту и замедлял этим работу API для всех порталов той же площадки. Запрос HEAD к списку объектов обслуживался как полноценный GET: набор читался целиком, а отдавались только заголовки.

Стало

На каждую из двух операций действует лимит 600 запросов в минуту на портал; все API-ключи одного портала делят один лимит, и у каждой из двух операций он считается отдельно. Действующее значение берите из заголовка ответа X-RateLimit-Limit, а не из числа в этом тексте: оно может оказаться ниже. При превышении API Вайбкод отвечает 429 RATE_LIMITED с заголовками X-RateLimit-Remaining, X-RateLimit-Reset и Retry-After; срока в теле ответа нет — берите его из заголовка. Метод HEAD на адресе списка больше не обслуживается — вместо него используйте GET с limit=1. Успешные ответы обеих операций, их коды и формат данных не изменились, поведение остальных методов хранилища не изменилось.

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

  1. Обработка 429 на удалении и списке. Обе операции получили лимит, которого у них не было. Если ваш код удаляет объекты пачкой или в цикле либо часто перечитывает список — добавьте обработку 429 RATE_LIMITED с паузой по заголовку Retry-After. Бюджет общий на портал, поэтому выпуском второго ключа его не расширить.
  2. Не задавайте потолок числом в коде. Читайте X-RateLimit-Limit из ответа.
  3. Замените HEAD на список на GET /v1/storage/objects?limit=1.
  4. Проверьте цикл повторов. Повторное удаление уже удалённого объекта отвечает 410 STORAGE_OBJECT_DELETED — это признак того, что объект удалён, а не что операцию надо повторить. Код, повторяющий вызов на 410, теперь упрётся ещё и в лимит.

FIX-0914-3: правка и удаление смарт-процесса отвечают кодом отказа портала, а не внутренней ошибкой

Было

PATCH /v1/smart-processes/{id}, DELETE /v1/smart-processes/{id} и пакетная правка или удаление через POST /v1/smart-processes/batch (action: update / delete) перед записью запрашивают у портала внутренний номер смарт-процесса по его entityTypeId. Если Битрикс24 отвечал на этот запрос отказом — превышен лимит обращений, портал недоступен или не ответил вовремя, — клиент получал код INTERNAL_ERROR со статусом, повторяющим статус портала (429, 502, 503 или 504), и без заголовка Retry-After. Тот же отказ портала на следующем шаге тех же операций приходил как 429 RATE_LIMITED, 502 BITRIX_UNAVAILABLE или 503 BITRIX_TIMEOUT — клиент, который повторяет вызов по этим кодам, при INTERNAL_ERROR попытку не повторял.

Стало

Отказ портала на этом шаге отвечает так же, как на любом другом обращении к порталу: 429 RATE_LIMITED (в том числе для лимита, который портал присылает со статусом 503) и 503 BITRIX_TIMEOUT — с заголовком Retry-After, 502 BITRIX_UNAVAILABLE — без него. Запись при таком отказе на портал не отправляется. Успешный ответ по-прежнему 200 (у DELETE /v1/smart-processes/{id} — 204). 404 SMART_PROCESS_NOT_FOUND на неизвестный порталу entityTypeId и 400 на entityTypeId, который не является положительным целым числом (INVALID_ENTITY_TYPE_ID у одиночных операций, BATCH_ITEM_VALIDATION у пакетной) — без изменений. Подробности по кодам — на странице Ошибки.

NEW-0914-4: создание лида предупреждает, когда портал сконвертировал его сам

На портале в простом режиме CRM (без лидов) Битрикс24 конвертирует лид сразу при создании: он приходит CONVERTED и закрытым, а из него создаются контакт и сделка, которых в запросе не было, — запрошенная стадия не сохраняется. Вайбкод в запросе ничего не меняет: так ведёт себя сам портал. Теперь POST /v1/leads в этом случае добавляет в meta.warnings предупреждение LEAD_AUTO_CONVERTED с номерами созданных порталом контакта (contactId) и сделки (dealId); null — если сущность не создана или не найдена: контакт, привязанный вами через contactId, портал переиспользует. Ответ по-прежнему 201 с созданной записью; лид, оставшийся открытым, ответ не меняет. Предупреждения нет, если CONVERTED запрошен явно.

BC-0914-5: отказ при смене политики называет нужный ключ

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

Было

PATCH /v1/infra/servers/:id/access-policy отвечал 404 NOT_FOUND, когда ключ был связан с приложением и сервером, но сервером управлял другой ключ.

Стало

В этом случае метод отвечает 403 SERVER_MANAGING_KEY_REQUIRED и предлагает использовать управляющий ключ сервера или кабинет. Права не расширились; для посторонних ключей ответ остаётся 404 NOT_FOUND.

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

Обрабатывать SERVER_MANAGING_KEY_REQUIRED отдельно от отсутствующего сервера и повторять смену политики с управляющим ключом.

BC-0914-6: поиск компаний не принимает служебный индекс, контакты поддерживают фильтр по категории

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

Было

Фильтр компаний по searchContent принимался с HTTP 200 и предлагался в подсказке UNKNOWN_FILTER_FIELD, хотя служебный индекс не предназначен для поиска обычного текста. Фильтр контактов по categoryId отклонялся с HTTP 400, несмотря на поддержку в Битрикс24.

Стало

Фильтр компаний по searchContent возвращает 400 UNKNOWN_FILTER_FIELD, поле исключено из списка допустимых фильтров. Чтение поля и его выбор через select сохранены. Фильтр контактов по categoryId принимается и перечисляется в подсказке Also filterable.

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

Замените текстовый поиск по searchContent фильтром title с $contains. Ограничение действует и для запросов с подготовленной строкой служебного индекса. Для фильтра контактов используйте точное написание categoryId, например { "filter": { "categoryId": 0 } }.

Затронутые эндпоинты: GET /v1/companies, POST /v1/companies/search, GET /v1/contacts, POST /v1/contacts/search. Эти правила действуют также в фильтрах пакетных запросов и агрегации.

BC-0914-7: список объектов хранилища не считает весь набор по умолчанию

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

Было

GET /v1/storage/objects возвращал обязательное точное поле total на каждой странице. Список с prefix сортировался по id в убывающем порядке, а ключ приложения без пользовательского токена мог включать персональные объекты сотрудников.

Стало

По умолчанию ответ содержит только data и cursor. Точное поле total возвращается только с withTotal=true. Без prefix сохраняется порядок id по убыванию, с prefix действует побайтовый порядок key по возрастанию и id по убыванию. Новый непрозрачный курсор привязан к владельцу, префиксу и порядку. Ключ приложения без пользовательского токена перечисляет только общие объекты приложения, а ключ с пользовательским токеном — только объекты соответствующего сотрудника Битрикс24.

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

Завершайте обход только при cursor: null и передавайте непустой курсор без разбора и изменений. Обход с prefix, начатый старым курсором, перезапустите без курсора. Передавайте withTotal=true только в тех запросах, где нужен точный подсчёт. Персональные объекты сотрудника запрашивайте с его пользовательским токеном.

BC-0914-8: создание шаблона документа из файла на Диске требует скоуп disk

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

Было

POST /v1/doc-templates принимал ID объекта Диска в fileId с одним скоупом documentgenerator и отвечал 201, но созданный шаблон не позволял сформировать документ: последующий вызов возвращал 422 BITRIX_ERROR с b24Code=FILE_NOT_PROCESSABLE.

Стало

Вариант с fileId создаёт пригодный для генерации документов шаблон и требует у ключа оба скоупа: documentgenerator и disk. Файл может занимать до 2 МиБ. Вариант с содержимым .docx в base64-поле file не требует disk и продолжает работать со скоупом documentgenerator.

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

Добавьте скоуп disk в ключи, которые создают шаблоны через fileId. Для вызовов с base64-полем file менять ключ не нужно.

NEW-0914-9: Демо Vibe+ открывает агентов на международной платформе

Активное демо Vibe+ открывает агентов и управляемых ботов с общим лимитом одной виртуальной машины. Платная редакция Vibe+ сохраняет доступ. Управляемые боты также требуют включённой функции на платформе. После окончания демо доступ отзывается, сущность сохраняется, а машина замораживается при плановой проверке. Запуск, пробуждение, перезагрузка, починка, смена конфигурации и восстановление демо-машины, включая создание машины из её бэкапа, могут вернуть VIBE_DEMO_EXPIRED (HTTP 403). Другие регионы и существующие машины без отметки демо сохраняют прежнюю модель доступа.

FIX-0914-10: поля очереди открытой линии отказывают понятно вместо ошибки портала

Было

Справочник полей и бессессионное знакомство агента перечисляли у конфигураций открытых линий все 95 полей, включая queue, queueFull, queueUsersFields и queueOnline. Имя одного из этих четырёх в select, filter или sort у GET /v1/openline-configs и POST /v1/openline-configs/search уезжало в Битрикс24 и возвращалось ответом портала 422 BITRIX_ERROR с текстом An unknown field 'QUEUE' is passed in the PARAMS field 'select' — в написании, которого клиент не отправлял, и без указания, где поле всё-таки читается.

Стало

Обе ручки отказывают до вызова Битрикс24: 400 UNSUPPORTED_LIST_FIELD. Сообщение называет написание, которое прислал клиент, позицию (select, filter или sort), все четыре поля границы и маршрут, который их отдаёт, — GET /v1/openline-configs/:id. Та же граница теперь записана в описаниях этих полей в GET /v1/openline-configs/fields и в разделе сущности у GET /v1/guide. Набор полей в ответах списка и поиска не изменился: этих четырёх там не было и раньше.

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

Действий не требуется. Запрос, который раньше получал 422, теперь получает 400 с адресом рабочего маршрута; успешные вызовы не затронуты.

FIX-0914-11: партнёрская NFR-лицензия распознаётся как коммерческая

Было

При расхождении данных о лицензии в Битрикс24 GET /v1/me мог вернуть для партнёрской NFR-лицензии data.tariff.code со значением бесплатного тарифа и data.tariff.isCommercial: false. Коммерческие возможности при этом отображались недоступными.

Стало

GET /v1/me распознаёт такую лицензию по коду nfr, возвращает data.tariff.isCommercial: true и оценивает возможности как для коммерческого тарифа.

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

Изменять клиент не требуется. После обновления снимка тарифа прежний ошибочный запрет снимается автоматически.

FIX-0914-12: вызов метода 1С принимает ответ модуля 1С в его фактическом формате

Было

Вызов POST /v1/onec/tools/{method}/call доходит до модуля 1С. Модуль отвечает на getData документом {"data": [...], "errors": []} — массив строк и параллельный массив ошибок. Платформа ждала только конверт {"success": true, "data": {...}} и отвергала такой ответ целиком: операция заканчивалась статусом failed с кодом ONEC_INVALID_INLINE_RESULT, хотя модуль вернул HTTP 200 и настоящие данные. Строки терялись, и отличить эту ситуацию от недоступности 1С по ответу API было нельзя.

Стало

Платформа принимает оба конверта. Ответ {"data": [...], "errors": []} переводится в стандартный результат операции: сам массив становится rows, а columns — это объединение ключей всех строк страницы в порядке первого появления. Если ключей не нашлось ни в одной строке — в том числе когда страница пуста, — платформа возвращает в columns набор, запрошенный в вызове, а при его отсутствии пустой список. Признак truncated выводится из заполненности страницы — страница, в которой строк не меньше, чем запрошено в limit, помечается усечённой и отдаёт nextOffset, равный смещению запроса плюс число возвращённых строк; более короткая страница считается последней и отдаёт nextOffset: null. Непустой errors становится доменной ошибкой операции: платформа берёт код из первого элемента, когда он назван одним из документированных (METHOD_NOT_FOUND, ACCESS_DENIED, INVALID_FILTER, TIMEOUT и прочие), иначе сообщает INTERNAL. Ответ, уже соответствующий контракту, обрабатывается ровно как раньше.

NEW-0914-13: ответ внешнего API приложений несёт X-Vibe-Request-Id

Ответ канала ANY /v1/applications/{id}/api/** теперь может нести заголовок X-Vibe-Request-Id со сквозным идентификатором вызова — тем же, который платформа записывает в свой журнал. Указывайте его значение при обращении в поддержку.

Заголовок есть ровно тогда, когда идентификатор был выдан, то есть вызов дошёл до туннеля и туннель ответил: на ответе самого приложения с любым его статусом, а также на отказах 503 APP_API_UNAVAILABLE и 502 APP_API_RESPONSE_TOO_LARGE, пришедших ответом туннеля, и на 502 APP_API_BAD_ENVELOPE.

Заголовка нет там, где идентификатор ещё не существовал или ответ туннеля не дошёл: 401 и 403 по ключу, 429 APP_API_RATE_LIMITED, 409 APP_API_NOT_ENABLED, 403 APP_API_NOT_GRANTED, 404 APP_API_APP_NOT_FOUND, 400 APP_API_BAD_PATH, 413 APP_API_PAYLOAD_TOO_LARGE, а также 504 APP_API_TIMEOUT и те 503 APP_API_UNAVAILABLE / 502 APP_API_RESPONSE_TOO_LARGE, которые платформа вынесла сама (приложение недоступно, канал насыщен, туннель не отвечает, ответ не влез в потолок на нашей стороне).

Из этого следует правило для клиента: различает не код ответа, а наличие заголовка — один и тот же 503 APP_API_UNAVAILABLE приходит и с ним, и без. Заголовок необязательный, обрабатывайте его отсутствие как штатный случай.

Всё остальное в ответе прежнее — статус, тело и остальные заголовки не изменились, менять в клиенте ничего не нужно.

BC-0914-14: у `Idempotency-Key` на создании сервера появилось окно реплея в 15 минут

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

Было

POST /v1/infra/servers реплеил создание по Idempotency-Key бессрочно: пока строка сервера жива, тот же ключ возвращал 201 с заголовком Idempotent-Replayed независимо от того, сколько времени прошло. Реплей при этом минует предпроверку прав на создание целиком — включая отказы, не зависящие от числа машин: недоступный регион, нечитаемый тариф портала, тариф вне разрешённого списка. Портал, потерявший право создавать серверы, всё равно получал 201 по старому ключу.

Стало

Реплей действует 15 минут с момента создания машины. После окна тот же ключ реплей не даёт: запрос идёт как новое создание и проходит все проверки прав — то есть портал без права создания получит обычный отказ (402 / 403), а не машину.

Повторить создание старым ключом нельзя и тогда, когда права в порядке: ключ израсходован и отвечает 409 IDEMPOTENCY_KEY_ALREADY_USED. Текст ответа говорит, что именно произошло: сервер удалён — берите новый ключ; сервер существует — сначала найдите его через GET /v1/infra/servers, иначе оплатите вторую машину рядом с первой.

Одно ограничение остаётся прежним и не связано с окном: ПЕРВОЕ создание в галактике ключом не защищено — он там не резервируется вовсе. Это отдельная известная дыра, она была и до изменения. При этом ключ, уже израсходованный прежним standalone-созданием, на galaxy-пути теперь отвергается с 409, а не игнорируется молча.

Что делать интегратору: на повтор после долгой паузы сначала проверьте GET /v1/infra/servers, не создал ли сервер первый запрос, и повторяйте только если его там нет. Если всё же повторяете вслепую — шлите ТОТ ЖЕ Idempotency-Key, а не новый: для standalone-создания он вернёт либо сам сервер, либо 409 IDEMPOTENCY_KEY_ALREADY_USED, чей текст скажет, существует сервер или удалён. ⚠️ На galaxy-размещении и этого мало: первое создание там ключ не резервирует, поэтому повтор даже с тем же ключом может дать второй ресурс — для галактики проверка через GET обязательна, а не желательна.

FIX-0914-15: OpenAPI различает личный ключ и ключ OAuth-приложения

Было

Все операции в GET /v1/openapi.json несли одну схему авторизации security: [{ apiKey: [] }], а её описание говорит, что заголовок X-Api-Key принимает и личный ключ (vibe_api_…), и ключ приложения (vibe_app_…), и управляющий ключ (vibe_live_…). Для маршрутов, которые Битрикс24 привязывает к ПРИЛОЖЕНИЮ, это неправда: операции сущностей bizproc-templates, bizproc-robots, bizproc-activities отвечают личному ключу 403 OAUTH_REQUIRED, а GET /v1/triggers — 403 BITRIX_ACCESS_DENIED. Коды отказа в спеке уже названы, но семейство ключа оставалось машинно неотличимым, и сгенерированный по спеке клиент узнавал его только по отказу.

Стало

Такие операции объявляют собственное требование авторизации — пару схем oauthAppKey (ключ приложения vibe_app_… в заголовке X-Api-Key) и oauthSession (сессионный токен vibe_session_… из POST /v1/oauth/token в заголовке Authorization: Bearer); обе схемы стоят в одном объекте требования, то есть нужны оба заголовка сразу. Операции, которым личный ключ подходит, остались на прежней схеме — в том числе POST /v1/triggers/fire и GET /v1/workflows из того же скоупа bizproc. Заодно поправлено описание 403 у POST /v1/triggers/fire: оно утверждало, что запуск триггера тоже требует контекста приложения, хотя личный ключ там работает.

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

Поведение API не изменилось: те же вызовы отвечают теми же кодами, что и раньше, ответ 200 остаётся 200. Изменился только машинный контракт, поэтому клиент, сгенерированный заново, попросит для этих операций ключ приложения с сессионным токеном ещё на этапе сборки, а не в рантайме. Список таких сущностей отдаёт GET /v1/me в поле api.entityApi.oauthOnlyEntities.

FIX-0914-16: нативные имена пользовательских полей сохраняются в узкой выборке

Было

При запросе CRM-сущности с select=id,UF_CRM_... значение пользовательского поля могло отсутствовать в ответе, хотя было сохранено в Битрикс24. Правило в GET /v1/me не объясняло, что динамические имена не проверяются как неизвестные поля схемы.

Стало

Нативное имя UF_CRM_... переводится в написание, которое принимает выбранный метод Битрикс24, и проецирует соответствующий ключ пользовательского поля. Это включает имена с цифровым хвостом, которые заводит интерфейс Битрикс24: в camelCase у них сохраняется подчёркивание перед цифрами (UF_CRM_1698325419 → ufCrm_1698325419). GET /v1/me перечисляет классы динамических и method-specific имён, которые нельзя проверить по статической схеме; отсутствие такого ключа в узкой выборке само по себе не означает пустое сохранённое значение или корректное для метода написание.

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

Менять запросы не нужно. Узкая выборка с нативным именем UF_CRM_... теперь возвращает сохранённое значение поля; ключ в ответе по-прежнему имеет написание, принятое выбранным методом Битрикс24.

FIX-0914-17: подключение приложений через Connect к коробочным порталам

Было

Подключение приложения через Connect к коробочному порталу без привязки к Битрикс24.Network останавливалось с PORTAL_NOT_LINKED.

Стало

Коробочные порталы выпускают ключ через коннектор портала или ключ разработчика пользователя, без Битрикс24.Network. Если ключ разработчика не настроен, экран согласия объясняет, что нужно настроить. Права ключа соответствуют согласию пользователя. Для облачных порталов сохраняется выпуск через Битрикс24.Network; для прав только vibe:* вебхук не требуется.

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

Настройки Connect-приложений и OAuth-процесс менять не требуется. Пользователю коробочного портала может понадобиться настроить свой ключ разработчика в кабинете Вайбкод.

Затронутые эндпоинты: GET /v1/connect/authorize, POST /v1/connect/device/authorize, POST /v1/connect/token.

FIX-0914-18: карточка выделенного сервера возвращает установленный рантайм после успешного деплоя

Было

После успешного POST /v1/infra/servers/:id/deploy с полем runtime на выделенном сервере запрос GET /v1/infra/servers/:id отдавал data.runtimeId: null, хотя шаг runtime проходил и приложение отвечало. Документация это поле уже обещала заполненным, поэтому повторный деплой «ради установки рантайма» выглядел необходимым, хотя рантайм уже стоял. У galaxy-приложения то же поле после успеха заполнялось.

Стало

После успешного деплоя на выделенный сервер GET отражает runtime из этого запроса, например python311. Поле runtime на выделенном сервере остаётся необязательным, и запрос без него прежнее значение не затирает. Провалившийся деплой поле по-прежнему не заполняет, даже если шаг runtime успел пройти. Ответ деплоя остаётся HTTP 200, набор шагов не меняется, runtimeStatus остаётся устаревшим и пустым. Уже накопившиеся пустые значения этим исправлением не заполняются — заполнит первый успешный деплой с runtime.

BC-0914-19: поле model в чате больше не подбирает модель по подстроке

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

Было

POST /v1/chat/completions принимал в model часть идентификатора и выбирал первую по порядку каталога модель, в идентификаторе которой встречалась эта подстрока. Запрос мог выполниться и тарифицироваться на другой модели, чем была названа, а о подмене говорило только поле model ответа.

Стало

model сопоставляется с каталогом только целиком. Подходит полный идентификатор или тот же идентификатор без префикса провайдера: bitrixgpt-5.5 находит bitrix/bitrixgpt-5.5. Модель, найденная по короткому имени, отмечается в ответе заголовком X-Model-Resolved с полным идентификатором. Идентификатор, который лишь входит в более длинный, и короткое имя, подходящее нескольким моделям, получают 404 ai_model_not_found.

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

Передавайте в model полный идентификатор из GET /v1/models. Если в ответах приходит заголовок X-Model-Resolved, замените короткое имя на его значение.

FIX-0914-20: пользовательские поля смарт-процесса отвечают кодом отказа портала, а не «не найден»

Было

Пять операций с пользовательскими полями смарт-процесса — GET, POST /v1/items/{entityTypeId}/userfields и GET, PATCH, DELETE /v1/items/{entityTypeId}/userfields/{id} — перед действием запрашивают у портала внутренний номер смарт-процесса по его entityTypeId. Если Битрикс24 отвечал на этот запрос отказом — превышен лимит обращений, портал недоступен или не ответил вовремя, — клиент получал 404 SMART_PROCESS_NOT_FOUND, как будто смарт-процесса нет. Ответ «не найден» повторять не принято, а клиент мог решить, что смарт-процесс удалён, и создать его заново.

Стало

Отказ портала на этом шаге отвечает так же, как на любом другом обращении к порталу: 429 RATE_LIMITED (в том числе для лимита, который портал присылает со статусом 503) и 503 BITRIX_TIMEOUT — с заголовком Retry-After, 502 BITRIX_UNAVAILABLE — без него. Запрос к полям при таком отказе на портал не отправляется. Успешный ответ по-прежнему 200 (у POST — 201, у DELETE — 204 без тела). 404 SMART_PROCESS_NOT_FOUND означает, что портал такого entityTypeId не знает или не вернул его внутренний номер, — а не то, что портал был недоступен. Псевдоним /v1/userfields/invoices (Смарт-счета) внутренний номер не запрашивает и не менялся. Кроме того, у всех операций, запрашивающих внутренний номер смарт-процесса (включая PATCH, DELETE /v1/smart-processes/{id} и пакетную правку или удаление через POST /v1/smart-processes/batch), ответ портала со статусом 5xx больше не принимается за «не найден», даже если его текст содержит такие слова — например, страница «Страница не найдена», которую отдаёт прокси недоступной коробки: такой ответ приходит как 502 BITRIX_UNAVAILABLE. Подробности по кодам — на странице Ошибки.

BC-0914-21: ответ по предложению без служебных полей Битрикс24, поле contacts помечено как не возвращаемое

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

Было

GET /v1/quotes/{id} (а также список, поиск и include) отдавал 17 полей, которых нет ни в описании, ни в справочнике: служебную строку полнотекстового индекса Битрикс24 searchContent (в ней — название транслитом и имя ответственного), дубли дат «для отображения» (dateCreateShort, dateModifyShort, begindateShort, closedateShort), внутренние коды contentType, termsType, commentsType, entityTypeId, пустой hasProducts и семь колонок реквизитов клиента clientTitle, clientAddr, clientContact, clientEmail, clientPhone, clientTpId, clientTpaId — через API они не заполняются даже у предложения с привязанными компанией и контактом, а присланное значение отбрасывается. Объявленное поле contacts не приходило никогда, при этом select=contacts принимался и отвечал 200 без этого ключа. У GET /v1/invoices/{id} в ответ попадал служебный entityTypeId, а lastActivityTime приходил со смещением +03:00, тогда как остальные даты записи — в UTC.

Стало

Семнадцать служебных полей предложения из ответа исключены; ответ на чтение остаётся 200. Поле contacts в описании и справочнике помечено как не возвращаемое (notReturned): item-API Битрикс24 не отдаёт его у предложений, привязанные контакты — в contactIds; попытка записать contacts по-прежнему отвечает 400 READONLY_FIELD, а select=contacts теперь отвечает 400 SELECT_FIELD_NOT_RETURNED вместо 200 без ключа. У счёта entityTypeId из ответа исключён, lastActivityTime объявлен полем только для чтения и приходит в UTC, как остальные даты записи; в filter и order он, как и прежде, не принимается, а присланное на запись значение, которое Битрикс24 и раньше не сохранял, теперь отклоняется: создание и изменение — 400 READONLY_FIELD, импорт — 400 IMPORT_ITEM_VALIDATION, пакетный запрос сущности — 400 BATCH_ITEM_VALIDATION, общий пакетный запрос — READONLY_FIELD под вызовом в data.errors.

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

Если вы читали служебные поля предложения (searchContent, *Short, contentType, termsType, commentsType, entityTypeId, hasProducts, client*) — их больше нет; полнотекстовый поиск ведите фильтром title, реквизиты клиента берите из привязанных контакта и компании по contactId и companyId. Если в select предложения был contacts — уберите его (в том числе в подвызовах пакетных запросов): поле никогда не возвращалось, привязки — в contactIds. Если вы отправляли lastActivityTime счёта — уберите его из тела: его проставляет Битрикс24. Отправка client* при создании или изменении, как и раньше, игнорируется порталом — платформа предупреждает об этом подсказкой UNRECOGNIZED_WRITE_FIELD.

Затронутые эндпоинты: GET /v1/quotes/{id}, GET /v1/quotes, POST /v1/quotes/search, GET /v1/quotes/fields, GET /v1/invoices/{id}, GET /v1/invoices, POST /v1/invoices/search, GET /v1/invoices/fields, POST /v1/invoices, PATCH /v1/invoices/{id}, POST /v1/{entity}/batch, POST /v1/batch.

NEW-0914-22: рассуждение прошлых ответов в истории чат-комплишена

POST /v1/chat/completions принимает у сообщений ассистента поле reasoning_content — рассуждение модели из прошлого ответа, возвращённое в историю диалога. Часть моделей с рассуждением в диалоге с функциями читает рассуждения прошлых ходов ассистента и без них теряет нить между вызовами. Раньше поле молча отбрасывалось.

Поле доходит до модели, у которой owned_by в GET /v1/models равно bitrix, openrouter или vibecode. Моделям OpenAI, Anthropic и других OpenAI-совместимых провайдеров оно не передаётся: их API такое поле не принимают. У сообщений других ролей поле игнорируется, null равнозначен отсутствию поля, пустая строка допустима. Модель, которая читает рассуждение, учитывает его во входных токенах. Значение не строкой или длиннее 4 000 000 символов отклоняется с 400 invalid_request.

FIX-0914-23: описания частоты называют суммарный лимит и указывают на заголовок с действующим значением

Было

Страницы справки и машинная схема GET /v1/openapi.json называли предел частоты одним числом — 60 запросов в минуту у POST /v1/search, 20 у POST /v1/research, 30 у POST /v1/batch, 600 и 120 у чтения уведомлений, 120 у настроек календаря, 30 у записей рабочего дня, 20 у ресурсов бронирования, 10 и 30 у ключей AI-провайдеров, 10 у SSH-доступа, значка приложения, порта, расписаний пробуждения и операций Deploy API, 6 у снятия зависшей блокировки, 60 у опроса статуса операции, 20 у комментариев к обращению и 60 у публичной ссылки хранилища. Запросы обслуживает несколько процессов платформы, каждый держит свою долю предела, поэтому ни одно из этих чисел клиенту не приходило: заголовок x-ratelimit-limit отдавал меньше, и клиент, закрепивший число из описания, получал 429 раньше, чем ожидал. Тем же одним числом описывались Partner Connect и коннектор 1С: 30 запросов в минуту у GET /v1/connect/authorize, 60 у POST /v1/connect/token, 60 у POST /v1/connect/revoke и 120 у чтения операций коннектора 1С. Так же одним числом был описан внешний API приложения (ANY /v1/applications/:id/api/*) — 120 запросов в минуту на ключ, и в таблице ограничений на странице справки, и в подсказках для агентов /v1/guide и /v1/me.

Стало

Каждое такое описание называет число суммарным и рядом указывает источник действующего значения — заголовок ответа x-ratelimit-limit, — а также говорит, что предел делится между процессами платформы. То же исправление внесено в описания отказа 429 машинной схемы. Отдельно помечен предел, который НЕ делится и приходит клиенту ровно как назван: выпуск токенов доступа TOKEN_MINT_RATE_LIMIT (50 в час на API-ключ). Предел активации пробного периода Маркетплейса пометки не несёт и по устройству в ней не нуждается: его потолок домножен на число процессов платформы, поэтому клиент получает ровно напечатанные 3 в час при любом их числе. В схеме он огласован двумя формами — «3 per hour per portal» и «3 per hour per Bitrix24 account». Указание на заголовок получили и описания выше — Partner Connect (страница справки и схема, включая отзыв ключа) и коннектор 1С. Оговорку получил и внешний API приложения — во всех трёх местах сразу. Рядом помечен ещё один предел, который между процессами НЕ делится: зона ограничения на краю у POST /v1/connect/token — 20 запросов в минуту на адрес вызывающего. Она считает до распределения запроса по процессам, отвечает конвертом RFC 6749 и заголовка x-ratelimit-* не ставит, поэтому его отсутствие и отличает её от предела самого маршрута.

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

Поведение эндпоинтов не менялось, ответы прежние — исправлено описание, которое расходилось с ними. Клиент, читавший x-ratelimit-limit, не меняет ничего. Клиент, закрепивший число из описания в коде, должен перейти на заголовок: суммарное число делится между процессами и меняется без записи в журнале.

FIX-0914-24: ступень рассуждения по умолчанию передаётся модели явно

Было

Если в запросе к POST /v1/chat/completions не было ни reasoning_effort, ни reasoning, ни chat_template_kwargs, в модель с декларацией рассуждения ничего не добавлялось, и режим определял провайдер модели. При обновлении модели на его стороне этот режим мог смениться. Поле reasoning ответа при этом сообщало ступень default из декларации.

Стало

Платформа передаёт модели ступень default из поля reasoning ответа GET /v1/models явно, поэтому поведение запроса без параметра не зависит от обновлений на стороне провайдера. Явно запрошенная ступень по-прежнему важнее default. Поле reasoning ответа и заголовки X-Reasoning-Applied и X-Reasoning-Native описывают переданную ступень. У моделей с reasoning: null ничего не меняется.

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

Менять ничего не нужно. Чтобы включить рассуждение в запросе, передайте reasoning_effort или объект reasoning. Ступень, которая применяется без параметра, показывает reasoning.default модели.

BC-0914-25: внешний API приложений отвечает на таймаут статусом 503, а не 504

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

Было

Приложение не ответило за общий предел вызова — ANY /v1/applications/{id}/api/** отдавал 504 с кодом APP_API_TIMEOUT и без заголовка Retry-After.

Стало

Тот же исход приходит статусом 503 с кодом APP_API_TIMEOUT и заголовком Retry-After в секундах. Код отказа не изменился, поэтому таймаут по-прежнему отличим от APP_API_UNAVAILABLE, который означает недоступный или насыщенный канал. Статуса 504 этот адрес больше не отдаёт вовсе: увидели его — он пришёл от промежуточного узла на пути к платформе, а не от платформы Вайбкод.

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

Переведите ветку обработки таймаута со статуса на код отказа: читайте error.code, а не 504. Клиент, который уже ветвится по error.code, менять не нужно. Клиент, который считал 503 безусловно повторяемым, получит по таймауту Retry-After — но повтор неидемпотентного вызова по-прежнему опасен: приложение могло довести работу до конца после того, как канал перестал ждать.