Для AI-агентов: markdown этой страницы — /docs-content/changelog/2026-08-13.md индекс документации — /llms.txt
Изменения API: 13 августа 2026
← Журнал изменений · Август 2026
FIX-0813-1: отказ сборки нативного модуля называется своей причиной, а не «не найден Python»
Было
Приложение на Node с зависимостью, которая содержит машинный код (например better-sqlite3),
разворачивалось через раз. Такие зависимости ставятся в два хода: сначала скачивается уже
собранный файл, а если не вышло — модуль собирается из исходников на месте. Когда скачивание
срывалось из-за внешней сети, начинался второй ход и падал — в образе приложения нет инструментов
сборки. В ответе на деплой и на карточке приложения оказывалась последняя строка этого второго
хода, Could not find any Python installation to use, и она уводила от настоящей причины: клиент
искал ошибку в своём коде и в версии Python, хотя ни то, ни другое сломано не было. Категория
отказа приходила общая — INSTALL_FAILED, с подсказкой про нехватку компилятора.
Стало
У такого отказа своя категория — NATIVE_PREBUILD_UNAVAILABLE, она приходит в поле category
ответа 502 GALAXY_APP_BUILD_FAILED и в buildHint карточки приложения. Текст подсказки говорит
то, что есть: готовую сборку не удалось скачать, внешний источник не ответил, это временно,
повторите развёртывание через несколько минут. Категория ставится, только когда обе улики в логе
сборки совпали — скачивание сорвалось по сети И собрать из исходников оказалось нечем; отказы,
которые повтор не лечит (для этой платформы готовых сборок не публикуют, на хосте кончилось
место), в неё не попадают и сохраняют прежний текст. Повторяет деплой клиент — платформа сборку
сама не пересылает.
FIX-0813-2: Формы ответов методов API описаны в машинной схеме
Было
Машинная схема не показывала фактические формы ответов для POST /v1/duplicates/find и GET /v1/lists/{iblockId}/elements. Это затрудняло обработку результата поиска дублей и Bitrix24-native полей элементов списков.
Стало
Схема описывает для поиска дублей объект с ключами типов сущностей или пустой массив, а для элементов списков — массив в конверте с динамическими ключами свойств и счётчиком meta.total, не меняя фактический ответ API.
Влияние на интеграторов
Интеграции могут использовать машинную схему для выбора формы ответа. Для элементов списков учитывайте, что параметр limit игнорируется.
NEW-0813-3: настоящее состояние спящего galaxy-приложения в ответе GET сервера и в ответе логов
GET /v1/infra/servers/:id для galaxy-приложения теперь отдаёт блок reachability, который отвечает на вопрос «может ли приложение ответить прямо сейчас». Поле status не изменилось — это состояние учётной записи приложения, и во время пробуждения оно отстаёт от машины: запись остаётся в sleeping, пока платформа поднимает галактику, а на холодной машине это занимает минуты. Рядом с ним reachability несёт сводный effectiveStatus, состояние галактики-носителя hostStatus и hostTunnel, живо снятые container и forwarder, исход опроса probe и его время probedAt. Опрос идёт только по работающей галактике, спящую он не будит, поэтому у спящей галактики container и forwarder приходят как unknown. У серверов остальных типов блок равен null.
Ответ GET /v1/infra/servers/:id/logs для приложения на спящей галактике дополнен полем recovery и называет рабочий путь: вызов пробуждения, признак logsPreserved (пробуждение запускает тот же контейнер, поэтому строки, записанные до сна, остаются в журнале), бюджет подъёма холодной галактики в секундах, чем проверять готовность и доступно ли этому приложению окно пробуждения по расписанию. Поле hint осталось строкой и теперь тоже называет вызов пробуждения.
Разбор состояний и порядок действий — Сон и пробуждение Galaxy-приложения.
FIX-0813-4: скачивание файла объявляет требуемый скоуп в openapi.json
Было
У операции GET /v1/files/{fileId}/download в машинной спецификации не было поля x-required-scope, хотя рантайм отвечает 403 SCOPE_DENIED без скоупа. Клиент или агент, собиравший ключ по спецификации, видел «скоуп не нужен» и получал отказ на первом же вызове. Эта же операция попадала в любой срез openapi.json?scope=, включая срезы других модулей.
Стало
Операция объявляет x-required-scope: disk — основной скоуп. Обработчик принимает и crm: ключ только с ним скачивает файл, прикреплённый к пользовательскому полю карточки CRM. Второй скоуп объявлен новым необязательным полем x-alternative-scopes рядом с основным. В срезах операция остаётся при openapi.json?scope=disk и ?scope=crm, в остальных её больше нет.
Влияние на интеграторов
Клиент, читающий только x-required-scope, запросит disk и продолжит работать как раньше. Клиенту с ключом на одном crm теперь видно из спецификации и со страницы операции, что вызов ему доступен: раньше об этом сообщали только текст отказа и самоописание ключа в /v1/me.
FIX-0813-5: Понятный текст ошибки сборки вместо машинного вывода и внешних адресов
Было
Когда сборка приложения падала из-за недоступности хранилища базовых образов, в provisionError и в ответе 502 приходил дословный вывод сборщика: имя внешнего хранилища, путь запроса и публичный IP-адрес. Для остальных отказов сборки в тексте тоже могли оказаться внешние ссылки и публичные IP-адреса.
Стало
Недоступность хранилища образов описывается фиксированной фразой: причина и действие — повторить тот же деплой через несколько минут, слот и данные не тронуты. Категория отказа (provisionErrorCategory) и признак повторяемости не изменились. Во всех прочих отказах сборки причина по-прежнему передаётся как есть, но внешние адреса в ней заменяются на пометки — и ссылки целиком, и имя хранилища образов без схемы, когда строка сама говорит про образ, и адрес, названный вообще без пути в строке сетевого отказа (getaddrinfo ENOTFOUND …, «не удалось разрешить имя хоста»), и публичные IP-адреса. Адреса самой платформы, локальные и внутренние остаются видны, как и имя образа с версией, имена файлов и имена пакетов: пометка ставится там, где текст сам называет адрес адресом, — поэтому имя пакета вида socket.io остаётся читаемым, хотя по форме не отличается от имени хранилища. Одно исключение: числовой ряд из четырёх частей (11.0.16.1) неотличим от IP-адреса, поэтому версия такого вида тоже станет пометкой.
Влияние на интеграторов
Менять ничего не нужно: коды ошибок, категории и признак повторяемости те же. Клиент, который разбирал текст provisionError по подстрокам, для этого класса отказа получит стабильную фразу вместо изменчивого вывода сборщика, а полный лог сборки по-прежнему доступен в поле buildLog того же ответа.
NEW-0813-6: манифест бандла агента сообщает режим сверки рантайма
В ответ GET /v1/agent-bundles/:kind/manifest.json добавлены два необязательных поля.
runtime_integrity принимает значение "on" или "off" и говорит агенту, сверять ли файлы своего окружения с контрольными суммами, записанными при установке. Агент выполняет сверку только при значении "on"; отсутствие поля означает, что она выключена.
runtime_integrity_budget — целое число, которое платформа сейчас всегда присылает равным единице. Агент читает его как разрешение: больше нуля — восстановление допускается, ноль — запрещено. Частоту попыток ограничивает сам агент, не чаще одной в час, поэтому значения больше единицы поведение не меняют. Режимом восстановления управляет не это поле, а настройка платформы; поле нужно, чтобы агент без него по умолчанию ничего не восстанавливал.
Прежние запросы не затронуты: поля необязательные, остальные поля манифеста и контрольная сумма архива не изменились. Клиентам, читающим манифест, действий не требуется.
NEW-0813-7: манифест бандла агента получил операцию точечного ремонта рантайма
В ответе GET /v1/agent-bundles/:kind/manifest.json в объекте operations появился ключ repair_runtime.
Операция переустанавливает движок агента на месте, когда файлы его окружения разошлись с контрольными суммами, записанными при установке. Раньше такое расхождение лечилось только пересозданием приложения целиком.
Поле available_to у неё содержит единственное значение admin: операция редкая и запускается вручную, поэтому вызов от имени регулярных заданий отклоняется с ошибкой OPERATION_FORBIDDEN. Успехом считается не только нулевой код возврата, но и подтверждение от агента, что окружение сошлось; иначе операция отвечает status: "failed" с причиной в поле error.
Прежние запросы не затронуты: остальные операции, поля манифеста и контрольная сумма архива не изменились. Клиентам, читающим манифест, действий не требуется.
FIX-0813-8: Отказ reauth больше не советует OAuth ключам без OAuth
Было
POST /v1/bots/{botId}/reauth на мёртвых кредах всегда отвечал 410 REAUTH_REQUIRED с одним и тем же советом — перезапустить авторизацию через POST /v1/oauth/authorize либо пересоздать личный ключ. Ключу, который ходит в Битрикс24 через входящий вебхук, этот совет выполнить нечем: ни потока авторизации, ни токена обновления у него нет. Владелец такого ключа читал инструкцию и упирался в тупик.
Стало
Текст отказа зависит от того, чем ключ авторизуется, а в error.details появилось поле credentialKind — oauth, webhook или unknown. Вебхучному ключу отказ называет реальную причину (вебхук мёртв, чаще всего удалён на стороне Битрикс24) и реальное лекарство — перевыпуск вебхука, при котором идентификатор и строка ключа сохраняются, а привязанные боты продолжают работать. Ключу с OAuth текст прежний.
Влияние на интеграторов
Менять ничего не нужно: код ответа и его статус не изменились. Клиент, который разбирал текст отказа строкой, увидит новую формулировку у вебхучных ключей — надёжнее ветвиться по error.details.credentialKind.
FIX-0813-9: удаление galaxy-приложения на непробуждаемом хосте отвечает терминальным 409
Было
DELETE /v1/infra/servers/{id} для приложения на galaxy-хосте, который нельзя разбудить
(заморожен счёт либо стоит запрет пробуждения), отвечал 502 GALAXY_HOST_UNREACHABLE
с объектом error.hint и советом повторить позже. Совет не срабатывал никогда: пробуждение
было не провалено, а запрещено, поэтому клиент повторял запрос до собственного таймаута.
Стало
Такой отказ терминален и приходит как 409 GALAXY_HOST_WAKE_BLOCKED. В теле — поле
error.reason с причиной: BILLING_FROZEN, ACCESS_EXPIRED, STOPPED или UNKNOWN.
Объекта error.hint на этом пути больше нет — он описывал восстановление недостижимого
хоста, а восстанавливать здесь нечего; для настоящей недостижимости 502 с hint
сохраняется без изменений. Повторять запрос бессмысленно — нужно снять причину.
Заодно уточнён текст 409 GALAXY_HAS_APPS при удалении самого хоста: удаление галактики
вместе с её приложениями доступно в кабинете, на публичном интерфейсе такой операции нет.
NEW-0813-10: пробный период Маркета включается с ключа десктопа Коворк/Код
Появился эндпоинт POST /v1/cowork/activate-market-trial: он включает одноразовый пробный период подписки Маркета для аккаунта Битрикс24, к которому привязан ключ десктопа Коворк/Код. Раньше программный путь был только у личных ключей и ключей приложений — ключ десктопа эндпоинт POST /v1/portals/{id}/activate-market-trial отклонял, и этот отказ остаётся в силе.
Параметра пути нет: аккаунт берётся из привязки ключа, поэтому клиенту не нужно знать внутренний идентификатор. Тело обязательное — {"acknowledgedOneTimeConsumption": true}, ровно литерал true. Им клиент подтверждает, что показал пользователю: включается одноразовый период, который нельзя отозвать, и назвал дату окончания. Подтверждение попадает в журнал действий аккаунта.
Ответ при успехе — {"success": true, "data": {"status": "activated", "trialEndsAt": "…"}}; вместо activated может прийти already_active (период или подписка уже действуют) либо pending — включение состоялось, подтверждения от Битрикс24 ещё нет, и повторять запрос в этом случае не нужно. Срок задаёт Битрикс24, поэтому показывайте пользователю дату из trialEndsAt, а не своё число дней.
Отказы: 400 DISCLOSURE_REQUIRED (нет подтверждения), 403 INSUFFICIENT_SCOPE (у ключа нет права vibe:cowork), 403 COWORK_DESKTOP_KEY_REQUIRED (ключ другого класса — например, ключ места агента с тем же правом), 403 WRITE_BLOCKED_READONLY_KEY, 409 ALREADY_ACTIVATED, 409 TRIAL_ACTIVATION_UNAVAILABLE, 503 TRIAL_ACTIVATION_RETRY. Предел частоты — 3 запроса в час на аккаунт.
Перед показом шага активации читайте activation.marketTrial.available в GET /v1/cowork/state: это предрасчёт, false окончателен, а true разрешает предлагать, но не обещает успех — отказ на самом включении обрабатывать всё равно нужно. В регионах с тарифной моделью доступа такого пробного периода нет как продукта: предрасчёт отвечает region_not_supported, а сам вызов — 409 TRIAL_ACTIVATION_UNAVAILABLE.
FIX-0813-11: временные ошибки больше не закрывают пробный период навсегда
Было
У каждого аккаунта был счётчик неудачных включений пробного периода, и он доходил до потолка от ЛЮБОЙ ошибки — в том числе от той, где Битрикс24 ничего не решал: запрос до него не дошёл, он ответил внутренней ошибкой или не сложилась наша собственная авторизация. Дойдя до потолка, аккаунт получал 409 TRIAL_ACTIVATION_UNAVAILABLE на любой следующий запрос, и вернуть его в рабочее состояние было нечем. Ответ 503 TRIAL_ACTIVATION_RETRY при этом предлагал повторить — то есть подсказка вела ровно в ту ловушку, где серия сетевых сбоев стоила аккаунту одноразового пробного периода.
Стало
Счётчик расходуют только решения Битрикс24 о самом аккаунте. Ошибка транспорта, внутренняя ошибка на стороне Битрикс24 и проблема с нашей авторизацией попытку не тратят — повтор после 503 TRIAL_ACTIVATION_RETRY теперь безопасен, как и написано в ответе.
Влияние на интеграторов
Менять ничего не нужно. Повторять запрос после 503 можно так же, как и раньше, — но теперь это действительно не приближает аккаунт к отказу. 409 TRIAL_ACTIVATION_UNAVAILABLE остаётся окончательным и означает то, что означал: решение Битрикс24 о самом аккаунте.
FIX-0813-12: активации пробного периода снова хватает на три попытки в час
Было
POST /v1/portals/{id}/activate-market-trial обещал в описании три запроса в час на аккаунт, а на деле отдавал одну попытку: заголовок x-ratelimit-limit приходил со значением 1, и второй запрос в течение часа получал 429 RATE_LIMITED с retry-after около часа. У пользователя, у которого включение сорвалось из-за временной ошибки, кнопка «Повторить» оставалась бесполезной до конца часа.
Стало
Аккаунт получает те самые три попытки в час, как и написано в описании. Значение x-ratelimit-limit совпадает с обещанным, 429 приходит с четвёртого запроса.
Влияние на интеграторов
Менять ничего не нужно. Если вы заложили у себя паузу в час после первого же 429, её можно вернуть к обычной обработке заголовка retry-after.
NEW-0813-13: новый код отказа доступа INT_VIBE_PLUS_REQUIRED
В справочнике кодов появился INT_VIBE_PLUS_REQUIRED (HTTP 402). На международном сегменте он приходит там же, где приходит INT_TARIFF_REQUIRED — на создании и пробуждении инфраструктуры и на выписке ключей — и означает, что аккаунту Битрикс24 нужен тариф Vibe+. Добавление аддитивное: прежние коды и форма ответа не изменились, поэтому обрабатывайте незнакомый код как отказ и ветвитесь по error.code, а не по тексту сообщения. Разбор кодов — в Ошибках.
NEW-0813-14: состояние Cowork/Code отдаёт оплаченный срок
Ответ GET /v1/cowork/state получил два поля в объекте subscription. termMonths — на сколько месяцев вперёд оплачено сиденье (1, 3, 6 или 12; у помесячного — 1). paidThroughAt — дата, до которой оплачено, в формате ISO 8601.
Это не то же самое, что currentPeriodEnd. Расчётный период — окно квоты, оно сдвигается каждые 30 дней независимо от того, на какой срок куплено сиденье. Поэтому у сиденья, оплаченного на год, currentPeriodEnd наступает через месяц, а paidThroughAt — через одиннадцать.
Заодно уточнено описание subscription.pendingTier: понижение тарифа применяется на paidThroughAt, а не на currentPeriodEnd. До появления сроков эти даты всегда совпадали, поэтому прежняя формулировка была верной; теперь совпадение сохраняется только у помесячных сидений. По той же дате заканчивается доступ, если подписка отменена: отмена прекращает автопродление, а оплаченный срок дослуживается целиком.
Прежние вызовы работают без изменений — оба поля добавлены, ни одно не переименовано и не удалено.
FIX-0813-15: переименование сервера теперь видно в кабинете
Было
PATCH /v1/infra/servers/:id меняет displayName и description сервера — документация этой ручки называет их двумя текстовыми полями, которые человек видит в личном кабинете и в карточке приложения в каталоге Битрикс24, и другой ручки для них нет. Но список и карточка приложения в кабинете показывали не сервер, а копию его имени и описания, снятую в момент создания приложения. После переименования GET /v1/infra/servers/:id и GET /v1/me/sources отдавали новое значение, а кабинет — прежнее, и вернуть его к правде было нечем.
Стало
У приложения со связанным сервером кабинет показывает displayName сервера. Описание кабинет берёт своё, если его там задавали, иначе — описание сервера, а правка описания через эту ручку теперь доходит до приложения и тогда, когда у него было своё описание: последняя правка выигрывает.
Имя стало одним значением с двумя дверями: переименование приложения в кабинете меняет displayName сервера, а переименование сервера обновляет карточку. Заголовок карточки в каталоге Битрикс24 после любой из этих правок перевыкладывается автоматически. Имя, введённое в кабинете при создании приложения, теперь попадает и в displayName нового сервера, а не только в карточку.
Действий со стороны клиента не требуется. Приложения, созданные до исправления, тоже следуют за сервером: имя видно в кабинете сразу, а описание — с первой же правки через эту ручку, до неё в кабинете остаётся прежний текст.