For AI agents: markdown of this page — /docs-content-en/calls/followup.md documentation index — /llms.txt

Call follow-up

⚠️ The methods ship in the call 26.600.0 update and are not yet available on all Bitrix24 accounts. If the update has not reached your Bitrix24 account, the API returns 422 METHOD_NOT_YET_AVAILABLE — this means the method has not been released on the account yet, not an integration error.

Read the AI Follow-up of completed calls: transcription, meeting overview, summary, insights, and efficiency evaluation. The methods only read data and change nothing.

Scope: call | Base URL: https://vibecode.bitrix24.com/v1 | Authorization: X-Api-Key

Follow-up list

⚠️ The method ships in update call 26.600.0 and is not yet available on all Bitrix24 accounts. If the update has not reached your account yet, the API returns 422 METHOD_NOT_YET_AVAILABLE — this means the method has not been released on the account, not that the integration is broken.

POST /v1/calls/followups/list

Returns a list of AI Follow-ups for completed calls within the specified period. Pagination through the results is cursor-based.

Request fields (body)

Field Type Req. Description
filter object yes Filter conditions. Without this object the request is rejected
filter.startDate.from string yes Start of the period, ISO 8601 — 2026-01-01T00:00:00Z
filter.startDate.to string yes End of the period, ISO 8601. A value earlier than from is rejected
filter.participantId integer no Filter by a single participant. Available to the Bitrix24 account administrator only: a regular employee cannot filter by another participant. List of employees — GET /v1/users
select string[] no Which fields to return. Allowed values — in the "Select field" section
order object no Sorting by start date: { "startDate": "asc" } or { "startDate": "desc" }. Defaults to desc
pagination object no Page size and cursor. Rules — in the "Navigation" section
pagination.limit integer no Records per page. Defaults to 50, maximum 200. Selecting data-heavy fields lowers the maximum to 20
pagination.afterCursor object no Cursor of the next page. Copied as a whole from data.afterCursor of the previous response. Not passed in the first request
mentionFormat string no Format of @-mentions in text fields: bb, html or none. Defaults to bb

Select field

Without select only call metadata is returned. The remaining fields are requested explicitly. An unknown value is rejected with 422 BITRIX_ERROR and a message that names the rejected field.

Metadata

Value What is returned
callId, callType, initiatorId, startDate, endDate, durationSeconds Base fields. Always returned in the list
uuid Call session identifier
participants List of participants
tracks Call recordings with download links
outcomes List of the AI blocks that are ready
language Transcription language
version Version of the AI data schema
createdAt Time of the last AI record

AI blocks

A block is requested either as a whole or as an individual subfield using dot notation.

Block Subfields
transcription transcription.language, transcription.segments
overview overview.topic, overview.detailedTakeaways, overview.meetingType, overview.agenda, overview.agreements, overview.actionItems, overview.meetings
summary Requested only as a whole
insights insights.speakerEvaluationAvailable, insights.speakerAnalysis, insights.meetingStrengths, insights.meetingWeaknesses, insights.speechStyleInfluence, insights.engagementLevel, insights.areasOfResponsibility, insights.finalRecommendations
evaluation evaluation.efficiencyValue, evaluation.calendar, evaluation.criteria

Selection rules:

  • Requesting a whole block (["overview"]) returns all of its subfields.
  • Requesting a subfield (["overview.topic"]) returns only that subfield — the rest are omitted.
  • transcription, transcription.segments, overview and insights contain a lot of data. Selecting them lowers the maximum page size to 20 records.
  1. The first request is sent without pagination.afterCursor.
  2. If hasMore in the response is true, copy the whole data.afterCursor object into pagination.afterCursor of the next request.
  3. Repeat until hasMore becomes false.

pagination.limit — defaults to 50, maximum 200. Selecting data-heavy fields lowers the maximum to 20.

jsonc
{ "pagination": { "limit": 50, "afterCursor": { "startDate": "2026-01-12T14:30:00.000000+00:00", "id": 12330 } } }

Mention format

mentionFormat controls how @-mentions of employees look in all AI text fields — transcription.segments[].text, overview.*, insights.*, evaluation.criteria.*.thoughts.

Value Text in the response When to choose
bb [USER=7]John Smith[/USER] Rendering in an interface that supports BB code
html <span class="bx-call-mention" …>John Smith</span> Rendering on the web
none John Smith Passing the text to an AI model, search, export

Examples

A review of one employee's meetings for January: we take the call metadata, the topic, the agreements and the action items from the overview, plus the participant analysis and the overall score. Results are sorted newest first, and mentions arrive as plain text. This is the first request, so it has no afterCursor — the cursor for the next page arrives in the response.

curl — personal key

Terminal
curl -X POST https://vibecode.bitrix24.com/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 application

Terminal
curl -X POST https://vibecode.bitrix24.com/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 — personal key

javascript
const res = await fetch('https://vibecode.bitrix24.com/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) {
  // Handle the error explicitly: otherwise on 403 or 422 the code fails when accessing data
  throw new Error(`${body.error.code}: ${body.error.message}`)
}

