Для AI-агентов: markdown этой страницы — /docs-content/calls/followup.md индекс документации — /llms.txt
Follow-up звонков
Методы выходят в обновлении
call 26.600.0и доступны пока не на всех порталах Битрикс24. Если обновление на ваш портал ещё не пришло, API вернёт422 METHOD_NOT_YET_AVAILABLE— это признак того, что метод на портале ещё не выпущен, а не ошибка интеграции.
Чтение AI Follow-up завершённых звонков: транскрипция, обзор встречи, краткое изложение, аналитические выводы и оценка эффективности. Методы только читают данные и ничего не изменяют.
Скоуп: call | Базовый URL: https://vibecode.bitrix24.tech/v1 | Авторизация: X-Api-Key
Список Follow-up
Метод выходит в обновлении
call 26.600.0и доступен пока не на всех порталах Битрикс24. Если обновление на ваш портал ещё не пришло, API вернёт422 METHOD_NOT_YET_AVAILABLE— это признак того, что метод на портале ещё не выпущен, а не ошибка интеграции.
POST /v1/calls/followups/list
Возвращает список AI Follow-up завершённых звонков за указанный период. Навигация по выдаче — курсорная.
Поля запроса (body)
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
filter |
object | да | Условия выборки. Без этого объекта запрос отклоняется |
filter.startDate.from |
string | да | Начало периода, ISO 8601 — 2026-01-01T00:00:00Z |
filter.startDate.to |
string | да | Конец периода, ISO 8601. Значение раньше from отклоняется |
filter.participantId |
integer | нет | Выборка по одному участнику. Только для администратора портала: рядовому сотруднику фильтр по другому участнику недоступен. Список сотрудников — GET /v1/users |
select |
string[] | нет | Какие поля вернуть. Словарь значений — в разделе «Поле select» |
order |
object | нет | Сортировка по дате начала: { "startDate": "asc" } или { "startDate": "desc" }. По умолчанию — desc |
pagination |
object | нет | Размер страницы и курсор. Правила — в разделе «Навигация» |
pagination.limit |
integer | нет | Записей на страницу. По умолчанию 50, максимум 200. При выборе полей с большим объёмом данных максимум снижается до 20 |
pagination.afterCursor |
object | нет | Курсор следующей страницы. Копируется целиком из data.afterCursor предыдущего ответа. В первом запросе не передаётся |
mentionFormat |
string | нет | Формат @-упоминаний в текстовых полях: bb, html или none. По умолчанию — bb |
Поле select
Без select возвращаются только метаданные звонка. Остальные поля запрашиваются явно. Неизвестное значение отклоняется с 422 BITRIX_ERROR и сообщением, которое называет отклонённое поле.
Метаданные
| Значение | Что вернётся |
|---|---|
callId, callType, initiatorId, startDate, endDate, durationSeconds |
Базовые поля. В списке возвращаются всегда |
uuid |
Идентификатор сессии звонка |
participants |
Список участников |
tracks |
Записи звонка со ссылками на скачивание |
outcomes |
Перечень готовых AI-блоков |
language |
Язык транскрипции |
version |
Версия схемы AI-данных |
createdAt |
Время последней AI-записи |
AI-блоки
Блок запрашивается целиком или отдельным подполем через точку.
| Блок | Подполя |
|---|---|
transcription |
transcription.language, transcription.segments |
overview |
overview.topic, overview.detailedTakeaways, overview.meetingType, overview.agenda, overview.agreements, overview.actionItems, overview.meetings |
summary |
Запрашивается только целиком |
insights |
insights.speakerEvaluationAvailable, insights.speakerAnalysis, insights.meetingStrengths, insights.meetingWeaknesses, insights.speechStyleInfluence, insights.engagementLevel, insights.areasOfResponsibility, insights.finalRecommendations |
evaluation |
evaluation.efficiencyValue, evaluation.calendar, evaluation.criteria |
Правила выбора:
- Запрос блока целиком (
["overview"]) возвращает все его подполя. - Запрос подполя (
["overview.topic"]) возвращает только это подполе, остальные опускаются. transcription,transcription.segments,overviewиinsightsсодержат много данных. Их выбор снижает максимальный размер страницы до 20 записей.
Навигация
- Первый запрос отправляется без
pagination.afterCursor. - Если в ответе
hasMoreравноtrue, скопируйтеdata.afterCursorцеликом вpagination.afterCursorследующего запроса. - Повторяйте, пока
hasMoreне станетfalse.
pagination.limit — по умолчанию 50, максимум 200. При выборе полей с большим объёмом данных максимум снижается до 20.
{ "pagination": { "limit": 50, "afterCursor": { "startDate": "2026-01-12T14:30:00.000000+00:00", "id": 12330 } } }
Формат упоминаний
mentionFormat управляет тем, как выглядят @-упоминания сотрудников во всех текстовых AI-полях — transcription.segments[].text, overview.*, insights.*, evaluation.criteria.*.thoughts.
| Значение | Текст в ответе | Когда выбирать |
|---|---|---|
bb |
[USER=7]Иван Петров[/USER] |
Вывод в интерфейсе, который понимает BB-код |
html |
<span class="bx-call-mention" …>Иван Петров</span> |
Вывод в вебе |
none |
Иван Петров |
Передача текста в нейросеть, поиск, экспорт |
Примеры
Разбор встреч одного сотрудника за январь: берём метаданные звонка, тему, договорённости и задачи из обзора, разбор участников и общую оценку. Сортировка — от новых к старым, упоминания приходят чистым текстом. Это первый запрос, поэтому afterCursor в нём нет — курсор для следующей страницы придёт в ответе.
curl — личный ключ
curl -X POST https://vibecode.bitrix24.tech/v1/calls/followups/list \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"filter": {
"startDate": { "from": "2026-01-01T00:00:00Z", "to": "2026-01-31T23:59:59Z" },
"participantId": 42
},
"select": [
"callId", "startDate", "durationSeconds", "participants", "outcomes",
"overview.topic", "overview.agreements", "overview.actionItems",
"insights.speakerAnalysis", "evaluation.efficiencyValue"
],
"order": { "startDate": "desc" },
"pagination": { "limit": 20 },
"mentionFormat": "none"
}'
curl — OAuth-приложение
curl -X POST https://vibecode.bitrix24.tech/v1/calls/followups/list \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filter": {
"startDate": { "from": "2026-01-01T00:00:00Z", "to": "2026-01-31T23:59:59Z" },
"participantId": 42
},
"select": [
"callId", "startDate", "durationSeconds", "participants", "outcomes",
"overview.topic", "overview.agreements", "overview.actionItems",
"insights.speakerAnalysis", "evaluation.efficiencyValue"
],
"order": { "startDate": "desc" },
"pagination": { "limit": 20 },
"mentionFormat": "none"
}'
JavaScript — личный ключ
const res = await fetch('https://vibecode.bitrix24.tech/v1/calls/followups/list', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
filter: {
startDate: { from: '2026-01-01T00:00:00Z', to: '2026-01-31T23:59:59Z' },
participantId: 42,
},
select: [
'callId', 'startDate', 'durationSeconds', 'participants', 'outcomes',
'overview.topic', 'overview.agreements', 'overview.actionItems',
'insights.speakerAnalysis', 'evaluation.efficiencyValue',
],
order: { startDate: 'desc' },
pagination: { limit: 20 },
mentionFormat: 'none',
}),
})
const body = await res.json()
if (!body.success) {
// Ошибку разбираем явно: иначе на 403 или 422 код упадёт на обращении к data
throw new Error(`${body.error.code}: ${body.error.message}`)
}
const { data } = body
for (const call of data.items) {
// AI-блоки готовы не у каждого звонка: у части из них приходит null
const topic = call.overview?.topic ?? 'тема не определена'
const score = call.evaluation?.efficiencyValue ?? '—'
console.log(call.startDate, topic, `оценка: ${score}`)
for (const item of call.overview?.actionItems ?? []) {
console.log(' задача:', item.actionItem)
}
}
// Следующая страница: курсор из ответа кладём в pagination.afterCursor нового запроса
console.log(data.hasMore, data.afterCursor)
JavaScript — OAuth-приложение
const res = await fetch('https://vibecode.bitrix24.tech/v1/calls/followups/list', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
filter: {
startDate: { from: '2026-01-01T00:00:00Z', to: '2026-01-31T23:59:59Z' },
participantId: 42,
},
select: [
'callId', 'startDate', 'durationSeconds', 'participants', 'outcomes',
'overview.topic', 'overview.agreements', 'overview.actionItems',
'insights.speakerAnalysis', 'evaluation.efficiencyValue',
],
order: { startDate: 'desc' },
pagination: { limit: 20 },
mentionFormat: 'none',
}),
})
const body = await res.json()
if (!body.success) {
// Ошибку разбираем явно: иначе на 403 или 422 код упадёт на обращении к data
throw new Error(`${body.error.code}: ${body.error.message}`)
}
const { data } = body
console.log(data.items, data.hasMore, data.afterCursor)
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
success |
boolean | Всегда true при успехе |
data.items |
object[] | Массив Follow-up. Поля элемента — в таблице ниже |
data.hasMore |
boolean | Есть ли записи за пределами текущей страницы |
data.afterCursor |
object | null | Курсор следующей страницы. null — записей больше нет |
Поля элемента массива:
| Поле | Тип | Описание |
|---|---|---|
items[].callId |
number | Идентификатор звонка. Передаётся в GET /v1/calls/followups/:callId |
items[].callType |
number | Вид звонка: 1 — мгновенный, 2 — конференция, 3 — большая комната |
items[].initiatorId |
number | Инициатор звонка. Карточка сотрудника — GET /v1/users/:id |
items[].startDate |
string | Начало звонка, ISO 8601 в UTC |
items[].endDate |
string | null | Окончание звонка, ISO 8601 в UTC |
items[].durationSeconds |
number | Длительность звонка в секундах |
items[].uuid |
string | Идентификатор сессии звонка |
items[].language |
string | Код языка транскрипции |
items[].version |
number | Версия схемы AI-данных |
items[].participants |
object[] | Участники звонка |
items[].outcomes |
string[] | Готовые AI-блоки этого звонка |
items[].createdAt |
string | Время последней AI-записи |
items[].tracks |
object[] | Записи звонка |
items[].transcription |
object | Транскрипция разговора |
items[].overview |
object | Обзор встречи |
items[].summary |
object | Краткое изложение по фрагментам |
items[].evaluation |
object | Оценка эффективности встречи |
items[].insights |
object | Аналитические выводы и разбор участников |
Участники — `participants[]`
| Поле | Тип | Описание |
|---|---|---|
userId |
number | Идентификатор сотрудника |
name |
string | Имя сотрудника |
avatar |
string | Ссылка на аватар |
workPosition |
string | Должность |
talkedSeconds |
number | Сколько секунд участник говорил |
Записи звонка — `tracks[]`
| Поле | Тип | Описание |
|---|---|---|
trackId |
number | Идентификатор записи |
type |
string | Вид дорожки, например mixed_audio |
duration |
number | Длительность записи в секундах |
fileName |
string | Имя файла |
mimeType |
string | MIME-тип файла |
url |
string | Ссылка на скачивание |
dateCreate |
string | Когда запись создана, ISO 8601 |
Транскрипция — `transcription`
| Поле | Тип | Описание |
|---|---|---|
language |
string | Код языка расшифровки |
segments[] |
object[] | Реплики в хронологическом порядке |
segments[].userId |
number | Кто говорит |
segments[].userName |
string | Имя говорящего |
segments[].start |
number | Начало реплики, секунды от начала звонка |
segments[].end |
number | Конец реплики, секунды от начала звонка |
segments[].text |
string | Текст реплики |
Обзор встречи — `overview`
| Поле | Тип | Описание |
|---|---|---|
topic |
string | Тема встречи |
detailedTakeaways |
string | Развёрнутые выводы |
meetingType |
object | Тип встречи: typeTag — код, title — название, explanation — обоснование |
agenda |
object | Повестка: explanation — формулировка, quote — цитата из разговора |
agreements[] |
object[] | Договорённости: agreement — формулировка, quote — цитата |
actionItems[] |
object[] | Задачи: actionItem — формулировка, quote — цитата |
meetings[] |
object[] | Назначенные встречи: meeting — формулировка, quote — цитата |
Краткое изложение — `summary`
| Поле | Тип | Описание |
|---|---|---|
segments[] |
object[] | Фрагменты разговора |
segments[].start |
number | Начало фрагмента, секунды |
segments[].end |
number | Конец фрагмента, секунды |
segments[].title |
string | Заголовок фрагмента |
segments[].summary |
string | Изложение фрагмента |
Аналитические выводы — `insights`
| Поле | Тип | Описание |
|---|---|---|
speakerEvaluationAvailable |
boolean | Доступен ли разбор участников на портале |
speakerAnalysis[] |
object[] | Разбор участников, по убыванию talkPercentage |
speakerAnalysis[].userId |
number | Идентификатор сотрудника. Карточка — GET /v1/users/:id |
speakerAnalysis[].detailedInsight |
string | Вывод по участнику |
speakerAnalysis[].efficiencyValue |
number | Оценка эффективности участника, от 0 до 100 |
speakerAnalysis[].evaluationCriteria |
string | Критерий, по которому дана оценка |
speakerAnalysis[].talkPercentage |
number | Доля времени, которую участник говорил, в процентах |
speakerAnalysis[].duration |
number | Сколько секунд участник говорил |
speakerAnalysis[].durationFormat |
string | То же время в виде ММ:СС |
meetingStrengths[] |
object[] | Сильные стороны: strengthTitle и strengthExplanation |
meetingWeaknesses[] |
object[] | Слабые стороны: weaknessTitle и weaknessExplanation |
speechStyleInfluence |
string | Как манера речи повлияла на встречу |
engagementLevel |
string | Вовлечённость участников |
areasOfResponsibility |
string | Кто за что отвечает по итогам |
finalRecommendations |
string | Рекомендации к следующей встрече |
Оценка эффективности — `evaluation`
| Поле | Тип | Описание |
|---|---|---|
efficiencyValue |
number | Общая эффективность встречи, от 0 до 100 |
calendar.overhead |
boolean | Была ли встреча избыточной по времени |
criteria |
object | Карта критериев. Ключ — код критерия, значение — объект с полями ниже |
criteria.<код>.value |
boolean | Выполнен ли критерий |
criteria.<код>.title |
string | Название критерия |
criteria.<код>.criteria |
string | Формулировка критерия |
criteria.<код>.thoughts |
string | Обоснование оценки |
Пример ответа
Ответ на запрос из примеров выше. Базовые поля звонка приходят всегда, а из AI-блоков вернулось ровно то, что перечислено в select: внутри overview — только тема, договорённости и задачи, внутри insights — только разбор участников, внутри evaluation — только общая оценка. Упоминания сотрудников идут чистым текстом, потому что запрошен mentionFormat: "none".
{
"success": true,
"data": {
"items": [
{
"callId": 12345,
"callType": 1,
"initiatorId": 7,
"startDate": "2026-01-15T10:00:00+00:00",
"endDate": "2026-01-15T10:42:00+00:00",
"durationSeconds": 2520,
"participants": [
{ "userId": 7, "name": "Иван Петров", "avatar": "https://example.bitrix24.ru/upload/avatar.png", "workPosition": "Руководитель проекта", "talkedSeconds": 600 },
{ "userId": 42, "name": "Мария Иванова", "avatar": "https://example.bitrix24.ru/upload/avatar-2.png", "workPosition": "Разработчик", "talkedSeconds": 1200 }
],
"outcomes": ["transcription", "overview", "summary", "insights", "evaluation"],
"overview": {
"topic": "Планирование спринта",
"agreements": [
{ "agreement": "В спринт берём только импорт каталога", "quote": "Предлагаю оставить только импорт каталога, остальное не успеем." }
],
"actionItems": [
{ "actionItem": "Подготовить прототип к пятнице", "quote": "Тогда прототип показываем в пятницу." }
]
},
"insights": {
"speakerAnalysis": [
{ "userId": 42, "detailedInsight": "Участник предложил сократить объём и обосновал это оценкой сроков.", "efficiencyValue": 82, "evaluationCriteria": "Конструктивность предложений", "talkPercentage": 66, "duration": 1200, "durationFormat": "20:00" },
{ "userId": 7, "detailedInsight": "Участник вёл встречу и зафиксировал договорённости.", "efficiencyValue": 74, "evaluationCriteria": "Управление обсуждением", "talkPercentage": 34, "duration": 600, "durationFormat": "10:00" }
]
},
"evaluation": {
"efficiencyValue": 75
}
},
{
"callId": 12318,
"callType": 2,
"initiatorId": 42,
"startDate": "2026-01-12T09:00:00+00:00",
"endDate": "2026-01-12T09:25:00+00:00",
"durationSeconds": 1500,
"participants": [
{ "userId": 42, "name": "Мария Иванова", "avatar": "https://example.bitrix24.ru/upload/avatar-2.png", "workPosition": "Разработчик", "talkedSeconds": 900 }
],
"outcomes": ["transcription", "overview"],
"overview": {
"topic": "Разбор обращений за неделю",
"agreements": [],
"actionItems": [
{ "actionItem": "Собрать частые вопросы в базу знаний", "quote": "Давай соберём повторяющиеся вопросы в одну статью." }
]
},
"insights": null,
"evaluation": null
}
],
"hasMore": true,
"afterCursor": { "startDate": "2026-01-12T09:00:00.000000+00:00", "id": 12318 }
}
}
Второй звонок показывает частый случай: у него готовы не все AI-блоки. В outcomes перечислено то, что сформировано, а запрошенные, но отсутствующие блоки приходят как null — проверяйте их перед обращением к полям.
Как выглядит звонок со всеми заполненными блоками, показано на странице Follow-up по одному звонку.
Пример ответа при ошибке
400 — в теле запроса нет объекта filter:
{
"success": false,
"error": {
"code": "MISSING_PARAMS",
"message": "Required: filter.startDate.from/to (ISO 8601)"
}
}
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 400 | MISSING_PARAMS |
В теле запроса нет объекта filter |
| 400 | INVALID_PARAMS |
Значение поля запроса вне списка допустимых — например mentionFormat. Если Битрикс24 отклонил значение по полю, ответ дополнительно содержит массив error.validation с именем поля |
| 401 | MISSING_API_KEY |
Не передан заголовок X-Api-Key |
| 401 | TOKEN_MISSING |
У ключа нет токенов портала. Ключ OAuth-приложения требует заголовок Authorization: Bearer |
| 403 | SCOPE_DENIED |
У ключа нет скоупа call |
| 403 | BITRIX_ACCESS_DENIED |
Битрикс24 отказал в доступе. Частый случай — набор скоупов, с которым ключ обращается к порталу, не содержит call. Полный разбор причин и что делать по типу ключа — Ошибки |
| 422 | METHOD_NOT_YET_AVAILABLE |
Обновление call 26.600.0 на портале ещё не выпущено. Ответ содержит поле error.release со значением call 26.600.0 |
| 422 | BITRIX_ERROR |
Запрос отклонён: некорректный диапазон дат, недопустимое поле в select, некорректные pagination или order, нет доступа к данным. Причина — в error.message |
| 429 | RATE_LIMITED |
Превышена частота запросов на стороне Битрикс24 |
| 429 | QUEUE_OVERFLOW, QUEUE_TIMEOUT |
Очередь запросов портала переполнена или запрос не дождался очереди. Заголовок Retry-After подсказывает задержку перед повтором |
| 503 | BITRIX_TIMEOUT |
Битрикс24 принял запрос, но не ответил за 15 секунд. Для чтения повтор безопасен |
| 502 | BITRIX_UNAVAILABLE |
Битрикс24 недоступен |
Полный список общих ошибок API — Ошибки.
Известные особенности
Звонки без AI-обработки в список не попадают. В выдаче только те звонки, по которым Follow-up уже сформирован. Пустой массив items означает, что за период таких звонков нет.
Неполный период отклоняется кодом 422, а не 400. Код 400 MISSING_PARAMS приходит только тогда, когда объекта filter нет в теле запроса вовсе. Пропущенный to или период, где from позже to, возвращают 422 BITRIX_ERROR с описанием причины.
Разбор участников доступен не на каждом портале. Если на портале он недоступен, блок insights приходит с speakerEvaluationAvailable: false и пустым разбором участников. Это не ошибка запроса — структура ответа не меняется.
Выдача ограничена правами сотрудника. Ключ возвращает Follow-up тех звонков, в которых владелец ключа участвовал или состоит в связанном чате. Администратор портала видит все звонки портала. Поэтому один и тот же период у разных сотрудников даёт разные списки.