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

Изменения API: 4 августа 2026

← Журнал изменений · Август 2026

BC-0804-1: V1 /wake и /start будят galaxy-приложение через хост

Поддержка старого формата до: 22.08.2026

Было

POST /v1/infra/servers/:id/wake и /start для kind=GALAXY_APP отвечали 422 VM_MISSING (у приложения нет cloud VM) и советовали редеплой, даже когда контейнер просто спал после idle. Периодические задачи после первого сна не могли подняться через API.

Стало

Для размещённого galaxy-приложения оба verb'а будят приложение через хост: будят общий хост при необходимости и стартуют контейнер. Успех — HTTP 200. ?wait=true на galaxy не ждёт RUNNING до таймаута / WAKE_TIMEOUT — после cold wake приложение может остаться SLEEPING; опрашивайте GET. Хост с preventWake блокирует и /wake, и /start (403 SERVER_WAKE_BLOCKED или 402 paywall-коды MARKETPLACE_REQUIRED / … — не маркеры TRIAL_EXPIRED). Слот без host/galaxyId → 404 GALAXY_HOST_NOT_FOUND (не 422 VM_MISSING). Для STANDALONE VM_MISSING / override /start без изменений.

BC-0804-2: тип архива при сохранении версии сверяется с его первыми байтами

Поддержка старого формата до: 03.08.2026

Было

Сохранение версии исходников — POST /v1/infra/servers/:id/sources и POST /v1/apps/:id/sources — верило заголовку Content-Type на слово. Архив zip, отправленный с Content-Type: application/gzip, принимался, сохранялся как gzip и получал имя с расширением .tar.gz; выкладка такой версии на сервер падала на распаковке с невнятной ошибкой чтения архива. Автосохранение версии после выкладки записывало формат как gzip всегда, независимо от того, что было в теле запроса.

Стало

При приёме читаются первые байты архива. Прямое противоречие между заявленным типом и содержимым — заявлен application/gzip, а байты zip, или наоборот — отвергается с кодом 415 UNSUPPORTED_ARCHIVE_FORMAT; тело ответа содержит error.hint.declared и error.hint.detected. Типы application/x-tar и application/octet-stream под этот отказ не попадают никогда: их сигнатура не читается в первых восьми байтах, поэтому противоречие с ними установить нечем. Нераспознанное содержимое принимается как раньше.

Автосохранение после выкладки отказа не даёт вообще: там тип архива клиент не заявляет, и распознанные байты просто записываются честно — zip сохраняется как zip и при повторной выкладке уходит в нужный распаковщик.

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

Отправляйте Content-Type, соответствующий архиву (application/gzip для tar.gz, application/zip для zip), либо application/octet-stream, если тип неизвестен. Клиенты, которые уже отправляют корректный заголовок, ничего не меняют.

NEW-0804-3: названия и описания полей у разделов товаров, шаблонов реквизитов и банковских реквизитов

Что нового

GET /v1/product-sections/fields, GET /v1/requisite-presets/fields и GET /v1/bank-details/fields возвращали только type и readonly — ни одно поле не имело человекочитаемого названия, поэтому по справочнику нельзя было понять, что означает, например, rqAccNum. Теперь названия объявлены у всех полей: 7 у разделов товаров, 11 у шаблонов реквизитов, 34 у банковских реквизитов. У шаблонов реквизитов и банковских реквизитов вместе с названием приходит и описание.

Ответ дополняется ключами label и description рядом с уже существующими type и readonly — прежние поля ответа не изменились.

Динамический справочник Битрикс24 эти названия дать не мог: он дополняет только те поля, которых нет в статической схеме, поэтому у объявленных полей его подписи отбрасывались. Операция aggregate у банковских реквизитов остаётся отключённой.

NEW-0804-4: `limit=0` больше не игнорируется молча

Что нового

limit=0 не является размером страницы: параметр отбрасывается, и применяется значение по умолчанию. Раньше это происходило без единого признака — ответ приходил с кодом 200 и полной страницей записей, как будто параметр учли. Теперь в такой ответ добавляется предупреждение в meta.warnings:

