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

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

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

BC-0909-1: Расшифровка аудио сохраняет тарификацию по подписке при отключении Cowork/Code

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

Было

При отключённом Cowork/Code запросы к POST /v1/audio/transcriptions уже выданным ключом vibe:cowork обходили квоту подписки, даже если подписка была активна и для доступной модели была назначена цена аудио. Исчерпание квоты подписки не препятствовало успешному ответу HTTP 200.

Стало

Отключение продукта не меняет тарификацию: при активной подписке и назначенной цене аудио за минуту или за вызов расход учитывается в её квоте, как у чата. При исчерпании окна запрос получает HTTP 402 cowork_quota_exhausted с заголовком Retry-After. Без активной подписки сохраняется прежний путь тарификации без списания квоты подписки.

Что изменить в интеграции

Обрабатывайте HTTP 402 cowork_quota_exhausted и при отключённом продукте: дождитесь сброса окна по Retry-After или увеличьте тариф подписки. Ключ и формат запроса менять не требуется.

NEW-0909-2: Идентификаторы методов каталога 1С поддерживают Unicode

GET /v1/onec/tools и POST /v1/onec/tools/{method}/call поддерживают идентификаторы методов из букв, комбинируемых знаков и чисел Unicode, а также ._-. Предел — 100 кодовых единиц UTF-16. Передавайте в URL точный идентификатор из каталога через encodeURIComponent(method): регистр и Unicode-представление сохраняются. Существующие латинские идентификаторы продолжают работать.

BC-0909-3: Универсальные списки: отсутствующий список отвечает «не найдено», а неверное смещение — ошибкой

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

Было

Один и тот же несуществующий список отвечал по-разному в зависимости от того, какой адрес дёрнуть: перечень элементов, перечень полей, набор типов полей, отдельный элемент, отдельное поле и файлы элемента отвечали 422 с текстом от Битрикс24 — то есть ошибкой «что-то пошло не так», а не «такого списка нет». Логика «прочитать, а если нет — создать» на этом ломалась.

Постраничный обход тех же перечней принимал любое значение смещения. start=-5, start=abc, start=1.5 и start=1e2 не отклонялись: смещение молча не применялось либо применялось искажённым (1e2 превращалось в 1, и вместо сотой записи приходила вторая). Ответ при этом был 200, поэтому ошибка в вызывающем коде оставалась невидимой — при том что соседние параметры того же запроса, iblockTypeId и sort, отклоняются с внятным сообщением.

Стало

Отсутствующий список отвечает 404 с кодом LIST_NOT_FOUND на шести адресах, где Битрикс24 сообщает об этом машинным кодом. Смещение принимается только как неотрицательное целое в обычной записи; всё прочее отклоняется 400 с кодом INVALID_PARAMS, и в сообщении назван именно тот параметр, который не подошёл. Проверяются оба параметра, start и offset, даже когда спор о старшинстве между ними выигрывает первый.

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

Если ваш код ловил 422 от перечней списков как «списка нет» — переведите его на 404. Распознаётся машинный код Битрикс24, а не текст сообщения, поэтому ответ не зависит от языка портала. Сам код замерен на международной платформе: если ваш портал сообщает об отсутствии списка иначе, распознавание не сработает и ответ останется прежним. Если смещение собиралось из внешнего источника и могло прийти отрицательным или дробным, теперь вместо страницы придёт ошибка: почините источник, а не обход. Отдельно назовём один вход, который прежде понимался ВЕРНО: ?start=+5 — плюс в строке запроса декодируется пробелом, и прежний разбор читал такое как 5. Теперь это отказ. Если ваш сборщик кодирует плюсом, уберите его: ?start=5.

Отдельно про запись параметров квадратными скобками. ?start[]=7 и ?iblockTypeId[]=lists раньше проходили: платформа склеивала такой список в одно значение и работала дальше. Теперь это отказ — скобки означают структуру, а перечисленные параметры структуру не принимают. Если ваш сборщик запроса ставит скобки автоматически на всякий список, передавайте эти три параметра простым значением: ?start=7, ?offset=7, ?iblockTypeId=lists. Скобочные формы с именем внутри (?start[x]=1) прежде роняли запрос внутренней ошибкой — теперь на них приходит понятный отказ.