const { data } = body

for (const call of data.items) {
  // AI blocks are not ready for every call: some of them arrive as null
  const topic = call.overview?.topic ?? 'topic not determined'
  const score = call.evaluation?.efficiencyValue ?? '—'
  console.log(call.startDate, topic, `score: ${score}`)

  for (const item of call.overview?.actionItems ?? []) {
    console.log('  action item:', item.actionItem)
  }
}

// Next page: put the cursor from the response into pagination.afterCursor of the new request
console.log(data.hasMore, data.afterCursor)

JavaScript — OAuth application

javascript
const res = await fetch('https://vibecode.bitrix24.com/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) {
  // Handle the error explicitly: otherwise on 403 or 422 the code fails when accessing data
  throw new Error(`${body.error.code}: ${body.error.message}`)
}

const { data } = body
console.log(data.items, data.hasMore, data.afterCursor)

Response fields

Field Type Description
success boolean Always true on success
data.items object[] Array of Follow-ups. Element fields — in the table below
data.hasMore boolean Whether there are records beyond the current page
data.afterCursor object | null Cursor of the next page. null — there are no more records

Fields of an array element:

Field Type Description
items[].callId number Call identifier. Passed to GET /v1/calls/followups/:callId
items[].callType number Call type: 1 — instant, 2 — conference, 3 — big room
items[].initiatorId number Call initiator. Employee profile — GET /v1/users/:id
items[].startDate string Call start, ISO 8601 in UTC
items[].endDate string | null Call end, ISO 8601 in UTC
items[].durationSeconds number Call duration in seconds
items[].uuid string Call session identifier
items[].language string Transcription language code
items[].version number Version of the AI data schema
items[].participants object[] Call participants
items[].outcomes string[] AI blocks already generated for this call
items[].createdAt string Time of the last AI record
items[].tracks object[] Call recordings
items[].transcription object Transcription of the conversation
items[].overview object Meeting overview
items[].summary object Fragment-by-fragment summary
items[].evaluation object Meeting efficiency score
items[].insights object Insights and participant analysis

Participants — `participants[]`

Field Type Description
userId number Employee identifier
name string Employee name
avatar string Link to the avatar
workPosition string Job title
talkedSeconds number How many seconds the participant spoke

Call recordings — `tracks[]`

Field Type Description
trackId number Recording identifier
type string Track type, for example mixed_audio
duration number Recording duration in seconds
fileName string File name
mimeType string MIME type of the file
url string Download link
dateCreate string When the recording was created, ISO 8601

Transcription — `transcription`

Field Type Description
language string Transcript language code
segments[] object[] Utterances in chronological order
segments[].userId number Who is speaking
segments[].userName string Speaker name
segments[].start number Start of the utterance, seconds from the start of the call
segments[].end number End of the utterance, seconds from the start of the call
segments[].text string Text of the utterance

Meeting overview — `overview`

Field Type Description
topic string Meeting topic
detailedTakeaways string Detailed takeaways
meetingType object Meeting type: typeTag — code, title — name, explanation — justification
agenda object Agenda: explanation — wording, quote — quote from the conversation
agreements[] object[] Agreements: agreement — wording, quote — quote
actionItems[] object[] Action items: actionItem — wording, quote — quote
meetings[] object[] Scheduled meetings: meeting — wording, quote — quote

Summary — `summary`

Field Type Description
segments[] object[] Fragments of the conversation
segments[].start number Start of the fragment, seconds
segments[].end number End of the fragment, seconds
segments[].title string Fragment title
segments[].summary string Summary of the fragment

Insights — `insights`

Field Type Description
speakerEvaluationAvailable boolean Whether participant analysis is available on the Bitrix24 account
speakerAnalysis[] object[] Participant analysis, in descending order of talkPercentage
speakerAnalysis[].userId number Employee identifier. Profile — GET /v1/users/:id
speakerAnalysis[].detailedInsight string Conclusion about the participant
speakerAnalysis[].efficiencyValue number Participant efficiency score, from 0 to 100
speakerAnalysis[].evaluationCriteria string The criterion the score was based on
speakerAnalysis[].talkPercentage number Share of the time the participant spoke, in percent
speakerAnalysis[].duration number How many seconds the participant spoke
speakerAnalysis[].durationFormat string The same time in MM:SS format
meetingStrengths[] object[] Strengths: strengthTitle and strengthExplanation
meetingWeaknesses[] object[] Weaknesses: weaknessTitle and weaknessExplanation
speechStyleInfluence string How the speaking style influenced the meeting
engagementLevel string Engagement of the participants
areasOfResponsibility string Who is responsible for what after the meeting
finalRecommendations string Recommendations for the next meeting

Efficiency score — `evaluation`

Field Type Description
efficiencyValue number Overall meeting efficiency, from 0 to 100
calendar.overhead boolean Whether the meeting ran longer than necessary
criteria object Map of criteria. The key is the criterion code, the value is an object with the fields below
criteria.<code>.value boolean Whether the criterion is met
criteria.<code>.title string Criterion name
criteria.<code>.criteria string Criterion wording
criteria.<code>.thoughts string Justification of the score