JSON
{
  "meta": {
    "warnings": [
      {
        "code": "LIMIT_ZERO_IGNORED",
        "field": "limit",
        "message": "limit=0 is not a page size and was ignored. Valid range: 1..5000; pass an explicit limit (e.g. 5000) to read the whole collection."
      }
    ]
  }
}

Работает на GET /v1/{entity} и POST /v1/{entity}/search для всех сущностей. Само значение не изменилось — прежние вызовы продолжают возвращать столько же записей, сколько и раньше; чтобы прочитать всю коллекцию, передайте явный limit (максимум 5000).

FIX-0804-5: банковские реквизиты: `entityTypeId` помечен как невозвращаемое поле

Было

GET /v1/bank-details/fields описывал entityTypeId обычным числовым полем — читаемым и записываемым. Про то, что Битрикс24 это значение принимает при создании, но никогда не возвращает при чтении, было сказано только в тексте описания поля. Клиент, который строит модель по машиночитаемому справочнику, а не по прозе, добавлял поле в тип чтения, а на месте числа получал пустоту.

Стало

У поля появился признак notReturned: true — в GET /v1/bank-details/fields, в GET /v1/guide и в OpenAPI-схеме (там это аннотация x-notReturned и фраза в описании). Тот же признак этот выпуск ввёл для serverName у телефонных линий.

Поле остаётся доступным для записи: POST /v1/bank-details по-прежнему принимает entityTypeId (всегда 8 — владелец-реквизит). Признак говорит только про чтение.

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

Ничего менять не нужно — признак аддитивен. Если вы генерируете типы по справочнику, entityTypeId можно исключить из модели чтения и оставить в модели создания.

FIX-0804-6: discover называет настоящий идентификатор в пути

Было

GET /v1/guide и OpenAPI-схема показывали путь одиночной записи как /:id у всех сущностей. У четырёх это неправда: smart-processes адресуется публичным entityTypeId (1030+), telephony-lines — номером линии, а bizproc-robots и bizproc-activities — кодом (code), причём собственного id у них нет вовсе. Клиент, прочитавший {id}, подставлял собственное поле id записи и получал 404 SMART_PROCESS_NOT_FOUND, где то же значение названо entityTypeId — притом что опубликованная документация уже писала :entityTypeId и :code.

Стало

GET /v1/guide показывает /v1/smart-processes/:entityTypeId, /v1/telephony-lines/:number, /v1/bizproc-robots/:code и /v1/bizproc-activities/:code; у остальных сущностей путь остался /:id. В OpenAPI имя параметра осталось id: имя path-параметра обязано совпадать с плейсхолдером в шаблоне пути, а сам адрес не менялся — вместо этого описание параметра теперь называет настоящий идентификатор. Там, где у сущности нет собственного поля id (телефонные линии и оба bizproc-справочника), описание так и говорит, а не отправляет сверяться с полем, которого не существует. Описание поля id у smart-processes тоже уточнено.

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

Ничего менять не нужно: маршруты и коды ответов не изменились, изменились только описания. Если вы подставляли в путь smart-processes внутренний id записи, теперь понятно, почему приходил 404 — используйте entityTypeId; для роботов и действий бизнес-процессов — code.

FIX-0804-7: телефонные линии: `name` объявлен nullable, `serverName` помечен как невозвращаемый

Было

GET /v1/telephony-lines/fields объявлял name обычной строкой, хотя у линии без названия приходит null — модель, построенная по справочнику, ломалась на первом же таком значении. Поле serverName выглядело в справочнике обычным читаемым полем, хотя Битрикс24 его не хранит и никогда не возвращает.

Стало

У name появился признак nullable: true — и в GET /v1/telephony-lines/fields, и в GET /v1/guide, и в OpenAPI-схеме (там это форма type: ["string","null"]). У serverName появился признак notReturned: true в тех же местах, а в OpenAPI — аннотация x-notReturned и фраза в описании. Поле осталось в справочнике намеренно: запись в него по-прежнему отклоняется с 400 READONLY_FIELD, и клиент должен иметь возможность найти поле и прочитать причину.

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