Ещё один параметр в том же ряду — набор возвращаемых полей: ?select[x]=1 прежде роняло запрос внутренней ошибкой, теперь набор просто не применяется и приходит полный состав полей; пустые элементы вида ?select[]=&select[]=NAME больше не уезжают в портал пустой строкой.

То же касается тела запроса при создании раздела и элемента: "iblockSectionId": [5] раньше принималось за пятёрку и клало запись под этого родителя, теперь значение отбрасывается и запись попадает в корень. Присылайте число или строку с числом.

Тип инфоблока в теле сузился так же, только отвечает иначе: "iblockTypeId": ["lists"] раньше проходил (список склеивался в одно значение), теперь приходит 400 с кодом INVALID_IBLOCK_TYPE — на восьми адресах, где этот параметр вообще читается из тела: создание и изменение списка, поля, раздела и элемента. Удаления его не принимают и не затронуты. Присылайте строку: "iblockTypeId": "lists".

Чего правка НЕ меняет

Чтение разделов по-прежнему отвечает жалобой на неверный тип инфоблока, а чтение самого списка — отказом в правах, если номер списка числовой. По символьному номеру этот же адрес отвечал «не найдено» и до правки: там Битрикс24 возвращает пустой результат, а не отказ. Битрикс24 сообщает об отсутствии списка на этих адресах теми же словами, что и о настоящей нехватке прав и о настоящем неверном типе, поэтому распознавать их как «не найдено» означало бы прятать реальные отказы.

BC-0909-4: фантомное поле contacts удалено у компаний, лидов и сделок

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

Было

Схема полей и ответы компаний, лидов и сделок могли содержать contacts, хотя это поле нельзя было надёжно прочитать из Битрикс24. Явный select: ["contacts"] принимался и отвечал 200.

Стало

contacts не публикуется в схеме полей и не возвращается в записях. Явный select: ["contacts"] без * или UF_* отклоняется с 400 UNKNOWN_SELECT_FIELD. Запрос всех полей через * или UF_* по-прежнему выполняется, но contacts из ответа удаляется.

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

Удалите contacts из явных списков select. Для связей с контактами у компаний используйте contactIds, а у лидов и сделок — contactId и contactIds.

Затронутые эндпоинты: GET /v1/companies/fields, GET /v1/leads/fields, GET /v1/deals/fields, операции чтения и записи из разделов компаний, лидов и сделок, POST /v1/batch, POST /v1/{entity}/batch.

FIX-0909-5: на коробочном портале выписывается ключ, которому вебхук не нужен

Было

На коробочном портале у владельца без ключа разработчика выдача и перевыпуск ключа с правами только vibe:* (например vibe:infra + vibe:storage) отвечали 400 BOX_NO_DEVELOPER_KEY, хотя входящий вебхук такому ключу на портале не регистрируется вовсе. Затрагивало POST /v1/keys, POST /v1/keys/{id}/rotate и выдачу личного ключа приложения Коворка.

Стало

Набор прав без единого права Битрикс24 проверяется раньше коробочного гейта: ключ выдаётся, поле webhookUrl остаётся пустым, к порталу обращений нет. Отказ 400 BOX_NO_DEVELOPER_KEY сохраняется для наборов, где хотя бы одно право Битрикс24 есть, — такому ключу вебхук нужен, а снять его без ключа разработчика владельца нечем. Перевыпуск требует ещё одного условия: у прежней строки не должно остаться вебхука. Ключ без прав Битрикс24, за которым вебхук всё же числится, отвечает прежним 400 — снять этот вебхук без ключа разработчика нечем, и успешный ответ скрыл бы, что прежний доступ продолжает работать.

FIX-0909-6: замена ключа приложения больше не выдаёт секрет с истёкшим сроком

POST /v1/cowork/applications/{id}/key переносил срок жизни заменяемого ключа на новый как есть. Если срок уже прошёл, владелец получал секрет, не проходящий ни одного запроса, а прежний протухший ключ получал сутки жизни и на эти сутки снова начинал работать.

Было

Приложение с ключом, срок которого истёк три дня назад. Ответ 201, issued: "rotated", key.expiresAt — та же прошедшая дата, previousKey.graceUntil — сутки вперёд от момента замены.

Стало

