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

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

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

NEW-0827-1: агрегация помечает неполную сумму рядом с самим числом

Было

POST /v1/{entity}/aggregate с sum / avg / min / max считает по первым 5000 записям под фильтр. Признак неполноты лежал только в data.meta.truncated, а data.aggregates.amount выглядел как { "sum": 1234567 } — обычное число без пометок. Клиент, который читает только сумму, получал заниженный результат под кодом 200 и не имел, за что зацепиться: data.count при этом показывал полное количество записей.

Стало

Когда выборка усечена, каждый объект поля в data.aggregates и в groups[].aggregates дополнительно несёт truncated: true — { "sum": 1234567, "truncated": true }. Тем же условием в data.meta.warnings добавляется предупреждение с кодом AGGREGATE_TRUNCATED. Значения sum / avg / min / max остаются числами, в объект их никто не оборачивает. На полной выборке ответ не меняется вовсе: ключа truncated в объекте поля нет, meta.warnings не появляется. Потолок 5000 и data.count работают как раньше.

У группировки добавилось ещё одно поле — groups[].truncated: при усечении сам объект группы несёт этот признак рядом со своим счётчиком. Признак говорит, что образцом является ответ; точен ли счётчик группы, показывает meta.aggregatePath — на обычном обходе groups[].count посчитан по прочитанному срезу, а в режиме счётчиков по стадиям (meta.aggregatePath: "fanout") он берётся отдельной пробой и точен. На группировке с одним только count это единственная пометка у числа: у count-выражения объекта поля не возникает, и оба бэга aggregates приходят пустыми. data.count и data.meta.totalRecords остаются точными на выборке любого размера и признака не несут.

Вместе с признаком неполноты ответ теперь всегда сообщает размер нехватки. Раньше meta.recordsShortfall приходил только тогда, когда усечение случилось НЕ из-за потолка: на выборке больше 5000 записей ответ поднимал truncated: true, но поля с размером дыры не было вовсе. Именно этот случай — самый частый: на воронке в 20 000 сделок клиент видел «ответ является образцом» и ноль в качестве размера пропажи. Теперь на любой причине усечения рядом с признаком едет квантификатор — meta.recordsShortfall (сколько записей не доехало до чисел) либо meta.pageErrorSample (если срез оборвался ошибкой подстраницы). На полной выборке ни того, ни другого ключа в ответе по-прежнему нет.

Одновременно убрана ложная тревога. Признак усечения раньше поднимался по сравнению «всего записей больше 5000», а это лишь косвенная примета того, что чтение обрежут. На сущностях, где ограничение до Битрикс24 не доезжает — страницы и сайты (landing.*), настройки открытых линий, — обрезания не происходит и строки читаются все. Такой ответ всё равно объявлял себя образцом. Теперь признак ставится по факту: прочитано меньше, чем обещано, — тогда и только тогда. На полностью прочитанной выборке любого размера ответ снова считается полным.

Заодно закрыт разрыв на группировке сделок по стадиям: если обход стадии возвращал меньше строк, чем насчитала проба (обычно из-за прав доступа), ответ раньше приходил с data.meta.truncated: false и выглядел полным. Теперь такой ответ честно поднимает truncated — и вместе с ним получает и пометку у числа, и предупреждение.

BC-0827-2: порядок установки среды выполнения и запуск nginx изменились

Поддержка старого формата до: не предусмотрена

Было

При повторной выкладке среда выполнения устанавливалась после остановки прежней версии приложения. Сбой установки мог оставить приложение остановленным. Для static, php83 и php83-mysql установка пакета могла неявно запустить и включить системный nginx.service, и запрос мог полагаться на этот процесс.

Стало

POST /v1/infra/servers/:id/deploy устанавливает среду выполнения до остановки и замены файлов приложения. Если установка завершается ошибкой, прежнее приложение не останавливается. Установка nginx для static, php83 и php83-mysql не запускает системный nginx.service и не оставляет его впервые включённым. Существующее состояние включения сервиса сохраняется.

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

Для static, php83 и php83-mysql проверьте, что команда из поля start сама запускает нужный процесс, слушающий порт приложения внутри app.service. Не полагайтесь на неявный запуск системного nginx.service. Запросы с другими средами выполнения менять не нужно.

FIX-0827-5: приглашение пользователей сохраняет все поля анкеты

Было

POST /v1/users/invite принимал десять записываемых полей анкеты в обычном формате API Вайбкод, но передавал их в Битрикс24 без преобразования. Сотрудник создавался, а фотография, внешний идентификатор, часовой пояс и личные данные оставались пустыми.

Стало

POST /v1/users/invite преобразует эти поля в формат Битрикс24. Клиенту не нужно менять запрос, а прежний формат полей Битрикс24 продолжает работать.