Ничего менять не нужно — признаки аддитивны. Если вы генерируете типы по справочнику, name станет string | null, а serverName можно исключить из модели чтения.

FIX-0804-8: рабочие группы: работают `limit > 50` и точное смещение

Было

GET /v1/workgroups?limit=500 возвращал первые 50 записей независимо от того, сколько групп доступно, и meta.hasMore не помогал дочитать остальное. Причина — метод списка у этой сущности называется не .list, а sonet_group.get, и признак «это список» у неё не был объявлен, поэтому ни limit, ни авто-пагинация до Битрикс24 не доходили. Смещение при этом округлялось вниз до границы страницы: offset=30 отдавал записи с первой, а не с тридцать первой.

Стало

limit доходит до Битрикс24, и при limit > 50 платформа сама читает нужное число страниц — как это давно работает у пользователей, отделов и хранилищ. Смещение стало точным: offset=30 начинает выдачу с 31-й записи. То же поведение на POST /v1/workgroups/search и в списочном подзапросе POST /v1/batch.

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

Если вы листали рабочие группы вручную и компенсировали округление смещения на своей стороне (например, отбрасывали первые записи страницы), эту компенсацию нужно убрать — иначе записи будут пропускаться дважды. Для глубокого листания надёжнее курсор: фильтр {">id": последнийId} с сортировкой по id.

FIX-0804-9: удаление приложения доводит снятие регистрации с портала до конца

Было

DELETE /v1/apps/:id снимал приложение с портала одной попыткой. Если портал был недоступен, права отозвали или у автора приложения не оказалось ключа разработчика, попытка молча пропадала: приложение удалялось у нас, но оставалось установленным на портале Битрикс24 — его пункт оставался в меню. Встройки при этом отвязывались только у опубликованных в каталоге приложений и только на облачных порталах.

Стало

Исход попытки сохраняется, и незакрытое снятие повторяется в фоне с нарастающей паузой, пока портал не подтвердит удаление. Встройки снимаются у любого приложения независимо от того, публиковалось ли оно в каталоге.

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

Ответ эндпоинта не изменился — по-прежнему 204 сразу после удаления на нашей стороне. Изменился результат: пункт приложения на портале теперь исчезает и в тех случаях, когда раньше оставался навсегда.

NEW-0804-10: Отказ по таймауту шлюза на выполнении команды несёт подсказку по восстановлению

Отказ с кодом GATEWAY_TIMEOUT у POST /v1/infra/servers/:id/exec теперь дополнен объектом hint с полями reason, recovery и recoveryAction — так же, как это уже сделано для EXEC_TIMEOUT и агентского EXEC_BUSY. Подсказка говорит главное: код возврата не получен, поэтому исход команды неизвестен и она может продолжать выполняться на сервере. Повторный запуск вслепую способен создать вторую копию поверх первой, поэтому сначала стоит выяснить фактическое состояние — прочитать логи или выполнить короткую read-only команду. Для работы, которая заведомо не укладывается в предельное время, подсказка направляет на фоновую задачу.

Поля code и message не изменились — подсказка добавлена аддитивно, и прежние вызовы продолжают работать. Приходит в обоих режимах ответа: в JSON-конверте и SSE-событием error.

FIX-0804-11: отказ при недоступной модели — 429 с выдержкой вместо 502

Было

Когда доступ к моделям временно закрывался из-за череды неудачных вызовов, POST /v1/chat/completions и POST /v1/embeddings отвечали 502 с кодом AI_PROVIDER_UNAVAILABLE, а в error.message приходила внутренняя служебная строка вместо объяснения. Заголовка Retry-After не было, поэтому клиенту нечего было ждать — типовая реакция библиотеки на 5xx — повторить сразу, что продлевало недоступность.

Стало

Тот же отказ приходит как 429, error.type: "rate_limit_exceeded", error.code: "ai_provider_cooldown" (в потоковом кадре — то же имя в верхнем регистре, как у остальных кодов этого семейства), с заголовком Retry-After в секундах; в потоковом ответе то же значение приходит полем retryAfter внутри терминального кадра ошибки. Значение — остаток окна ожидания, не меньше секунды. error.message больше не содержит служебных строк и адресов. Отказ временный: дождитесь Retry-After и повторите тот же запрос.

