Для AI-агентов: markdown этой страницы — /docs-content/changelog/2026-08-25.md индекс документации — /llms.txt
Изменения API: 25 августа 2026
← Журнал изменений · Август 2026
FIX-0825-1: карточка приложения получает сервер и на порталах с галактиками
Было
Приложение, созданное без сервера, а затем опубликованное на портале с галактиками, оставалось в разделе «Приложения» без сервера: GET /v1/applications/{id} отдавал server: null неограниченно долго. Привязка контейнера к уже существующей карточке зависела от настройки, выключенной по умолчанию, поэтому карточка и контейнер жили порознь.
Стало
Контейнер привязывается к уже существующей карточке независимо от этой настройки, и GET /v1/applications/{id} отдаёт сервер сразу после публикации. Настройка по-прежнему управляет только появлением НОВОЙ карточки у приложения, созданного на общем хосте, — её поведение не изменилось.
BC-0825-2: ключ «только чтение» больше не пишет на платформенных ручках
Поддержка старого формата до: не предусмотрена
Было
Режим ключа «только чтение» резал вызовы Битрикс24, но не трогал платформенные ручки V1.
Ключом «только чтение» проходили управление серверами (DELETE /v1/infra/servers/{id},
POST /v1/infra/servers/{id}/stop|start|reboot|wake), деплой и запуск команд на сервере,
запись в хранилище (POST /v1/storage/objects), обращения (POST /v1/feedback), ключи
поиска и ИИ, а также ручки, списывающие вайбы.
Стало
Любая запись на платформенной ручке V1 под ключом «только чтение» отвечает
403 WRITE_BLOCKED_READONLY_KEY до выполнения операции. Ручки, которые проксируют вызов
в Битрикс24, работают как прежде: там решение принимает классификатор по имени метода,
поэтому чтения с телом запроса (POST /v1/deals/search, POST /v1/batch из одних чтений
и подобные) не затронуты.
Исключений два. POST /v1/apps — ключом «только чтение» по-прежнему можно завести
приложение и парный ключ В РЕЖИМЕ «только чтение», но нельзя выписать ключ «чтение и
запись». DELETE /v1/infra/servers/{id}/lock — снятие залипшего лока не меняет
состояния сервера и остаётся доступным: на него ссылается поле recoveryAction
в ответе EXEC_BUSY.
Если приложению нужны эти операции, переключите ключ в режим «чтение и запись» на
странице /keys. Проверить режим и доступность создания сервера можно через
GET /v1/me: у ключа «только чтение» в ответе появилось поле
writeRestriction — код отказа, область его действия и адрес страницы про режимы. Оно
нужно потому, что тело ответа называет пишущие ручки в трёх десятках мест (подсказки
хранилища, обращений, автосохранения исходников, коворка); это адреса, а не разрешения,
и поле говорит это прямо. Доступность конкретной операции по-прежнему в capabilities.
FIX-0825-3: /v1/me перестал объявлять создание приложения недоступным ключу «только чтение»
В ответе GET /v1/me слот capabilities.apps.create под ключом в режиме «только чтение» приходил с available: false и причиной WRITE_BLOCKED_READONLY_KEY. Это было неверно: POST /v1/apps отказывает такому ключу только при попытке завести приложение и парный ключ в режиме «чтение и запись», а приложение В РЕЖИМЕ «только чтение» тот же ключ заводит и получает 201.
Слот теперь приходит доступным, а ограничение описано в его поле note. Клиент, который ветвится по capabilities — а /v1/me для этого и нужен, — больше не пропускает работающую операцию.
BC-0825-4: ключ десктопа Коворка больше не меняет регистрацию OAuth-приложений
Поддержка старого формата до: не предусмотрена
Было
Ключ с системным правом vibe:cowork мог создать OAuth-приложение на аккаунте Битрикс24 (POST /v1/apps), изменить его (PATCH /v1/apps/{id}), снести (DELETE /v1/apps/{id}) и перепривязать к другим учётным данным (POST /v1/apps/{id}/relink-oauth). Тот же ключ при этом уже был закрыт от инфраструктуры, депо исходников и публикации в каталог, то есть запрет был неполным.
Стало
Все четыре операции отвечают 403 INFRA_FORBIDDEN_FOR_COWORK_KEY; в details.deployableKeys перечислены пригодные ключи владельца. На POST /v1/apps отказ приходит до проверки тела, поэтому невалидное тело тоже получает этот код, а не VALIDATION_ERROR. Чтения семейства (GET /v1/apps, GET /v1/apps/{id}) не изменились.
Что делать
Выполнять эти операции обычным ключом приложения: право vibe:cowork выдаётся платформой и предназначено только для данных. Ключи-кандидаты приходят в details.deployableKeys того же ответа — имя, префикс и последние символы, без секрета. Окна поддержки старого поведения нет: право vibe:cowork не выдаётся пользователям и не появляется в диалогах ключей, а единственный его носитель этих операций не вызывает.
BC-0825-5: повторная загрузка файла заменяет содержимое вместо ошибки 500
Поддержка старого формата до: не предусмотрена
Было
Загрузка на уже занятый логический key через POST /v1/storage/objects/upload отвечала 500 с кодом
P2002. При этом байты в хранилище уже были перезаписаны, а sizeBytes и sha256 объекта оставались
от прежней версии, поэтому размер в списке и в счёте не соответствовал реальному файлу.
Стало
Повторная загрузка на тот же key заменяет содержимое: 200, тот же object.id (выданные ранее
ссылки продолжают работать), а sizeBytes, sha256, contentType и новое поле contentUpdatedAt
соответствуют новым байтам.
Это верно для ключа приложения. У личного ключа разработчика без привязки к приложению повторная
загрузка по-прежнему создаёт новый объект со своим id — поведение не изменилось, оно чинится
отдельно.
Когда заменить объект на месте нельзя, вместо 500 приходит 409 с внятным кодом:
STORAGE_KEY_DELETED (объект удалён и держит имя до уборки),
STORAGE_MULTIPART_IN_PROGRESS (идёт составная загрузка),
STORAGE_UPLOAD_PENDING (по ключу висит незавершённая бронь предподписанной ссылки),
STORAGE_KEY_OWNED_ELSEWHERE (имя занято другим объектом приложения),
STORAGE_KEY_CONFLICT (объект изменился во время загрузки — повторите запрос).
Что нужно сделать
- Поле
visibilityпри замене не может менять видимость объекта: не передавайте его либо передавайте текущее значение. Иное значение отвечает400 STORAGE_VISIBILITY_MISMATCH, и текущее значение указано в сообщении. Раньше такой запрос отвечал500, но байты при этом всё же заменялись — то есть клиент, игнорировавший ошибку, публиковал обновления и после фикса перестанет. - Замена через предподписанную ссылку (
POST /v1/storage/objects) больше не выдаётся на существующий объект:409 STORAGE_KEY_EXISTS. Content-Type в такой ссылке не подписывается, поэтому заменять содержимое можно только прямой загрузкой. Незавершённая бронь, выданная вам же, при этом переиспользуется — приходит200с тем жеobject.idи свежей ссылкой; видимость брони такая ссылка не меняет, поэтому расхождение отвечает400 STORAGE_VISIBILITY_MISMATCH. - Составная загрузка (
POST /v1/storage/objects/multipart/create) на занятый ключ тоже отвечает409вместо500:STORAGE_KEY_EXISTS,STORAGE_KEY_DELETED,STORAGE_MULTIPART_IN_PROGRESS,STORAGE_UPLOAD_PENDINGилиSTORAGE_KEY_CONFLICT(объект создал параллельный запрос). Замена объекта через составную загрузку не поддерживается — используйте другой ключ. - В ответах появилось поле
object.contentUpdatedAt— момент, когда содержимое последний раз стало актуальным. У объектов, записанных до этого обновления, оноnull.
BC-0825-6: поля привязки и автора у комментария таймлайна больше не выглядят изменяемыми
Поддержка старого формата до: не предусмотрена
Было
GET /v1/timelines/fields отдавал entityType, entityId и authorId как обычные записываемые поля. PATCH /v1/timelines/{id} с любым из них отвечал 200 и success: true, но значение не менялось — повторное чтение показывало прежнее. При этом id и createdAt в том же ответе честно отклонялись с 400 READONLY_FIELD, то есть справочник полей был правдив избирательно. Интегратор и AI-агент считали, что сменили автора или перенесли комментарий на другую запись, тогда как не менялось ничего.
Стало
Три поля помечены в справочнике неизменяемыми, и попытка их записать отклоняется с 400 READONLY_FIELD вместо тихого успеха. Причины у полей разные, и справочник теперь их различает:
entityTypeиentityId— доступны только при создании: комментарий привязывается к записи в момент добавления, перенести его на другую запись нельзя;authorId— только для чтения: автора Битрикс24 берёт из учётных данных, которыми сделан вызов, поэтому задать его нельзя ни при обновлении, ни при создании.
Изменяемым остаётся comment — это единственное поле, которое принимает и обновление на стороне Битрикс24.
Что делать интеграторам
Уберите entityType, entityId и authorId из тела PATCH /v1/timelines/{id} — они и раньше не применялись, а теперь запрос с ними получит 400 READONLY_FIELD. Отдельно проверьте создание: POST /v1/timelines с полем authorId тоже переходит с «201, значение проигнорировано» на 400 READONLY_FIELD, потому что автора нельзя задать и при создании. Поля entityType и entityId на создании по-прежнему обязательны и принимаются. Если код полагался на «успешный» ответ как на признак смены автора или переноса комментария, это ожидание не выполнялось и до правки: значение оставалось прежним. Комментарий по-прежнему обновляется обычным PATCH с полем comment. Привязку задавайте при создании через POST /v1/timelines, автора сменить нельзя — вызовите метод от имени нужного пользователя.
Окно поддержки прежнего поведения не предусмотрено намеренно: прежнее поведение и было дефектом — оно молча теряло переданное значение, и сохранять его на срок значило бы продлевать тихую потерю данных.
BC-0825-7: базовая версия для выкладки требуется и когда верхнюю версию сохранил другой человек
Поддержка старого формата до: не предусмотрена
Было
POST /v1/infra/servers/{id}/deploy требовал baseVersionId только на сервере, у которого есть живая команда разработки. Если владелец добавлял сотрудника, тот выкладывал свою версию, а затем владелец снимал его с команды, требование снималось вместе с последним участником — и следующая выкладка молча затирала сохранённую работу.
Стало
Метка baseVersionId обязательна и тогда, когда верхняя версия в хранилище исходников сервера сохранена не тем, кто выкладывает сейчас, — независимо от того, есть ли у сервера команда прямо сейчас. Отказ прежний — 409 BASE_VERSION_REQUIRED с номером актуальной версии.
Что делать интеграторам
Отправлять baseVersionId при каждой выкладке. Клиент, который уже это делает, не меняет ничего. Клиент, который полагался на «команда пуста → метка не нужна», получит 409 BASE_VERSION_REQUIRED на сервере с чужой сохранённой версией — в том числе после передачи владения приложением, когда верхнюю версию сохранил прежний владелец. Обработка та же, что уже написана для сервера с командой: прочитать номер актуальной версии из тела отказа и повторить выкладку, указав его как базу. Старое поведение не сохраняется ни на какой срок: именно оно и приводило к потере чужой работы.
NEW-0825-8: участник команды разработки сервера теперь видит его приложение в витрине
Участник команды разработки сервера теперь видит приложение, привязанное к этому серверу, в GET /v1/applications (со значением viewerState: "shared") и может прочитать его карточку через GET /v1/applications/{id} — раньше карточка отвечала 403 FORBIDDEN, потому что доступ проверялся только по владению и по политике доступа сервера, без учёта членства в команде.
FIX-0825-9: include публикуется только для сущностей со связями
Было
В OpenAPI и MCP-справке параметр include объявлялся для list, get и search у всех сущностей. Для сущностей без доступных связей запрос с этим параметром завершался 400 INVALID_INCLUDE с пустым списком доступных связей.
Стало
OpenAPI объявляет include только у сущностей с доступными связями, а MCP-справка предлагает сначала проверить capability через discover или get_fields. Проверка во время запроса и ответ 400 INVALID_INCLUDE для неподдерживаемого include не изменились.
Влияние на интеграторов
Генераторы клиентов больше не получают неподдерживаемый include из OpenAPI, а MCP-агенты получают явное указание сначала проверить capability. Общий optional-ключ MCP сохраняется. Существующие корректные запросы продолжают работать без изменений, а прежние неподдерживаемые запросы получают тот же ответ 400 INVALID_INCLUDE.
BC-0825-10: Потолок inline-архива в теле деплоя сужен до 96 МБ
Поддержка старого формата до: не предусмотрена
Было
POST /v1/infra/servers/:id/deploy с кодом во встроенном source.content, POST /v1/infra/servers/:id/upload со встроенным content и POST /v1/infra/servers с полем source при создании принимали тело до 500 МБ. Отказ сверх потолка приходил кодом PAYLOAD_TOO_LARGE.
Стало
Тело этих трёх запросов ограничено 96 МБ. Единица — само HTTP-тело, а не архив: source.content / content это base64, который тяжелее исходных байт примерно на треть, поэтому 96 МБ тела соответствуют архиву примерно в 72 МБ. Тело сверх потолка отклоняется кодом 413 INLINE_SOURCE_TOO_LARGE — новым, вместо прежнего PAYLOAD_TOO_LARGE на этих трёх входах. Отказ приходит по заголовку Content-Length до чтения тела, поэтому он детерминированный — то же тело повторной отправкой не пройдёт. Трафик это не экономит: тело загружается целиком, и отказ приходит после того, как загрузка закончилась. Конверт ошибки несёт error.hint с полями reason, recovery, recoveryAction и note — готовым рецептом перехода.
Многосоставная форма (multipart/form-data) POST /v1/infra/servers/:id/deploy под тот же потолок попадает условно. Файловая часть уходит в хранилище потоком, и тогда её предел остаётся прежним — 500 МБ архива, — только когда одновременно верны три условия: вызывающий обращается к серверу как его прямой владелец, а не через карточку чужого приложения или через менеджмент-ключ; сервер либо не galaxy-приложение, либо для вызывающего включены обе настройки ссылочного деплоя galaxy-приложений; хранилище исходников включено — и на уровне платформы, и для этого портала. Если хотя бы одно условие не выполнено, поток на потоковую запись не переключается, и форма принимает архив тем же буферным способом, что и base64-поля выше, — под тем же потолком в 72 МБ архива и с тем же кодом 413 INLINE_SOURCE_TOO_LARGE и error.hint.
Прежний код PAYLOAD_TOO_LARGE никуда не делся: он по-прежнему приходит на входе /v1/ (потолок 500 МБ) и на остальных маршрутах платформы со своими лимитами — переименований нет.
Без изменений:
source.url— по-прежнему принимается до 500 МБ, платформа скачивает архив по ссылке сама;source.versionId— деплой уже сохранённой версии, до 500 МБ архива;- потолок сохранения версии исходников на POST /v1/infra/servers/:id/sources и
POST /v1/apps/:id/sources— 500 МБ, не тронут.
Что делать интеграторам
Архив крупнее 72 МБ отправляйте версионным путём в два вызова — он работает одинаково для личного ключа (vibe_api_*) и для ключа OAuth-приложения, а прямому владельцу сервера этих двух вызовов достаточно:
POST /v1/infra/servers/:id/sources # сырые байты архива, Content-Type: application/gzip, --data-binary
POST /v1/infra/servers/:id/deploy # {"source":{"versionId":"vN"}}
Если же сервер доступен через карточку приложения или менеджмент-ключ, а не напрямую владельцем, к тем же двум вызовам добавляется третий: {versionId} может ответить SOURCE_VERSION_REQUIRES_APP или SOURCE_VERSION_NOT_FOUND — тогда получите подписанную ссылку GET /v1/infra/servers/:id/sources/vN/download и разверните архив по ней: {"source":{"url":"<ссылка>"}}. Тот же путь и есть страховка от условного потолка многосоставной формы — версионный деплой ни при каких условиях не буферизует архив целиком, поэтому его 500-мегабайтный предел безусловен.
Сужено на уровне наблюдаемого поведения: тело в сотни мегабайт в base64-форме (и многосоставный архив, для которого не выполнилось хотя бы одно из условий выше) приходилось держать в памяти целиком на всё время запроса, и такой запрос мог оборваться без ответа, задев параллельные запросы на этом же процессе.
NEW-0825-11: `GET /v1/me` называет архивный эквивалент inline-потолка отдельным полем
Было
Блок deployment.limits нёс потолок встроенного тела одним полем uploadInlineMax. Единица там — HTTP-тело, а source.content и content едут в base64, поэтому размер архива, который в это тело поместится, клиент считал сам.
Стало
Рядом появилось поле uploadInlineMaxArchive — тот же потолок, выраженный в размере АРХИВА: три четверти от uploadInlineMax, потому что base64 тяжелее исходных байт примерно на треть. Поле добавлено к ответу и ничего в нём не убирает: uploadInlineMax остаётся на прежнем месте с прежним смыслом, и клиент, который его не читает, работает без правок. Оба значения приходят строками с единицей измерения — например 96MB и 72MB.
Что делать интеграторам
Ничего обязательного. Если вы сами пересчитывали потолок тела в размер архива, возьмите готовое значение из uploadInlineMaxArchive — оно приходит из той же константы, что и отказ 413 INLINE_SOURCE_TOO_LARGE, поэтому разойтись с фактическим поведением не может.
BC-0825-12: POST /v1/apps соблюдает политику портала «кто может создавать приложения»
Поддержка старого формата до: не предусмотрена
Было
Публичный маршрут сверялся только с устаревшим режимом «по списку». Портал, где администратор
Битрикс24 разрешил создавать приложения одним администраторам или запретил создание совсем,
всё равно позволял создать приложение любым личным API-ключом — при том что то же действие в
кабинете отвечало 403.
Стало
POST /v1/apps отвечает 403 с кодом APP_CREATION_RESTRICTED, когда
политика портала не разрешает вызывающему создавать приложения. Режим «по списку» работает
как прежде: участник из списка приложение создаёт, остальные получают 403. На порталах, где
создание открыто всем, не меняется ничего.
Что делать интеграторам
Ключ, выписанный на портале с ограничением, начнёт получать 403 APP_CREATION_RESTRICTED
там, где раньше приходил 201. Попросите администратора Битрикс24 выдать право на создание
приложений — или ведите создание ключом того, у кого это право есть.
FIX-0825-13: Установка среды Node.js 20 не повторяет уже выполненные шаги
Было
При повторном развёртывании среды Node.js 20 через POST /v1/infra/servers/:id/deploy платформа заново устанавливала Node.js и pm2. Недоступность реестра npm могла занять всё время шага и завершиться без точной причины.
Стало
Платформа пропускает установку уже доступных Node.js 20 и pm2. Если pm2 отсутствует, его установка ограничена по времени и числу повторов, а ошибка или превышение лимита времени останавливает развёртывание с явной диагностикой.
Влияние на интеграторов
Повторные развёртывания завершаются быстрее и не требуют изменений со стороны интеграторов. Ошибка установки pm2 теперь сразу видна как причина неуспешного развёртывания.
FIX-0825-14: привязка плейсмента отвечает 400 на слишком длинный iconName вместо 502 без причины
Было
POST /v1/placements/bind принимал options.iconName длиной до 255 символов. Битрикс24 отклоняет значение длиннее 50, поэтому запрос уходил в аккаунт и возвращался оттуда как 502 BITRIX_UNAVAILABLE с текстом «Failed to register placement on Bitrix24 via dev key». Какое именно поле не подошло, из ответа понять было нельзя.
Стало
Граница длины в схеме совпадает с границей Битрикс24: значение длиннее 50 символов отклоняется сразу, а 400 называет поле options.iconName. Значения, которые привязывались раньше, продолжают привязываться — длиннее 50 аккаунт не принимал никогда, а подставляемый по умолчанию значок fa-cube в границу укладывается.