Ответ по-прежнему 201, issued: "rotated". key.expiresAt отсчитывается заново по сроку, принятому на портале (его же отдаёт GET /v1/cowork/applications/defaults полем keyExpiresInDays), — новый ключ работает. previousKey.graceUntil не превышает собственного срока заменяемого ключа: у протухшего он остаётся в прошлом, и суточная отсрочка его не воскрешает. Действующий срок и его отсутствие переносятся как раньше — бессрочный ключ остаётся бессрочным, живой срок повторяется один в один.

Та же поправка к отсрочке действует у POST /v1/keys/{id}/rotate: перевыпуск ключа с истёкшим сроком больше не даёт прежнему ключу сутки работы.

FIX-0909-7: публичный числовой адрес в baseUrl и proxyUrl больше не отбивается как частный

Было

POST /v1/ai/credentials и PATCH /v1/ai/credentials/{id} с публичным числовым адресом в baseUrl или proxyUrl — например http://203.0.113.10:8080 — отвечали 400 с кодом BASE_URL_PRIVATE или PROXY_URL_PRIVATE. Сохранить такой ключ удавалось, только записав тот же адрес доменным именем.

Стало

Такой запрос отвечает успешно — как и с доменным именем. Частный числовой адрес по-прежнему получает 400 с теми же кодами: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 100.64.0.0/10, 127.0.0.0/8, 169.254.0.0/16, 0.0.0.0/8, а для IPv6 — ::1, ::ffff:, fc00::/7 и fe80::/10. Только для числовых адресов к этому перечню добавились зарезервированные диапазоны, которыми числовой адрес раньше пройти не мог в принципе: 192.0.0.0/24, 198.18.0.0/15, 224.0.0.0/4, 240.0.0.0/4 (вместе с 255.255.255.255), а для IPv6 — fec0::/10, ff00::/8 и 100::/64. Для доменных имён перечень запрещённых диапазонов не менялся: имя, ведущее в любой из этих зарезервированных диапазонов, работает как работало, и запрос с доменным именем отвечает успешно, как прежде. Исключение — адреса, встраивающие IPv4 в IPv6-форму (::a.b.c.d, NAT64 64:ff9b::/96, 6to4 2002::/16): они отбиваются одинаково, и когда записаны числами, и когда имя ведёт на такой адрес.

FIX-0909-8: спека объявляет отказ 429 у ручек с собственным лимитом частоты

Было

Двадцать шесть операций несут собственный лимит частоты и отвечают 429 RATE_LIMITED, когда он исчерпан, а публичная спека GET /v1/openapi.json этот ответ у них не объявляла. Клиент, собранный по спеке, считал 429 неописанным статусом и не строил ветку повтора запроса вовсе. Затронуты POST /v1/batch, GET /v1/bots/:botId/events, GET /v1/chats/recent, POST /v1/chats/events/subscribe, GET /v1/connect/authorize, POST /v1/connect/token, POST /v1/connect/revoke, GET /v1/app/blueprints/:slug, GET /v1/me/sources, POST /v1/feedback/attachments, GET /v1/workday/records и пятнадцать ручек инфраструктуры — POST /v1/infra/servers, GET /v1/infra/servers/:id/ssh, POST /v1/infra/servers/:id/reboot, PATCH /v1/infra/servers/:id/sleep, PATCH /v1/infra/servers/:id/port, POST /v1/infra/servers/:id/wake-schedules, PATCH /v1/infra/servers/:id/wake-schedules/:scheduleId, DELETE /v1/infra/servers/:id/wake-schedules/:scheduleId, POST /v1/infra/servers/:id/sources, POST /v1/infra/servers/:id/exec, POST /v1/infra/servers/:id/upload, POST /v1/infra/servers/:id/icon, GET /v1/infra/servers/:id/logs, POST /v1/infra/servers/:id/deploy и POST /v1/infra/servers/:id/unstick.

Стало

У каждой из этих операций отказ 429 объявлен в спеке. Описание отправляет за действующим значением в заголовок ответа x-ratelimit-limit, а за сроком повтора — в Retry-After. Число в спеку не вписано намеренно: заголовок — единственный источник, который не расходится с настройкой. У POST /v1/infra/servers, POST /v1/infra/servers/:id/upload и POST /v1/infra/servers/:id/deploy на этом же статусе назван второй код DEPLOY_BACKEND_BUSY — он приходит, когда заняты все места под встроенное тело запроса, отказывает конкретному телу, а не вызывающему, и несёт Retry-After: 30. Общие сведения о лимитах остаются на странице лимитов.

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