FIX-0804-12: деплой архива формой multipart сохраняет версию исходников даже при неудачном деплое

Было

POST /v1/infra/servers/:id/deploy с телом multipart/form-data сохранял архив в хранилище исходников только после успешного деплоя. Если деплой падал, версия не появлялась вовсе — разбирать было нечего, а повторная выкладка требовала заново отправить те же байты.

Стало

Архив помещается в хранилище исходников до старта деплоя, и деплой продолжается по ссылке на эту версию. Версия остаётся в истории при любом исходе: при успехе она получает deployStatus: "success", при неудаче — "failed". Блок data.source в ответе не изменился: autoSaved, savedVersionId, sha256 и newVersion заполняются как раньше, повторная отправка тех же байт по-прежнему дедуплицируется и новой версии не создаёт.

Появился новый код отказа SOURCE_DEPOT_UNAVAILABLE (502): хранилище исходников не приняло архив, деплой не стартовал, запрос можно повторить без изменений. Раньше такой сбой приходил как VALIDATION_ERROR (400), то есть выглядел ошибкой запроса.

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

Действий не требуется. Список версий (GET /v1/infra/servers/:id/sources) у клиентов, деплоящих формой multipart, теперь может содержать версии неудавшихся выкладок — они помечены deployStatus: "failed".

NEW-0804-13: поля адресов приходят с человекочитаемыми подписями и описаниями

Раньше GET /v1/addresses/fields у шести полей из четырнадцати отдавал в title имя поля Битрикс24 — TYPE_ID, ENTITY_TYPE_ID, ENTITY_ID, COUNTRY_CODE, ANCHOR_TYPE_ID, ANCHOR_ID. Показать такую подпись пользователю нельзя, а значения кодов приходилось искать в документации.

Теперь у этих шести полей в title приходит подпись на языке портала, а у полей, которым есть что добавить к подписи, появился ключ description с назначением поля и расшифровкой кодов: типы адреса (все двенадцать, с 1 по 12 — какие из них доступны, зависит от страновой зоны портала) и типы владельца (1 — лид, 3 — контакт, 4 — компания, 8 — реквизит). У поля countryCode описание не обещает формат: в документации REST Битрикс24 это поле помечено как неиспользуемое и оставленное для обратной совместимости. У кода 1 расшифровка дополнена подписью из англоязычного интерфейса Битрикс24 — Street address: сам Битрикс24 называет этот тип по-разному в русской и английской версиях, и без оговорки словарь расходился бы с подписью, которую пользователь видит в интерфейсе.

Подписи, которые Битрикс24 отдаёт сам, не изменились. Рядом с title та же подпись теперь приходит и в ключе label — так же, как у остальных сущностей, поэтому читать подписи можно одним способом на любой сущности. Ключи description и label добавляются к описанию поля, прежние ключи остаются на месте, поэтому менять ничего не нужно.

Заодно исправлены расшифровки кодов типа адреса в документации операций создания, чтения, изменения и удаления адреса: там были указаны неверные значения, а код 13 не существует вовсе — набор типов заканчивается на 12, и какие из них доступны, зависит от страновой зоны портала.

NEW-0804-14: поля товаров приходят с подписями, описаниями и словарём формата описания

GET /v1/products/fields описывал двадцать одно поле товара только типом и признаком «только для чтения» — ни подписи, ни описания. Понять по такому ответу, что measure это единица измерения, а vatId — ставка НДС, было нельзя.

Теперь каждое из двадцати одного поля несёт label на языке портала, а поля, у которых есть что добавить к подписи, — ещё и description: где взять список допустимых значений (GET /v1/currencies, GET /v1/product-sections, GET /v1/catalogs, GET /v1/users), как работает сортировка и что задаёт формат описания. У поля descriptionType появился словарь enum со значениями text и html.