FIX-0827-6: одиночное чтение находит комментарий при строковом идентификаторе

Было

GET /v1/tasks/:taskId/comments/:id мог отвечать 404 NOT_FOUND, если Битрикс24 возвращал идентификатор найденного сообщения строкой. При этом тот же комментарий присутствовал в списке комментариев задачи.

Стало

Эндпоинт нормализует числовой идентификатор из ответа Битрикс24 и возвращает найденный комментарий с числовыми id и authorId.

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

Изменения в клиентах не нужны.

FIX-0827-7: select контактов снова принимает типизированные email-адреса

Было

POST /v1/contacts/search и подзапрос контактов в POST /v1/batch отклоняли emailWork, emailHome и emailMailing с кодом UNKNOWN_SELECT_FIELD, хотя ответы контактов уже содержали эти значения. GET /v1/contacts/fields не перечислял эти имена.

Стало

Обе операции принимают три имени в select и возвращают успешный ответ с выбранными значениями. GET /v1/contacts/fields описывает их как nullable-поля только для чтения.

FIX-0827-8: тарифные заголовки возвращаются для инфраструктурных запросов

Было

Ответы методов семейства /v1/infra/* не содержали X-Tariff-Checked-At и X-Tariff-Is-Commercial, даже когда сверка тарифа завершилась успешно.

Стало

Ответы /v1/infra/* содержат тарифные заголовки по тем же правилам, что и /v1/me: время последней успешной сверки и признак коммерческого тарифа возвращаются при наличии соответствующих данных портала. Статус и тело ответа не изменились.

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

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

NEW-0827-9: схема элементов массивов доступна в контрактах полей

GET /v1/orders/fields, GET /v1/basket-items/fields и GET /v1/guide теперь возвращают itemSchema для массивов с объявленной формой элемента. Схема рекурсивно описывает type, readonly, nullable, properties и вложенные itemSchema. Клиенты могут опционально читать новое поле, существующие интеграции продолжают работать без изменений. Отдельный ключ items по-прежнему содержит сырой справочник значений Битрикс24 у полей-перечислений.

FIX-0827-10: списки без общего количества больше не выглядят завершёнными раньше времени

Было

Если Битрикс24 не возвращал общее количество записей, запрос списка с лимитом больше 50 останавливался после первой страницы. В окне до 50 записей полная страница тоже могла ошибочно выглядеть последней, потому что её размер принимался за размер всей коллекции.

Стало

Платформа продолжает чтение после каждой полной страницы и останавливается на короткой странице или на лимите запроса. Когда конец коллекции ещё не доказан, общее количество остаётся неизвестным, а meta.hasMore или truncated сообщает, что записи могут продолжаться.

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

Менять запросы не нужно. Запрошенные окна больше одной страницы больше не усекаются молча; у GET /v1/mail/messages теперь всегда есть булевый признак truncated, а неизвестный total отсутствует вместо null.

Затронутые эндпоинты: GET /v1/humanresources/nodes, GET /v1/mail/mailboxes, GET /v1/mail/messages.

NEW-0827-11: самоописание указывает на документацию промокодов Коворк/Код

Ответы GET /v1/guide и GET /v1/me теперь называют пару промокодов настольного приложения. В разделе cowork ответа GET /v1/guide появились указатели docs.couponPreview и docs.couponRedeem на страницы POST /v1/cowork/coupon/preview и POST /v1/cowork/coupon/redeem, а правила /v1/me получили пункт про них: какой класс ключа нужен, чем проверка отличается от погашения и почему accessGranted: false показывают отдельным экраном.

Сами эндпоинты работают как прежде — новое только в том, что интегратор и агент находят их описание, не читая журнал.

FIX-0827-12: пределы частоты Коворк/Код больше не называются числом, которого клиент не получает

Было

Справочник GET /v1/guide, правила GET /v1/me и страницы документации раздела Коворк/Код называли пределы частоты конкретным числом: 20 запросов в минуту у POST /v1/cowork/coupon/preview, 10 у POST /v1/cowork/coupon/redeem, 30 у GET /v1/cowork/subscription/preview, 5 у DELETE /v1/cowork/key, 3 за пять минут у POST /v1/cowork/deploy-key, 30 у GET /v1/cowork/applications/defaults и 6 у POST /v1/cowork/applications. Ни одно из этих чисел клиенту не приходило: предел делится между процессами платформы, и заголовок x-ratelimit-limit отдавал соответственно 7, 4, 10, 2, 1, 10 и 2. У deploy-key, key и мастера создания приложения расходились между собой два канала одного эндпоинта — страница обещала одно, заголовок отдавал другое.

Стало

Справочник GET /v1/guide, правила GET /v1/me и страницы документации раздела называют источником действующего значения заголовок ответа x-ratelimit-limit и просят не закреплять число в клиентском коде. Поведение самих эндпоинтов не менялось, ответ остаётся прежним — исправлено описание, которое расходилось с ним. Клиент, читавший заголовок, не меняет ничего.

Что этой записью НЕ закрыто. Машинная схема GET /v1/openapi.json по-прежнему называет числа пяти операциям раздела — subscription/preview, deploy-key, applications/defaults, applications и key, — и эти числа расходятся с заголовком так же, как расходились остальные. Клиент, сгенерированный по схеме, пока обязан читать x-ratelimit-limit, а не значение из описания операции. Верно в схеме одно обещание — «три запроса в час» у POST /v1/cowork/activate-market-trial: там предел умножается на число процессов до деления.

FIX-0827-13: создание линии телефонии возвращает рабочий ключ

Было

POST /v1/telephony-lines возвращал внутренний числовой идентификатор. Его нельзя было использовать в адресе для изменения или удаления созданной линии.

Стало

Поле data.id содержит номер созданной линии. Это значение подходит для последующих запросов изменения и удаления.

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

Дополнительных действий не требуется. Новые ответы создания сразу содержат адресуемый ключ.

NEW-0827-14: списки трудозатрат явно отклоняют неподдерживаемый filter

Было

Неподдерживаемый filter в запросах GET /v1/task-time и GET /v1/tasks/:taskId/time мог вернуть статус 200 и более широкую выборку, чем ожидал клиент.

Стало

Непустой, bracket-, JSON- или повторный filter возвращает 400 UNSUPPORTED_FILTER. Для запросов с именованными параметрами userId, taskId, from и to ответ остаётся HTTP 200, их поведение не меняется.

FIX-0827-15: файл robots.txt PUBLIC-приложения доступен роботам

Было

Точные GET и HEAD на /robots.txt всегда получали локальный запрет шлюза, даже если приложение имело accessPolicy=PUBLIC, работало и само отдавало файл.

Стало

При accessPolicy=PUBLIC и живом туннеле точные GET и HEAD на /robots.txt возвращают ответ приложения: 200 text/plain с полным непустым GET-телом не более 1 MiB (HEAD — без тела) или 304. Для остальных политик, недоступного приложения и любого некорректного ответа шлюз по-прежнему возвращает локальный 200 text/plain с Disallow: /.

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

PUBLIC-приложение теперь может управлять индексацией через свой файл /robots.txt. Для непубличных приложений ничего менять не нужно: запрет остаётся закрытым по умолчанию.

FIX-0827-16: фильтры сущностей больше не теряются при списочных вызовах

Было

list_entities мог передать фильтры как обычные параметры запроса. Из-за этого поле с именем sort конфликтовало с директивой сортировки, а openline-configs мог вернуть полный список вместо отфильтрованного. На envelope-сущностях фильтр также мог потеряться в GET /v1/{entity}/aggregate, POST /v1/batch и POST /v1/{entity}/batch.

Стало

list_entities передаёт поля через filter[...], отдельно от сортировки. Все списочные V1-пути применяют объявленный сущностью envelope, поэтому непустой фильтр доходит до Битрикс24 и несовпадающий фильтр возвращает пустой результат, а не полную коллекцию. Ручной список бронирований принимает ту же bracket-форму для обязательного окна dateFrom/dateTo и сохраняет прежнюю плоскую форму.

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

Менять запросы не нужно. Ранее слишком широкие успешные ответы теперь соответствуют переданному фильтру.

FIX-0827-17: список доступа к приложению содержит только сотрудников портала

Было

GET /v1/infra/servers/{id}/access отдавал в users[] каждую строку аудитории. Поле id элемента объявлено обязательным, но у записи, выданной человеку не из портала сервера, портального номера нет вовсе — такой элемент приезжал бы с пустым id, и клиент, читающий поле как обязательное, ломался бы на нём.

Стало

users[] содержит только записи с портальным номером. Записи, адресованные по сетевому идентификатору, из этого списка исключены — у них другое пространство идентификаторов, и смешивать его с портальным нельзя. На сегодняшних данных ответ не меняется: таких записей ещё не существует.

FIX-0827-18: шаг `connect` в статусе ремонта больше не проваливается на подключившемся агенте

Было

Ремонт сервера засчитывал шаг connect только тогда, когда версия поднявшегося агента совпадала с версией, которую ожидала платформа. Если агент подключался на другой версии, туннель был поднят и blackholeStatus показывал CONNECTED, но GET /v1/infra/servers/{id}/repair-status отдавал status: failed, step: connect и error: "Agent did not connect".

Стало

Шаг connect завершается по факту подключения агента к Gateway — ровно так, как описан порядок шагов в документации операции. Версия установленного агента по-прежнему возвращается в data.agentVersion и на исход ремонта не влияет.