Для AI-агентов: markdown этой страницы — /docs-content/changelog/2026-07-09.md индекс документации — /llms.txt
Изменения API: 9 июля 2026
← Журнал изменений · Июль 2026
FIX-0709-1: транзиентная перегрузка БД теперь отдаёт 503 с Retry-After вместо 500
Было
В редкой форме кратковременной перегрузки БД (исчерпание коннектов) часть запросов (включая POST /v1/infra/servers) возвращала 500.
Стало
Такие запросы возвращают 503 с кодом POOL_EXHAUSTED и заголовком Retry-After. Ошибка транзиентная — повтори запрос с задержкой (backoff).
Влияние на интеграторов
Клиенты, повторяющие запросы при 5xx, теперь должны обрабатывать 503 и уважать Retry-After. POST /v1/infra/servers неидемпотентен — повтор может создать дубль сервера, поэтому повторяйте с backoff, а не немедленно.
FIX-0709-2: placements/bind честнее сообщает о необходимости подписки Маркетплейса
Было
При привязке плейсмента через ключ приложения на портале без активной подписки «BitrixGPT + Маркетплейс» Bitrix24 отвечал отказом доступа, а POST /v1/placements/bind возвращал непрозрачный 502 BITRIX_UNAVAILABLE без указания причины. Подписка требуется на пути через ключ разработчика независимо от коммерческого тарифа, но GET /v1/me не сообщал об этом предусловии заранее.
Стало
Отказ по подписке теперь классифицируется: POST /v1/placements/bind возвращает 403 с кодом B24_MARKET_SUBSCRIPTION_REQUIRED (или B24_MARKET_TRIAL_USED, если демо уже использован), понятным userMessage и ссылкой на оформление в details.upgradeUrl. У ключа приложения в GET /v1/me добавлен блок placements.bindPrerequisite — он заранее описывает предусловие Bitrix24 (путь через ключ разработчика требует активной подписки Маркетплейса, устаревший OAuth-путь — коммерческого тарифа) и перечисляет коды ошибок. Прочие отказы привязки (неизвестный clientId, устаревший embedding) по-прежнему возвращают 502 BITRIX_UNAVAILABLE.
Влияние на интеграторов
Менять ничего не нужно, успешные вызовы не затронуты. Тем, кто обрабатывал 502 BITRIX_UNAVAILABLE при привязке, стоит дополнительно ловить 403 B24_MARKET_SUBSCRIPTION_REQUIRED / B24_MARKET_TRIAL_USED и подсказывать пользователю оформить подписку на портале.
FIX-0709-3: bindPrerequisite в GET /v1/me учитывает регион портала
Было
Блок placements.bindPrerequisite у ключа приложения описывал предусловие привязки одинаково для всех порталов: subscriptionRequired: true, рецепт «попросите администратора активировать подписку Маркетплейса» и список кодов с B24_MARKET_SUBSCRIPTION_REQUIRED / B24_MARKET_TRIAL_USED. На порталах с тарифной моделью доступа отказ привязки приходит с кодом INT_TARIFF_REQUIRED, а подписки там нет — предложенный рецепт был невыполним.
Стало
Блок зависит от региона портала. На порталах с подписочной моделью доступа он прежний. На порталах с тарифной моделью subscriptionRequired равен false, текст note описывает требование коммерческого тарифа Битрикс24, а errorCodes содержит INT_TARIFF_REQUIRED и BITRIX_UNAVAILABLE — только те коды, которые портал действительно может получить.
Влияние на интеграторов
Успешные вызовы не затронуты. Если вы читали errorCodes из bindPrerequisite как полный перечень, учтите, что теперь он сужен до достижимых на конкретном портале кодов. Сами коды и поведение POST /v1/placements/bind не менялись.
BC-0709-4: Поля CRM, задач и лендингов приведены к реальному контракту Битрикс24
Поддержка старого формата до: 09.01.2027
Было
GET /v1/deal-categories возвращал isLocked строкой "Y"/"N", а GET /v1/payments — paySystemIsCash строкой "Y"/"N". GET /v1/leads в каждом ответе отдавал служебное поле searchContent (внутренний полнотекстовый индекс Битрикс24). Поля paySystemXmlId, dateMarked, dateResponsibleId у платежей приходили как есть, без нормализации даты.
Стало
isLocked (воронки) и paySystemIsCash (платежи) теперь имеют тип boolean (true/false). searchContent в ответах GET /v1/leads больше не отдаётся. У платежей добавлены задекларированные поля paySystemXmlId (строка), dateMarked и dateResponsibleId (даты нормализованы в единый формат ISO с суффиксом Z). У задач добавлены changedBy/closedBy/statusChangedBy (только для чтения — попытка записать возвращает 400 READONLY_FIELD). GET /v1/currencies/fields отдаёт человекочитаемые label для полей и поле lang; GET /v1/deal-categories/fields — label для полей; GET /v1/sites/fields — флаг nullable у полей, которые могут прийти пустыми.
Что делать интеграторам
Читать isLocked и paySystemIsCash как boolean, а не сравнивать со строкой "Y". Если код опирался на поле searchContent у лидов — перестать: оно было служебным и не задокументированным.
FIX-0709-5: создание сущности с пустым телом отклоняется явной ошибкой
Было
Создание сущности с пустым телом (или вовсе без тела, но с заголовком Content-Type: application/json) доходило до Битрикс24 и молча создавало сущность со значениями по умолчанию — включая сделки, лиды, контакты, компании, счета и смарт-процессы. Повторный вызов или клиент без тела так плодил мусорные записи в CRM. Это касалось всех трёх поверхностей создания: одиночного POST /v1/{entity}, пакетного POST /v1/{entity}/batch и общего POST /v1/batch.
Стало
Такой запрос возвращает 400 EMPTY_CREATE_BODY (в пакетных вызовах — ошибку элемента) до обращения к Битрикс24, на всех трёх поверхностях. Осмысленное создание всегда несёт хотя бы одно поле — передайте нужные поля в теле запроса. Сущности, у которых уже есть проверка обязательных полей, ведут себя как прежде.
FIX-0709-6: снятие блокировки сервера принимает пустое тело JSON
Было
DELETE /v1/infra/servers/:id/lock с заголовком Content-Type: application/json и пустым телом возвращал 400 (пустое JSON-тело). Чтобы снять зависшую блокировку, приходилось слать явное {} — не зная этого, клиент упирался в тупик.
Стало
Пустое тело при этом заголовке принимается как {}; запрос без тела отрабатывает штатно и снимает блокировку. Явное {} по-прежнему работает.
FIX-0709-7: события портала теперь будят спящее galaxy-приложение
Было
Событие Битрикса, отправленное на подписку спящего galaxy-приложения, не будило его — доставка уходила в повторные попытки и после их исчерпания терялась.
Стало
Платформа будит спящее galaxy-приложение при доставке события и доставляет его после подъёма — как для обычного сервера.
NEW-0709-8: camelCase-ключи внутри communications при создании дела
POST /v1/activities теперь принимает вложенные ключи элементов communications в camelCase (type, value, entityTypeId, entityId) — единообразно с остальным API. Раньше вложенные ключи принимались только в ВЕРХНЕМ регистре Bitrix24 (TYPE, VALUE, ENTITY_TYPE_ID, ENTITY_ID), а camelCase-форма молча отбрасывалась — communications: [{ "type": …, "value": … }] возвращал 422 «COMMUNICATIONS is not defined or invalid», тогда как [{ "TYPE": …, "VALUE": … }] создавал дело. ВЕРХНИЙ регистр по-прежнему работает; если в одном объекте заданы обе формы одного ключа, приоритет у ВЕРХНЕГО регистра.
FIX-0709-9: снятие с публикации убирает вкладку по всем обработчикам приложения
Было
POST /v1/apps/:id/unpublish снимал placement только по обработчику, совпадающему с ожидаемым платформенным адресом. Если вкладка была привязана к техническому адресу самого приложения, Битрикс24 не находил её и не удалял — вкладка оставалась висеть в карточке CRM, и через API её уже нельзя было убрать.
Стало
Снятие с публикации теперь убирает placement по всем обработчикам приложения, включая привязанные к техническому адресу сервера — осиротевшая вкладка исчезает.
NEW-0709-10: Самоописание ключей в GET /v1/guide
Ответ GET /v1/guide дополнен блоком data.keysAuth. Он описывает два эндпоинта самоописания — GET /v1/me и GET /v1/guide — и содержит ссылки на документацию: контракт ответа каждого из них, режим доступа ключа и общее описание типов ключей.
Оба эндпоинта работают по одному заголовку X-Api-Key, токен сессии для них не нужен.
Поле аддитивное: существующие клиенты не затронуты.
Затронутые эндпоинты: GET /v1/guide
FIX-0709-11: GET /v1/{entity}/:id теперь учитывает ?select=
Проекция полей ?select= на чтении одной записи по id раньше игнорировалась: ответ всегда приходил со всеми полями, хотя /v1/me заявляет, что ?select= работает «на списке, чтении по id и POST /search». Теперь чтение по id проецирует ответ так же, как список и поиск, — приводя поведение в соответствие с задокументированным.
Было
GET /v1/leads/42?select=id,title возвращал полную запись (все поля).
Стало
GET /v1/leads/42?select=id,title возвращает только id и title. Поддерживаются формы через запятую (?select=id,title), массивом (?select[]=id&select[]=title) и с индексами (?select[0]=id&select[1]=title); id включается в ответ всегда. Неизвестное имя поля молча пропускается — это не ошибка. При одновременном ?select= и ?include= связанная сущность в ответе сохраняется. Индексная форма (?select[0]=…) раньше возвращала 500 и на списке GET /v1/{entity} — теперь тоже проецирует корректно.
FIX-0709-12: /fields сущностей заказов, позиций корзины, пресетов реквизитов и шаблонов документов приведены к реальному контракту B24
Было
GET /:entity/fields (и генерируемая по нему OpenAPI-схема) объявлял поля, которые Bitrix24 не возвращает: provider у шаблонов документов; reserved, sumPaid, dateBill, datePayBefore, datePaid, empPaidId, userEmail, userName на верхнем уровне заказа; module, fUserId, lid, dateRefresh, subscribe, reserved, reserveQuantity у позиций корзины; originatorId у пресетов реквизитов. Фильтрация и сортировка по этим полям молча не срабатывали. При этом реально приходящие поля не были объявлены: requisiteLink у заказа, type/properties/reservations у позиции корзины. Пресеты реквизитов принимали countryId/entityTypeId на обновление, где Bitrix24 их молча игнорирует.
Стало
Несуществующие поля убраны из /fields и OpenAPI. Реально приходящие поля объявлены: у заказа — requisiteLink (объект requisiteId/bankDetailId/mcRequisiteId/mcBankDetailId, только чтение); у позиции корзины — type, properties, reservations (только чтение). У пресетов реквизитов countryId и entityTypeId помечены как задаваемые только при создании: обновление возвращает 400 READONLY_FIELD вместо тихого игнорирования.
Влияние на интеграторов
Ответы list/get не меняются — убранные поля и так никогда не приходили. Если запрос фильтровал или сортировал по убранному полю, теперь он вернёт 400 — используйте реальные поля из /fields (например, даты и суммы оплаты у заказа лежат внутри массива payments, а не на верхнем уровне). Обновление countryId/entityTypeId у пресета реквизитов теперь явно отклоняется — задавайте эти поля только при создании.
Затронутые эндпоинты: GET /v1/orders/fields, GET /v1/basket-items/fields, GET /v1/requisite-presets/fields, GET /v1/doc-templates/fields
NEW-0709-13: GET /:entity/fields отдаёт человекочитаемые label и описания для сделок, лидов, счетов, дел, справочников и комментариев таймлайна
Ответ GET /v1/deals/fields, /v1/leads/fields, /v1/invoices/fields, /v1/activities/fields, /v1/statuses/fields и /v1/timelines/fields теперь несёт по каждому полю человекочитаемые label и description по-русски. У полей со служебными кодами добавлены словари enum: у сделок — stageSemanticId (P — в работе, S — успех, F — провал); у дел — typeId, direction, priority, status, notifyType и descriptionType. Прежние вызовы работают без изменений — это дополнительные поля метаданных, форма ответа не меняется.
FIX-0709-14: POST /v1/batch — единый формат ошибок под-вызовов и totals только для list/search
Было
Ошибка Bitrix24 внутри успешного 200-ответа POST /v1/batch (например, get несуществующего элемента) попадала в data.errors[<id>] в исходной форме Bitrix24 { error, error_description } — не в общем для V1 конверте { code, message }, который используют ошибки валидации и любой другой ответ API. Поле data.totals[<id>] при этом заполнялось для любого действия, включая get/create/update/delete, где одиночное число рядом с единственной записью не имеет смысла.
Стало
Ошибка под-вызова приводится к { code, message } (error → code, error_description → message), как у остальных ошибок. data.totals[<id>] заполняется только для действий list и search — там, где счётчик совпадений реально имеет смысл.
FIX-0709-15: GET /v1/openline-configs — нормализация пустых значений в ответе
Было
Ответы GET /v1/openline-configs и GET /v1/openline-configs/:id отдавали служебные поля в неудобных для клиента формах: KPI_FIRST_ANSWER_LIST, KPI_FURTHER_ANSWER_LIST, DEFAULT_OPERATOR_DATA приходили как null (на них падал .map/.length); AUTO_CLOSE_TEXT для незаданного значения приходил как "" в карточке и как null в списке; WORKTIME_HOLIDAYS/WORKTIME_DAYOFF для пустого набора приходили как [""] (массив с одной пустой строкой).
Стало
Списки нормализованы: null → []. AUTO_CLOSE_TEXT приведён к единому null для пустого значения и в списке, и в карточке. WORKTIME_HOLIDAYS/WORKTIME_DAYOFF для пустого набора приходят как []. Список и карточка теперь отдают одинаковую форму этих полей.
FIX-0709-16: GET /v1/users/fields отдаёт возможные значения (items) для UF-полей-перечислений
Было
Пользовательское поле-перечисление (UF_USR_* типа «список») приходило в GET /v1/users/fields как { "type": "string", "label": "…" } — без списка возможных значений. Причина: метод user.fields возвращает у UF-полей только подпись, без типа и вариантов, поэтому перечисление было неотличимо от строки.
Стало
Такое поле приходит с настоящим типом и списком вариантов: { "type": "enumeration", "label": "…", "items": [ { "ID": "…", "VALUE": "…", "DEF": "…", "XML_ID": "…" }, … ] }. Значения дочитываются из user.userfield.list — для этого у ключа должен быть скоуп user.userfield; если он не выдан, поле по-прежнему отдаётся с подписью, но без items (мягкая деградация). Заодно у остальных UF-полей (money, date и т. п.) в ответе появляется их настоящий тип вместо string.
FIX-0709-17: подсказка hint при пустой очереди событий появляется по факту устойчивой пустоты
Было
GET /v1/bots/:botId/events увеличивал счётчик пустых ответов ровно на каждый запрос, и поле hint появлялось строго после пятого подряд пустого ответа. Число в тексте подсказки совпадало с количеством сделанных запросов.
Стало
Счётчик пустых ответов обновляется периодически, а не на каждый запрос, поэтому hint появляется после устойчивой пустоты очереди — при рекомендованном интервале опроса 2–5 секунд спустя примерно пару минут непрерывно пустого опроса. Число N в тексте отражает количество зафиксированных периодов пустоты, а не точное количество сделанных запросов. Правило «доставлено событие → счётчик и подсказка сбрасываются» не изменилось.
Влияние на интеграторов
Менять код не нужно. Если вы опирались на появление hint строго на пятом запросе или трактовали N как точное число запросов — используйте persisted и наличие событий как основной сигнал, а hint как диагностическую подсказку.