Ключи добавляются к описанию поля, прежние type и readonly не меняются, поэтому менять ничего не нужно. Свойства каталога PROPERTY_<N> по-прежнему приходят с подписью из настроек портала.

NEW-0804-15: все 45 полей предложения приходят с подписью и описанием

GET /v1/quotes/fields отдавал подпись у тридцати полей из сорока пяти. Пятнадцать оставшихся — ровно базовые: id, title, dealId, contactId, companyId, amount, currency, assignedById, createdBy, comments, isManualOpportunity, beginDate, closeDate, createdTime, updatedTime — описывались только типом и признаком «только для чтения». Описания (description) не было ни у одного поля.

Теперь подпись есть у всех сорока пяти полей, и у каждого появилось описание: назначение поля, где взять список допустимых значений (GET /v1/currencies, GET /v1/users, GET /v1/deals и другие), поведение при записи. Отдельно названы расхождения имён, на которых легко ошибиться: сумма в Битрикс24 называется opportunity, валюта — currencyId, а даты начала и закрытия — begindate и closedate целиком в нижнем регистре.

У поля stageId словаря значений нет намеренно: набор стадий настраивается на портале, поэтому в описании стоит ссылка на справочник GET /v1/statuses?filter[entityId]=QUOTE_STATUS — статический словарь устарел бы.

Ключи добавляются к описанию поля, прежние type и readonly не меняются, поэтому менять ничего не нужно.

NEW-0804-16: поля товаров каталога приходят с подписями и описаниями

GET /v1/catalog-products/fields описывал все сорок два поля товара каталога только типом и служебными признаками — ни подписи, ни описания. Понять по такому ответу, чем purchasingCurrency отличается от валюты цены, а quantityTrace — от canBuyZero, было нельзя.

Теперь каждое из сорока двух полей несёт label на языке портала, а тридцать восемь полей — ещё и description. В описаниях названо то, что раньше приходилось выяснять на практике: iblockId задаётся только при создании и не даёт перенести товар между каталогами; iblockSection принимается только при записи, а на чтении основной раздел приходит скаляром iblockSectionId; available и bundle вычисляет Битрикс24; recurSchemeLength, recurSchemeType и trialPriceId работают только в коробочной версии Битрикс24 при продаже контента. Где значение берётся из справочника, указан эндпоинт — GET /v1/catalogs, GET /v1/catalog-sections, GET /v1/currencies, GET /v1/users.

У полей previewTextType и detailTextType набор значений приходит машиночитаемым словарём enum (text и html) — так же, как у формата описания товара, а не прозой внутри описания.

Ключи добавляются к описанию поля, прежние type, readonly, createOnly и nullable не меняются, поэтому менять ничего не нужно.

FIX-0804-17: схема полей шаблона реквизитов объявляет inShortList булевым

Было

GET /v1/requisite-presets/:presetId/fields/schema описывал поле inShortList типом char, хотя чтение строк того же шаблона отдаёт true/false, а запись принимает true/false. Схема противоречила данным, которые она описывает, и клиент, полагавшийся на объявленный тип, готовился разбирать односимвольную строку.

Стало

В том же ответе inShortList.type приходит как boolean. Остальные ключи описания поля (isRequired, isReadOnly, title и прочие) не изменились, типы остальных полей — тоже.

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

Менять ничего не нужно: данные и раньше приходили булевыми. Проверка, сравнивающая inShortList.type со строкой char, перестанет совпадать — сверяйте с boolean.

NEW-0804-18: скачивание записей звонков и вложений таймлайна

Появились два эндпоинта для файлов CRM, до которых нельзя было добраться через скачивание файла Диска.

GET /v1/activities/:activityId/files/:fileId/download отдаёт файл дела, в том числе запись звонка. До этого сделать это через API было нельзя: файл дела не является объектом Диска, его идентификатор живёт в отдельном пространстве, пересекающемся с идентификаторами Диска, а ссылка из ответа дела приходит с пустым параметром авторизации — запрос по ней возвращает страницу входа с кодом 200. Эндпоинт добавляет авторизацию сам, проверяет, что файл действительно принадлежит названному делу, и отдаёт поток байтов.