Лимиты и поведение ручек не менялись, менять запросы не нужно. Клиенту, сгенерированному из спеки до этой правки, стоит пересобрать его — тогда обработка 429 появится там, где раньше отказ приходил как неописанный.

FIX-0909-9: истёкший пользовательский токен OAuth возвращает ошибку авторизации

Было

Если приложение не могло обновить истёкший пользовательский токен, отказ Битрикс24 expired_token возвращался из V1 API как 422 BITRIX_ERROR, то есть как ошибка данных запроса.

Стало

Одиночный вызов V1 API возвращает 401 TOKEN_EXPIRED с подсказкой повторно открыть приложение из меню Битрикс24. В пакетном вызове код TOKEN_EXPIRED приходит в ошибке отдельного вызова, а общий HTTP-ответ остаётся 200. Подробнее: ошибки API.

FIX-0909-10: отказ по частоте на выдаче токена стал машиночитаемым

Было

При срабатывании ограничителя частоты на входе в платформу POST /v1/connect/token отдавал HTML-страницу и не ставил заголовок Retry-After. Приложение не могло ни разобрать тело, ни узнать, через сколько повторять. Для входа по коду устройства это единственный отказ по частоте, до которого реально доходит живой опрос.

Стало

Тот же отказ приходит с телом в форме RFC 6749 — {"error":"slow_down","error_description":"..."} — и с заголовком Retry-After, который называет минимальную паузу в секундах. Форма совпадает с той, что эндпоинт уже объявляет для остальных отказов, поэтому готовая OAuth-библиотека разбирает её без доработок. Статус ответа остаётся 429, поэтому отказ по частоте по-прежнему отличим от состояний авторизации, которые приходят с кодом 400. Прежние вызовы работают без изменений.

Важно: ограничителей частоты на этом маршруте два, и тела у них разные. В форме RFC 6749, описанной выше, отвечает только ограничитель на входе в платформу. Ограничитель самого эндпоинта отвечает тем же статусом 429, но в общем конверте API — { "success": false, "error": { "code": "RATE_LIMITED", "message": "..." } }, — поэтому ветка вида «на 429 разобрать тело и сравнить error со slow_down» распознает лишь половину отказов, а вторую примет за неизвестную ошибку. Различить ярусы можно по заголовку X-RateLimit-Limit: отказ на входе в платформу его не несёт, отказ самого эндпоинта несёт. Значение Retry-After — минимальная пауза, а не обещание, что следующий запрос примут, поэтому приложению нужно наращивать и собственную паузу. Оба отказа и оба тела описаны в разделе Partner Connect.

FIX-0909-11: reasoning модели для Cowork больше не попадает в финальный текст

Было

Когда Cowork не передавал настройку reasoning явно, модель могла вернуть внутренний рабочий текст как обычную часть финального ответа.

Стало

POST /v1/chat/completions для ключей с областью vibe:cowork применяет объявленную моделью настройку reasoning по умолчанию. Рассуждение остаётся в отдельном канале, а самостоятельный финальный текст сохраняется. Ответ остаётся HTTP 200.

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

Изменения клиентов не требуются. Вызовы без области vibe:cowork сохраняют прежнее поведение.

BC-0909-12: коробочная покупка идёт на кассу своей страны

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

Было

Клиента с коробочной лицензией Беларуси, Казахстана или Узбекистана уводило на российский сайт: другой коробочной кассы не существовало, и платформа намеренно считала такую лицензию российской. Купить там он всё равно не мог — касса отклоняла ключ чужого региона, — то есть путь вёл в тупик без объяснения.

Стало

Когда у страны открыта своя коробочная касса, покупка идёт на её сайт и в её валюте — цены, валюта и адрес оформления берутся из блока своего региона. Пока в каталоге страны нет коробочных позиций, пополнение для таких клиентов недоступно с понятным отказом, а не уводит на кассу, которая всё равно отклонит покупку. Появятся позиции — покупка включится сама.

GET /v1/cowork/subscription/preview для такой лицензии отдаёт валюту своей страны вместо RUB.

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

Читать валюту из ответа, а не подразумевать рубль: currency у пакетов и в корне ответа теперь может быть BYN, KZT или UZS, а пока пополнение для страны недоступно — null при topUpAvailable: false. Суммы приходят в минорных единицах своей валюты — пересчёт в рубли на стороне интегратора даст неверные числа.