Для AI-агентов: markdown этой страницы — /docs-content/changelog/2026-08-28.md индекс документации — /llms.txt
Изменения API: 28 августа 2026
← Журнал изменений · Август 2026
FIX-0828-2: поздняя загрузка по действующей ссылке сохраняет объект
Было
Если загрузка по подписанной ссылке начиналась позднее часа после её выдачи, служебная бронь могла быть удалена раньше окончания срока ссылки. Последующее завершение отвечало 404, а загруженные байты оставались без объекта в API.
Стало
Пустая бронь сохраняется до максимального срока подписанной ссылки. Ответ успешного завершения не изменился; поздняя загрузка по ещё действующей ссылке остаётся связанной с объектом API.
FIX-0828-3: правила листания в GET /v1/guide приходят одним блоком paginationCanon
Было
Правила листания и подсчёта записей повторялись внутри каждой сущности ответа. Поля operations.search.paginationStability и описание параметра operations.search.params.withTotal несли один и тот же текст у всех сущностей.
Стало
Тот же текст приходит один раз, блоком paginationCanon на верхнем уровне ответа. Формулировки перенесены дословно, ни одно правило не переписано и не сокращено. Одноимённые поля внутри сущностей сохранены и содержат указатель на соответствующий пункт paginationCanon.
Исключение — operations.search.paginationStability.counting. Он по-прежнему приходит у каждой сущности со своим текстом, потому что способ узнать точное количество зависит от того, доступна ли этой сущности операция агрегации.
Влияние на интеграторов
Вызовы работают как прежде, ни одно поле ответа не удалено. Если ваш код читал текст правил из полей сущности, возьмите его из блока paginationCanon. Ответ на полном наборе скоупов стал меньше примерно на 37 процентов.
FIX-0828-4: filter и sort комментариев задач принимают camelCase-имена полей
Было
GET /v1/tasks/:taskId/comments принимал в filter и sort только сырые имена полей Битрикс24. Имена authorId и createdAt, в которых те же поля приходят в ответе, давали 400 UNKNOWN_FILTER_FIELD или 400 INVALID_SORT_FIELD.
Стало
Параметры filter и sort принимают camelCase-имена наравне с сырыми: id, authorId, authorName, createdAt, а sort дополнительно authorEmail. Ограничения по типу карточки не изменились: фильтр по authorName и сортировка по authorName или authorEmail по-прежнему принимаются только на старой карточке, на новой отвечают 400. Если filter называет одно поле дважды в разных написаниях имени или знака равенства, приходит 400 INVALID_FILTER. Неизвестные имена по-прежнему возвращают 400.
Влияние на интеграторов
Для фильтрации и сортировки можно использовать authorId и createdAt — те же имена, в которых эти поля приходят в ответе. Менять существующие запросы с сырыми именами не требуется.
BC-0828-5: Исход deploy можно подтвердить после обрыва связи
Поддержка старого формата до: не предусмотрена
Было
Если связь со шлюзом обрывалась во время deploy, клиент не получал исход и идентификатор операции. Повторный deploy мог встретить EXEC_BUSY, но не отвечал на главный вопрос: завершилась ли первая выкладка.
Стало
POST /v1/infra/servers/:id/deploy сохраняет наблюдаемый исход standalone- и galaxy-выкладки, а GET /v1/infra/servers/:id/operations возвращает последние операции текущего API-ключа даже когда терминальный ответ с operationId был потерян. При GATEWAY_UNREACHABLE, GATEWAY_CONNECTION_TERMINATED, GATEWAY_STREAM_ERROR*, GATEWAY_TIMEOUT*, TUNNEL_NOT_FOUND и post-drop обрыве Galaxy исход сохраняется как unknown, а error.hint требует сначала сверить операцию, сервер и логи. Для standalone это одинаково работает и когда транспорт бросил исключение, и когда шлюз прислал timeout/error кадром внутри exec или upload/download; такой неподтверждённый исход несёт error.retryable: false и не запускает внутренний повтор. При подтверждённом EXEC_BUSY standalone-сервер можно восстановить через /unstick только когда выполняющейся операции уже нет; для общего Galaxy-хоста tenant recovery не поддерживается — нужно подождать и при устойчивом отказе обратиться в поддержку.
Что делать интеграторам
При error.retryable: false не отправляйте тот же deploy повторно: сначала прочитайте GET /v1/infra/servers/:id/operations, состояние сервера и логи. Повтор допустим только после устойчивого исхода failed, когда подсказка ответа явно разрешает тот же запрос. Не удаляйте и не пересоздавайте слот при исходе unknown.
FIX-0828-6: создание комментария задачи возвращает правильный числовой ID
Было
На новой карточке задачи POST /v1/tasks/:taskId/comments и POST /v1/tasks/:taskId/comments/batch с action: create могли вернуть id: null для найденного сообщения, если его числовые идентификаторы пришли строками. При нескольких совпадениях строковое сравнение могло выбрать неверный ID.
Стало
Оба эндпоинта возвращают числовой id найденного сообщения и сравнивают совпавшие ID как числа. Ответ одиночного POST по-прежнему остаётся HTTP 201. Ответ batch остаётся HTTP 200, а успешно созданный элемент — success: true.
Если поиск не находит сообщение или не может определить его однозначно, id: null остаётся допустимым успешным результатом: комментарий уже создан, и повторный запрос может создать дубликат.
Влияние на интеграторов
Менять клиент не требуется. Продолжайте поддерживать number | null и не считайте null признаком неудачного создания.
BC-0828-7: незавершённые публичные загрузки больше не доступны анонимно
Поддержка старого формата до: не предусмотрена
Было
Для объекта PUBLIC в состоянии PENDING запрос GET /v1/public-storage/{portalId}/{objectId} отвечал 302, а HEAD /v1/public-storage/{portalId}/{objectId} — 200. Файл становился доступен без аутентификации до завершения загрузки.
Стало
Оба запроса отвечают 404, пока загрузка остаётся в состоянии PENDING. Анонимный доступ открывается только для объекта PUBLIC с завершённой загрузкой.
Что делать интеграторам
После загрузки файла вызовите POST /v1/storage/objects/complete и публикуйте анонимную ссылку только после успешного ответа.
FIX-0828-8: MCP отдаёт содержимое файла Диска вместо ошибки сети
Было
Действие download инструмента manage_file разбирало ответ GET /v1/files/:fileId/download как служебный JSON, хотя этот запрос отдаёт байты файла. На любом реальном файле агент получал success: false с кодом NETWORK_ERROR и текстом Unexpected token … — то есть первые байты уже скачанного файла выдавались за сбой связи. Рабочего ответа у действия не было.
Стало
Действие возвращает content с содержимым файла в base64, а также contentType, size и filename — симметрично тому, как upload принимает content. Файлы больше 10 МиБ отклоняются кодом FILE_TOO_LARGE, и текст ошибки называет способ получить такой файл: запрос к тому же адресу с тем же ключом API. Ответы с ошибкой остаются обычным конвертом платформы: отсутствующий файл — это ENTITY_NOT_FOUND, а не NETWORK_ERROR. Универсальный call_api, который умеет читать только JSON-конверты, теперь заранее отклоняет известные не-JSON маршруты кодом NON_JSON_RESPONSE_UNSUPPORTED, не выполняя заведомо неверный запрос. Так же заранее он отклоняет кодом REDIRECT_ROUTE_UNSUPPORTED браузерные точки входа потоков OAuth и подключения: они отвечают перенаправлением, и запрос к ним уходил вместе с ключом API, а затем следовал за перенаправлением на адрес, который выбирает не платформа. Путь приводится к каноническому виду до проверки, поэтому его написание через .. больше не обходит отказ, а полный адрес вместо пути отклоняется кодом INVALID_PATH. У действия download идентификатор файла теперь обязан быть целым положительным числом: дробное значение приводило к содержимому другого файла, выданному как успешный ответ. Сам REST-запрос по-прежнему отдаёт бинарные данные, поэтому обычные клиенты работают как раньше.
FIX-0828-9: конкурентные прямые загрузки одного объекта согласованы
Было
Одновременные вызовы POST /v1/storage/objects/upload для одного физического адреса приложения могли перемешать содержимое файла и его метаданные.
Стало
Прямые загрузки пути A с ключом приложения выполняются по очереди. После получения очереди ответ по-прежнему остаётся HTTP 200. Если безопасное право записи не подтверждено в пределах 60 секунд или лимита конкурентности, запрос получает 409 STORAGE_KEY_CONFLICT до записи в объектное хранилище. Повторите весь запрос.
Гарантия относится только к пути A с ключом приложения. Она не расширяет поведение личных ключей (appId = null) и путей B/C.
Влияние на интеграторов
Формат успешного ответа не изменился. При STORAGE_KEY_CONFLICT повторяйте исходный запрос целиком.
FIX-0828-10: спецификация ответов создания и обновления отражает идентификатор
Было
Спецификация OpenAPI и примеры ответов для операций создания и обновления обещали полную сущность там, где API возвращает только data.id.
Стало
OpenAPI и документация описывают фактический ответ с data.id. Статусы HTTP 201 для создания и HTTP 200 для обновления, а также поведение API при выполнении запросов не изменились.
Затронутые эндпоинты: POST /v1/bizproc-activities, PATCH /v1/bizproc-activities/:code, POST /v1/bizproc-robots, PATCH /v1/bizproc-robots/:code, POST /v1/bizproc-templates, PATCH /v1/bizproc-templates/:id, POST /v1/calendar-sections, PATCH /v1/calendar-sections/:id, POST /v1/telephony-lines, PATCH /v1/telephony-lines/:number.
Влияние на интеграторов
Существующие запросы менять не нужно. Повторно сгенерированные клиенты теперь видят фактическую форму успешного ответа.
FIX-0828-11: выполнение команд в galaxy-приложении больше не отклоняется до отправки
Было
POST /v1/infra/servers/{id}/exec для galaxy-приложения отвечал 502 с кодом EXEC_FAILED и сообщением о неподдерживаемом безопасном выполнении в контейнере. Отказ приходил на любом приложении и не зависел ни от команды, ни от состояния контейнера: до контейнера запрос не доходил вовсе.
Стало
Команда выполняется в контейнере приложения, и успешный ответ остаётся HTTP 200 с полями exitCode, stdout, stderr и duration — той же формы, что на остальных серверах. Код CONTAINER_NOT_READY для остановленного или отсутствующего контейнера платформа возвращает там, где может подтвердить это состояние; где не может — причина приезжает в stderr результата, а сам ответ по-прежнему HTTP 200.
FIX-0828-12: Устойчивее установка Node.js 20 в шаблонах рантайма
Node.js 20 в шаблонах node20* теперь устанавливается устойчивее при проблемах с внешней сетью.
Было
Шаблон без ограничения выполнял установку через NodeSource. При сетевой ошибке мог быть установлен Node.js 18, после чего деплой завершался только общей ошибкой проверки версии.
Стало
Установка NodeSource выполняется с ограниченными сетевыми попытками и проверкой целостности. При неуспехе его источник временно изолируется, существовавшая конфигурация сохраняется, и используется проверенный резервный архив Node.js 20; идентификаторы рантаймов и API деплоя не меняются.
FIX-0828-13: ZIP-выкладка больше не просит сменить формат архива, если сервер занят другой командой
Было
Пока на сервере выполнялась другая команда, POST /v1/infra/servers/:id/upload с zip и extract: true и выкладка galaxy-приложения из zip отвечали отказом установки unzip (UNZIP_PREFLIGHT_FAILED / ошибка сборки) и советовали пересобрать архив в .tar.gz.
Стало
Кратковременная занятость канала команд сервер повторяет сам. Если канал так и не освободился, ответ — 409 с кодом EXEC_BUSY (на выкладке galaxy-приложения — GALAXY_APP_BUSY), retryable: true и заголовком Retry-After. Формат архива менять не нужно. Настоящий отказ установить unzip по-прежнему приходит как 502 UNZIP_PREFLIGHT_FAILED и совет использовать .tar.gz.
Влияние на интеграторов
Повторяйте запрос по Retry-After. Не пересобирайте архив из-за EXEC_BUSY / GALAXY_APP_BUSY. Ветка UNZIP_PREFLIGHT_FAILED не менялась.
FIX-0828-15: ключ владельца в самоудалении больше не вызывает методы Битрикс24 через V1
Было
Ключ владельца портала с запланированным самоудалением мог продолжать вызывать часть методов Битрикс24 через V1. Ограничение действовало не для всех сгенерированных и рукописных обёрток, методов REST 3.0, прямых вызовов и пакетных запросов.
Стало
Все V1-методы, которые по APP/OAuth-ключу портала отправляют запросы в Битрикс24, возвращают 503 user_self_deletion_pending и Retry-After до отправки запроса. Это относится, в частности, к GET /v1/lists, GET /v1/calendar/settings, GET /v1/chats/recent, GET /v1/workday/status, GET /v1/applications, POST /v1/apps, методам обновления тарифа и активации trial, а также POST /v1/batch.
Для READONLY-ключа владельца в самоудалении этот 503 имеет приоритет над WRITE_BLOCKED_READONLY_KEY. Полностью аутентифицированный ключ активного владельца по-прежнему получает READONLY-запрет; более ранние ошибки аутентификации и состояния аккаунта сохраняют свои коды.
Мета-методы V1, включая обычный GET /v1/me без refresh=tariff, MANAGEMENT control-plane и методы, работающие только с данными платформы Вайбкод, не замораживаются этим изменением.
Влияние на интеграторов
Менять интеграцию не требуется. При ответе 503 повторяйте запрос не раньше значения Retry-After.
BC-0828-16: include требует право на связанную сущность
Поддержка старого формата до: не предусмотрена
Было
Параметр include не проверял, есть ли у ключа право на ту сущность, которую он достаёт. Право проверялось только у сущности, которую вы читаете. Поэтому ключ с одним правом tasks через GET /v1/tasks/{id}?include=responsible получал полную карточку сотрудника, хотя на /v1/users тот же ключ отвечал отказом.
Стало
Право проверяется у обеих сторон связи. Не хватает права на связанную сущность — запрос отклоняется с кодом SCOPE_DENIED и HTTP 403, в тексте названо недостающее право и связь, из-за которой оно понадобилось.
Затронуты связи, у которых стороны требуют разных прав: responsible и creator у задач и owner у рабочих групп требуют user, catalog у разделов товаров требует catalog. Связи внутри одного права — например preset у реквизитов или parentSection у разделов товаров — работают как раньше.
Если ваша интеграция пользуется такой связью, добавьте недостающее право ключу: набор прав правится у ключа в кабинете, перевыпускать его не нужно.
Затронутые эндпоинты: любой эндпоинт, принимающий include — чтение по идентификатору, выдача списка и POST /search. Общее описание механизма — включение связанных записей.
NEW-0828-17: include для реквизитов, рабочих групп и разделов товаров
Три справочные сущности получили связи, поэтому параметр include на них теперь объявлен и работает. У реквизитов появилась связь preset — шаблон реквизитов, определяющий набор полей. У рабочих групп — owner, карточка сотрудника-владельца группы. У разделов товаров сразу две: catalog — торговый каталог, к которому относится раздел, и parentSection — родительский раздел, он приходит пустым у раздела верхнего уровня.
Связанная запись, как и раньше, лежит в поле _included рядом с самой записью, работает на выдаче списка, на чтении по идентификатору и в теле POST /search. Ограничения общие для механизма: не больше трёх связей на запрос, а на выборке больше 200 записей связи не разрешаются, и ответ помечается includeSkipped.
Остальные справочники по-прежнему include не объявляют, и это не упущение. Стадии направления сделок Битрикс24 отдаёт строковым кодом, а не идентификатором записи справочника, поэтому связать их с элементом справочника нечем. У элемента справочника номер воронки имеет смысл только в паре с типом объекта CRM, и один и тот же номер принадлежит одновременно направлению сделок и воронке смарт-процесса. У шаблона документа идентификатор файла не адресуется методами Диска, а нумератор отдельной сущностью в API не представлен. Список участников рабочей группы доступен отдельной ручкой, а не через include.
Затронутые эндпоинты: GET /v1/requisites, GET /v1/workgroups, GET /v1/product-sections, их чтение по идентификатору и POST /search. Общее описание механизма — включение связанных записей.
FIX-0828-18: select вместе с include больше не обнуляет связь на списке и в поиске
Было
Если в одном запросе к списку или к POST /search стояли и select, и include, а поле-ссылка в select названо не было, связанная запись приходила пустой. Например, GET /v1/deals?select=id,title&include=company отдавал _included.company пустым, хотя без select та же связь разрешалась. На чтении по идентификатору проблемы не было.
Стало
Связь разрешается до того, как ответ урезается до запрошенных полей, а поле-ссылка добирается во внутренний запрос само. Публичный ответ при этом не расширяется: в нём остаются только названные вами поля плюс блок _included.
Затронутые эндпоинты: выдача списка и POST /search у любой сущности со связями. Общее описание механизма — включение связанных записей.
NEW-0828-19: профиль текущего сотрудника появился в спецификации и справочнике
Метод GET /v1/users/me работал и раньше, но не был объявлен в GET /v1/openapi.json, поэтому не попадал ни в справочник API, ни в карту эндпоинтов. Клиент, сверявшийся со спецификацией, не находил метод и делал вывод, что его нет.
Теперь операция описана: скоуп user, форма ответа как у GET /v1/users/:id плюс трёхзначное поле isAdmin. Само поведение метода не менялось.
Значение isAdmin равно null, когда проверку выполнить не удалось. Профиль при этом возвращается целиком, поэтому права проверяйте условием isAdmin === true, а не отрицанием.
FIX-0828-20: `topUpAvailable` у коробочного аккаунта отражает доступность именно коробочной кассы
Было
GET /v1/cowork/subscription/preview отвечал коробочному аккаунту topUpAvailable: true, если в его регионе была открыта продажа вообще. Продажа для коробочных аккаунтов идёт через отдельную кассу и открывается отдельно, поэтому признак мог обещать пополнение там, где заказ следующим шагом отклонялся.
Стало
Признак считается по доступности коробочной продажи в регионе аккаунта. Ответ остаётся HTTP 200, набор полей прежний, у облачных аккаунтов значение не изменилось. Пока коробочная продажа закрыта, приходит topUpAvailable: false и currency: null, а попытка начать пополнение отвечает кодом BOX_TOPUP_NOT_AVAILABLE.
FIX-0828-21: ключ авторизации получает права, которые портал реально выдаёт
Было
Если у личного API-ключа приложения не было ни одного права Битрикс24, платформе
было нечем спросить портал о доступных правах — и ключ авторизации выпускался с
набором crm + placement. Приложение, которому нужны задачи, чат или диск,
молча упиралось в отказ по правам, а расширить уже выпущенный ключ нельзя: только
перевыпуск.
Стало
Права спрашиваются каналом, которым платформа управляет порталом, поэтому набор больше не зависит от того, есть ли вебхук у конкретного ключа приложения. Ключ авторизации получает пересечение доступных прав портала с поддерживаемыми, как и задумано. Если спросить нечем — поведение прежнее, выпуск не блокируется.
FIX-0828-22: фотографию сотрудника снова можно записать через API
Было
Поле personalPhoto объявлено строкой, поэтому любой массив или объект в нём отклонялся с
400 INVALID_PARAMS — а массив [имя файла, base64] и есть единственная форма, которую
принимает Битрикс24. На сущностных маршрутах записать фотографию было нельзя ни одной формой:
строка с base64 и ссылка возвращали 422, пакетные маршруты — 400. Проходила она только через
обёртку POST /v1/users/invite.
Стало
personalPhoto принимает на записи файл прямо в теле: массив ровно из двух непустых строк —
имя файла и содержимое в base64 — на POST /v1/users и PATCH /v1/users/:id. Чтение поля не
изменилось, оно по-прежнему отдаёт URL фотографии. Прочие формы отклоняются как раньше, и это
намеренно: вложенная {"personalPhoto": {"fileData": [...]}} принимается порталом с успехом,
но при этом снимает фотографию. Пакетные маршруты фотографию отклоняют: подзапрос пакета едет
строкой запроса под общим потолком тела, и за пределом длины значение обрезалось бы,
отвечая при этом успехом. Обёртка POST /v1/users/invite эту же форму принимает — она переводит имя
поля и отдельно проверяет пару, — но её потолок тела остался общим (1 МиБ против 40 МиБ у
одиночных маршрутов), поэтому настоящую фотографию отправляйте через POST /v1/users или
PATCH /v1/users/:id.