GET /v1/timelines/:commentId/files/:fileRef/download отдаёт вложение комментария таймлайна. В fileRef принимается любой из двух идентификаторов: ID привязки, который показывает интерфейс портала, и ID объекта Диска — ключ объекта в поле files ответа комментария. Первый считает доступ через сам комментарий, поэтому дотягивается до вложений, которые скачивание файла Диска отдавать отказывается; второй идёт через личные права на Диске. Сначала читается сам комментарий, затем пробуется ID объекта Диска, и только если его нет в списке файлов комментария — ID привязки; указывать выбор не нужно.

Оба эндпоинта требуют скоуп crm и никогда не возвращают адрес для скачивания: в нём содержится код авторизации, поэтому наружу уходит только содержимое. Файл, принадлежность которого названному делу или комментарию не подтверждается, получает 404 — это касается и вложения, которое висит на записи другого типа, например на задаче с тем же номером, — без этой проверки эндпоинт позволял бы перебирать файлы портала, поскольку сам Битрикс24 в таком случае отвечает страницей под кодом 200, а не отказом.

Проверка адреса распространяется и на перенаправления: эндпоинт проходит их сам, сверяя каждый шаг, ограничивает цепочку по длине и по времени и не идёт по перенаправлению на внутренний адрес — такой ответ становится 502. Это же касается скачивания файла Диска, которое пользуется той же обвязкой.

404 на скачивании вложения означает именно неверную ссылку. Временная причина — лимит запросов Битрикс24, недоступность портала, сработавшая защита от повторяющихся ошибок — приходит как она есть: 429 либо 502/503 с заголовком Retry-After. Разница практическая: по 404 повторять запрос бессмысленно, по 429/5xx — нужно, с задержкой. Срок в Retry-After считается по тому вызову Битрикс24, который действительно упёрся в лимит.

Контракт скачивания файла Диска не менялся: те же параметры, те же ответы. Общей обвязкой оно унаследовало только проверку адреса и перенаправлений, описанную выше.

FIX-0804-19: сообщение бота без текста отбивается понятной ошибкой, а не мнимым успехом

Было

POST /v1/bots/:botId/messages с текстом в неузнанном поле — например {"dialogId": "…", "text": "привет"} — уходил в Битрикс24 без содержимого, и тот отвечал 422 с кодом EMPTY_MESSAGE и текстом «Message can't be empty». Понять из такого ответа, что дело в имени поля, было нельзя: текст-то передан.

Хуже вело себя обновление. PATCH /v1/bots/:botId/messages/:messageId в той же ситуации отвечал 200 {"result": true}, а текст сообщения не менялся — мнимый успех, после которого интегратор считал правку применённой.

Стало

Оба запроса проверяют содержимое до обращения к Битрикс24 и при его отсутствии отвечают 400 с кодом MESSAGE_REQUIRED. В тексте ошибки перечислены нераспознанные ключи тела и указано, что текст сообщения кладётся в поле message. Пустой массив в attach и пустая строка в message содержимым не считаются; блок attach без текста — считается, как и число (0 это текст «0»).

Обёртка fields — способ передать тело в родном виде Битрикс24, и «обёртка передана» теперь понимается одинаково на всех шагах обработки. Значение, обёрткой не являющееся (false, 0, пустой массив), обёрткой и не считается: {"dialogId": "…", "fields": false} получает тот же 400 с кодом MESSAGE_REQUIRED, а {"message": "привет", "fields": []} отправляет текст, а не теряет его.

Это тот же код и та же формулировка, что у соседнего POST /v1/chats/:dialogId/messages: один контракт на одинаковую ошибку в двух родственных эндпоинтах.

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

Запрос с текстом в поле message работает как раньше. Запрос, который раньше получал 422 EMPTY_MESSAGE, теперь получает 400 MESSAGE_REQUIRED с указанием, что исправить. Поле text синонимом message не становится: на чтении содержимое сообщения действительно называется text, но принимать оба имени молча значило бы развести контракт с эндпоинтом чатов.