Response example

The response to the request from the examples above. Base call fields always arrive, and the AI blocks contain exactly what is listed in select: inside overview — only the topic, the agreements and the action items, inside insights — only the participant analysis, inside evaluation — only the overall score. Employee mentions arrive as plain text, because mentionFormat: "none" was requested.

JSON
{
  "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": "John Smith", "avatar": "https://example.bitrix24.com/upload/avatar.png", "workPosition": "Project manager", "talkedSeconds": 600 },
          { "userId": 42, "name": "Mary Jones", "avatar": "https://example.bitrix24.com/upload/avatar-2.png", "workPosition": "Developer", "talkedSeconds": 1200 }
        ],
        "outcomes": ["transcription", "overview", "summary", "insights", "evaluation"],
        "overview": {
          "topic": "Sprint planning",
          "agreements": [
            { "agreement": "Only the catalog import goes into the sprint", "quote": "I suggest we keep only the catalog import, we will not finish the rest." }
          ],
          "actionItems": [
            { "actionItem": "Prepare the prototype by Friday", "quote": "Then we show the prototype on Friday." }
          ]
        },
        "insights": {
          "speakerAnalysis": [
            { "userId": 42, "detailedInsight": "The participant proposed cutting the scope and backed it with a deadline estimate.", "efficiencyValue": 82, "evaluationCriteria": "Constructiveness of proposals", "talkPercentage": 66, "duration": 1200, "durationFormat": "20:00" },
            { "userId": 7, "detailedInsight": "The participant ran the meeting and recorded the agreements.", "efficiencyValue": 74, "evaluationCriteria": "Discussion management", "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": "Mary Jones", "avatar": "https://example.bitrix24.com/upload/avatar-2.png", "workPosition": "Developer", "talkedSeconds": 900 }
        ],
        "outcomes": ["transcription", "overview"],
        "overview": {
          "topic": "Review of the week's support requests",
          "agreements": [],
          "actionItems": [
            { "actionItem": "Collect frequent questions into the knowledge base", "quote": "Let's collect the recurring questions into one article." }
          ]
        },
        "insights": null,
        "evaluation": null
      }
    ],
    "hasMore": true,
    "afterCursor": { "startDate": "2026-01-12T09:00:00.000000+00:00", "id": 12318 }
  }
}

The second call shows a common case: not all of its AI blocks are ready. outcomes lists what has been generated, and blocks that were requested but are absent arrive as null — check them before accessing their fields.

See the Follow-up for a single call page for a call with all of its blocks filled in.

Error response example

400 — the request body has no filter object:

JSON
{
  "success": false,
  "error": {
    "code": "MISSING_PARAMS",
    "message": "Required: filter.startDate.from/to (ISO 8601)"
  }
}

Errors

HTTP Code Description
400 MISSING_PARAMS The request body has no filter object
400 INVALID_PARAMS The value of a request field is not in the list of allowed values — mentionFormat, for example. If Bitrix24 rejected the value of a specific field, the response additionally contains an error.validation array with the field name
401 MISSING_API_KEY The X-Api-Key header was not passed
401 TOKEN_MISSING The key has no portal tokens. An OAuth application key requires the Authorization: Bearer header
403 SCOPE_DENIED The key has no call scope
403 BITRIX_ACCESS_DENIED Bitrix24 denied access: the key's webhook has no call permission on the portal side. Reconnect the key with the required permission
422 METHOD_NOT_YET_AVAILABLE Update call 26.600.0 has not been released on the portal yet. The response contains an error.release field with the target version
422 BITRIX_ERROR The request was rejected: incorrect date range, disallowed field in select, incorrect pagination or order, no access to the data. The reason is in error.message
429 RATE_LIMITED Request rate exceeded on the Bitrix24 side
429 QUEUE_OVERFLOW, QUEUE_TIMEOUT The portal request queue is full or the request did not get through the queue in time. The Retry-After header suggests the delay before a retry
503 BITRIX_TIMEOUT Bitrix24 accepted the request but did not respond within 15 seconds. For reads a retry is safe
502 BITRIX_UNAVAILABLE Bitrix24 is unavailable

The full list of common API errors — Errors.

Known specifics

Calls without AI processing do not appear in the list. The output contains only the calls for which a Follow-up has already been generated. An empty items array means there are no such calls for the period.

An incomplete period is rejected with code 422, not 400. The code 400 MISSING_PARAMS is returned only when there is no filter object in the request body at all. A missing to, or a period where from is later than to, returns 422 BITRIX_ERROR with a description of the reason.

Participant analysis is not available on every Bitrix24 account. When it is unavailable, the insights block comes back with speakerEvaluationAvailable: false and an empty participant analysis. This is not a request error — the response structure does not change.

The output is limited by the employee's permissions. The key returns Follow-ups of the calls in which the key owner took part, or whose linked chat the key owner belongs to. The Bitrix24 account administrator sees all calls of the account. That is why the same period gives different lists for different employees.

See also