For AI agents: markdown of this page — /docs-content-en/calls/followup/get.md documentation index — /llms.txt
Follow-up for a single call
GET /v1/calls/followups/:callId
Returns the AI Follow-up of a single completed call.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
ParametercallId (path) |
Typeinteger | Requiredyes | DescriptionCall identifier. A positive integer. Where to get it — POST /v1/calls/followups/list |
Parameterselect (query) |
Typestring[] | Requiredno | DescriptionWhich fields to return. Pass it as a repeated parameter or as a comma-separated list. The set of values is the same as in the list method — see the "Select field" section of Follow-up list |
ParametermentionFormat (query) |
Typestring | Requiredno | DescriptionFormat of @-mentions in text fields: bb, html or none. Defaults to bb |
Select field
select value |
What comes back |
|---|---|
| select valueNot passed | What comes backThe full Follow-up object. All fields are present — missing data arrives as null |
| select valueEmpty array | What comes backBase metadata only: callId, callType, initiatorId, startDate, endDate, durationSeconds |
| select valueList of fields | What comes backOnly the listed fields and always callId. A requested but unfilled field arrives as null |
Examples
A request without select returns the whole Follow-up. mentionFormat: none strips the mention markup, so the text is ready to pass to an AI model or to store in a task. To fetch only some of the blocks, add select — for example ?select=overview.actionItems&select=evaluation.efficiencyValue.
curl — personal key
curl "https://vibecode.bitrix24.com/v1/calls/followups/12345?mentionFormat=none" \
-H "X-Api-Key: YOUR_API_KEY"
curl — OAuth application
curl "https://vibecode.bitrix24.com/v1/calls/followups/12345?mentionFormat=none" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN"
JavaScript — personal key
const params = new URLSearchParams({ mentionFormat: 'none' })
const res = await fetch(`https://vibecode.bitrix24.com/v1/calls/followups/12345?${params}`, {
headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})
const body = await res.json()
if (!body.success) {
// Handle the error explicitly: otherwise on 403 or 422 the code breaks when reading data
throw new Error(`${body.error.code}: ${body.error.message}`)
}
const { data } = body
const call = data.item
// Ready AI blocks are listed in outcomes — the ones that are not ready arrive as null
console.log(call.outcomes, `${call.durationSeconds} sec`)
console.log(call.overview?.topic ?? 'overview is not built yet')
for (const item of call.overview?.actionItems ?? []) {
console.log('action item:', item.actionItem, '— quote:', item.quote)
}
// speakerAnalysis is absent if speaker analysis is unavailable on the Bitrix24 account
for (const speaker of call.insights?.speakerAnalysis ?? []) {
console.log(`speaker ${speaker.userId}: ${speaker.talkPercentage}% of the time, score ${speaker.efficiencyValue}`)
}
// Criteria are a map — the keys depend on the meeting type, so iterate over the keys
for (const [code, criterion] of Object.entries(call.evaluation?.criteria ?? {})) {
console.log(code, criterion.value ? 'met' : 'not met', '—', criterion.thoughts)
}
JavaScript — OAuth application
const params = new URLSearchParams({ mentionFormat: 'none' })
const res = await fetch(`https://vibecode.bitrix24.com/v1/calls/followups/12345?${params}`, {
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
})
const body = await res.json()
if (!body.success) {
// Handle the error explicitly: otherwise on 403 or 422 the code breaks when reading data
throw new Error(`${body.error.code}: ${body.error.message}`)
}
const { data } = body
console.log(data.item)
Response fields
| Field | Type | Description |
|---|---|---|
Fieldsuccess |
Typeboolean | DescriptionAlways true on success |
Fielddata.item |
Typeobject | DescriptionCall Follow-up. Its fields are in the table below |
Fields of the item object:
| Field | Type | Description |
|---|---|---|
Fielditem.callId |
Typenumber | DescriptionCall identifier |
Fielditem.callType |
Typenumber | DescriptionCall type: 1 — instant, 2 — conference, 3 — large room |
Fielditem.initiatorId |
Typenumber | DescriptionCall initiator. Employee profile — GET /v1/users/:id |
Fielditem.startDate |
Typestring | DescriptionCall start, ISO 8601 in UTC |
Fielditem.endDate |
Typestring | null | DescriptionCall end, ISO 8601 in UTC |
Fielditem.durationSeconds |
Typenumber | DescriptionCall duration in seconds |
Fielditem.uuid |
Typestring | DescriptionCall session identifier |
Fielditem.language |
Typestring | DescriptionTranscription language code |
Fielditem.version |
Typenumber | DescriptionAI data schema version |
Fielditem.participants |
Typeobject[] | DescriptionCall participants |
Fielditem.outcomes |
Typestring[] | DescriptionReady AI blocks of this call |
Fielditem.createdAt |
Typestring | DescriptionTime of the last AI record |
Fielditem.tracks |
Typeobject[] | DescriptionCall recordings |
Fielditem.transcription |
Typeobject | null | DescriptionConversation transcript |
Fielditem.overview |
Typeobject | null | DescriptionMeeting overview |
Fielditem.summary |
Typeobject | null | DescriptionSummary by segments |
Fielditem.evaluation |
Typeobject | null | DescriptionMeeting efficiency score |
Fielditem.insights |
Typeobject | null | DescriptionInsights and speaker analysis |
Participants — `participants[]`
| Field | Type | Description |
|---|---|---|
FielduserId |
Typenumber | DescriptionEmployee identifier |
Fieldname |
Typestring | DescriptionEmployee name |
Fieldavatar |
Typestring | DescriptionAvatar link |
FieldworkPosition |
Typestring | DescriptionJob position |
FieldtalkedSeconds |
Typenumber | DescriptionHow many seconds the participant spoke. This field does not need the participant analysis from insights; inside that analysis the participant's time arrives in insights.speakerAnalysis[].duration |
Call recordings — `tracks[]`
| Field | Type | Description |
|---|---|---|
FieldtrackId |
Typenumber | DescriptionRecording identifier |
Fieldtype |
Typestring | DescriptionTrack type, for example mixed_audio |
Fieldduration |
Typenumber | DescriptionRecording duration in seconds |
FieldfileName |
Typestring | DescriptionFile name |
FieldmimeType |
Typestring | DescriptionFile MIME type |
Fieldurl |
Typestring | DescriptionDownload link |
FielddateCreate |
Typestring | DescriptionWhen the recording was created, ISO 8601 |
Transcription — `transcription`
| Field | Type | Description |
|---|---|---|
Fieldlanguage |
Typestring | DescriptionTranscript language code |
Fieldsegments[] |
Typeobject[] | DescriptionUtterances in chronological order |
Fieldsegments[].userId |
Typenumber | DescriptionWho speaks |
Fieldsegments[].userName |
Typestring | DescriptionSpeaker name |
Fieldsegments[].start |
Typenumber | DescriptionUtterance start, seconds from the call start |
Fieldsegments[].end |
Typenumber | DescriptionUtterance end, seconds from the call start |
Fieldsegments[].text |
Typestring | DescriptionUtterance text |
Meeting overview — `overview`
| Field | Type | Description |
|---|---|---|
Fieldtopic |
Typestring | DescriptionMeeting topic |
FielddetailedTakeaways |
Typestring | DescriptionDetailed takeaways |
FieldmeetingType |
Typeobject | DescriptionMeeting type: typeTag — code, title — name, explanation — rationale |
Fieldagenda |
Typeobject | DescriptionAgenda: explanation — wording, quote — quote from the conversation |
Fieldagreements[] |
Typeobject[] | DescriptionAgreements: agreement — wording, quote — quote |
FieldactionItems[] |
Typeobject[] | DescriptionAction items: actionItem — wording, quote — quote |
Fieldmeetings[] |
Typeobject[] | DescriptionScheduled meetings: meeting — wording, quote — quote |
Summary — `summary`
| Field | Type | Description |
|---|---|---|
Fieldsegments[] |
Typeobject[] | DescriptionConversation segments |
Fieldsegments[].start |
Typenumber | DescriptionSegment start, seconds |
Fieldsegments[].end |
Typenumber | DescriptionSegment end, seconds |
Fieldsegments[].title |
Typestring | DescriptionSegment title |
Fieldsegments[].summary |
Typestring | DescriptionSegment summary |
Insights — `insights`
| Field | Type | Description |
|---|---|---|
FieldspeakerEvaluationAvailable |
Typeboolean | DescriptionWhether speaker analysis is available on the Bitrix24 account |
FieldspeakerAnalysis[] |
Typeobject[] | DescriptionSpeaker analysis, in descending order of talkPercentage |
FieldspeakerAnalysis[].userId |
Typenumber | DescriptionEmployee identifier. Profile — GET /v1/users/:id |
FieldspeakerAnalysis[].detailedInsight |
Typestring | DescriptionConclusion about the participant |
FieldspeakerAnalysis[].efficiencyValue |
Typenumber | DescriptionParticipant efficiency score, from 0 to 100 |
FieldspeakerAnalysis[].evaluationCriteria |
Typestring | DescriptionThe criterion the score is based on |
FieldspeakerAnalysis[].talkPercentage |
Typenumber | DescriptionShare of time the participant spoke, in percent |
FieldspeakerAnalysis[].duration |
Typenumber | DescriptionHow many seconds the participant spoke, as part of the participant analysis. Outside the insights block the participant's time arrives in the participants[].talkedSeconds field |
FieldspeakerAnalysis[].durationFormat |
Typestring | DescriptionThe same duration in MM:SS format |
FieldmeetingStrengths[] |
Typeobject[] | DescriptionStrengths: strengthTitle and strengthExplanation |
FieldmeetingWeaknesses[] |
Typeobject[] | DescriptionWeaknesses: weaknessTitle and weaknessExplanation |
FieldspeechStyleInfluence |
Typestring | DescriptionHow the speech style affected the meeting |
FieldengagementLevel |
Typestring | DescriptionParticipant engagement |
FieldareasOfResponsibility |
Typestring | DescriptionWho is responsible for what based on the meeting outcomes |
FieldfinalRecommendations |
Typestring | DescriptionRecommendations for the next meeting |
Efficiency score — `evaluation`
| Field | Type | Description |
|---|---|---|
FieldefficiencyValue |
Typenumber | DescriptionOverall meeting efficiency, from 0 to 100 |
Fieldcalendar.overhead |
Typeboolean | DescriptionWhether the meeting took more time than needed |
Fieldcriteria |
Typeobject | DescriptionMap of criteria. The key is the criterion code, the value is an object with the fields below |
Fieldcriteria.<code>.value |
Typeboolean | DescriptionWhether the criterion is met |
Fieldcriteria.<code>.title |
Typestring | DescriptionCriterion name |
Fieldcriteria.<code>.criteria |
Typestring | DescriptionCriterion wording |
Fieldcriteria.<code>.thoughts |
Typestring | DescriptionRationale for the score |
Response example
{
"success": true,
"data": {
"item": {
"callId": 12345,
"callType": 1,
"initiatorId": 7,
"startDate": "2026-01-15T10:00:00+00:00",
"endDate": "2026-01-15T10:42:00+00:00",
"durationSeconds": 2520,
"uuid": "bb085e5d-5160-4a63-9ac4-152248046c39",
"language": "en",
"version": 3,
"participants": [
{ "userId": 7, "name": "John Smith", "workPosition": "Project manager", "talkedSeconds": 600 }
],
"outcomes": ["transcription", "overview", "summary", "insights", "evaluation"],
"createdAt": "2026-01-15T11:05:00+00:00",
"tracks": [
{ "trackId": 100, "type": "mixed_audio", "duration": 2520, "fileName": "call_12345.wav", "mimeType": "audio/wav", "url": "https://example.bitrix24.com/disk/call_12345.wav", "dateCreate": "2026-01-15T11:00:00+00:00" }
],
"transcription": {
"language": "en",
"segments": [
{ "userId": 7, "userName": "John Smith", "start": 12, "end": 25, "text": "Let's lock in the sprint scope. What are we taking on?" },
{ "userId": 42, "userName": "Mary Jones", "start": 26, "end": 48, "text": "I suggest we keep only the catalog import, we won't have time for the rest." },
{ "userId": 7, "userName": "John Smith", "start": 49, "end": 70, "text": "Agreed. Then we show the prototype on Friday." }
]
},
"overview": {
"topic": "Sprint planning",
"detailedTakeaways": "The team reduced the sprint scope to the catalog import and agreed to show the prototype on Friday.",
"meetingType": {
"typeTag": "planning",
"title": "Planning",
"explanation": "The participants assigned tasks and set deadlines for the next iteration."
},
"agenda": {
"explanation": "Define the sprint scope and the demo deadline.",
"quote": "Let's lock in the sprint scope."
},
"agreements": [
{ "agreement": "Only the catalog import goes into the sprint", "quote": "I suggest we keep only the catalog import, we won't have time for the rest." }
],
"actionItems": [
{ "actionItem": "Prepare the prototype by Friday", "quote": "Then we show the prototype on Friday." }
],
"meetings": [
{ "meeting": "Prototype demo on Friday", "quote": "Then we show the prototype on Friday." }
]
},
"summary": {
"segments": [
{ "start": 0, "end": 600, "title": "Sprint scope", "summary": "Discussed what the team can deliver and reduced the task set to the catalog import." },
{ "start": 601, "end": 2520, "title": "Deadlines and demo", "summary": "Agreed to show the prototype on Friday and to return to the other tasks in the next sprint." }
]
},
"insights": {
"speakerEvaluationAvailable": true,
"speakerAnalysis": [
{
"userId": 42,
"detailedInsight": "The participant proposed reducing 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"
}
],
"meetingStrengths": [
{ "strengthTitle": "Clear outcome", "strengthExplanation": "The meeting ended with a recorded decision and a deadline." }
],
"meetingWeaknesses": [
{ "weaknessTitle": "Unequal participation", "weaknessExplanation": "One participant spoke for two thirds of the time." }
],
"speechStyleInfluence": "The calm pace of speech helped reach a decision quickly.",
"engagementLevel": "High engagement of both participants.",
"areasOfResponsibility": "The catalog import is assigned to Mary Jones.",
"finalRecommendations": "Send the agenda in advance to shorten the scope discussion."
},
"evaluation": {
"efficiencyValue": 75,
"calendar": { "overhead": false },
"criteria": {
"agenda_defined": {
"value": true,
"criteria": "The agenda is stated at the start of the meeting",
"title": "Agenda",
"thoughts": "The host stated the goal in the first utterance."
},
"decisions_made": {
"value": true,
"criteria": "Decisions are made on the issues discussed",
"title": "Decisions",
"thoughts": "The sprint scope and the demo deadline are recorded."
},
"all_participants_involved": {
"value": false,
"criteria": "All participants are involved in the discussion",
"title": "Engagement",
"thoughts": "The split of utterances is 66 to 34 percent."
}
}
}
}
}
}
The keys in evaluation.criteria are criterion codes. Their set depends on the meeting type, so iterate over the map by keys instead of a fixed list.
Error response example
422 — the call is not found or its Follow-up is unavailable:
{
"success": false,
"error": {
"code": "BITRIX_ERROR",
"message": "No access to the Follow-up data"
}
}
The error.message text comes from Bitrix24, so its wording and language depend on the Bitrix24 account language. Branch on error.code, not on the message text.
Errors
| HTTP | Code | Description |
|---|---|---|
| HTTP400 | CodeINVALID_PARAMS |
DescriptioncallId in the path is not a positive integer. Checked before the request to Bitrix24 |
| HTTP400 | CodeINVALID_PARAMS |
DescriptionA query parameter value is outside the allowed list — for example mentionFormat. If Bitrix24 rejected the value on a specific field, the response also contains an error.validation array with the field name |
| HTTP401 | CodeMISSING_API_KEY |
DescriptionThe X-Api-Key header is missing |
| HTTP401 | CodeTOKEN_MISSING |
DescriptionThe key has no portal tokens. An OAuth application key requires the Authorization: Bearer header |
| HTTP403 | CodeSCOPE_DENIED |
DescriptionThe key has no call scope |
| HTTP403 | CodeBITRIX_ACCESS_DENIED |
DescriptionBitrix24 denied access. A common cause is that the set of scopes the key uses to reach the portal does not include call. The full list of causes and what to do per key type — Errors |
| HTTP422 | CodeBITRIX_ERROR |
DescriptionInvalid field in select — error.b24Code is invalid_select_field. The call access check can fail before select is validated |
| HTTP422 | CodeBITRIX_ERROR |
DescriptionThe request was rejected by Bitrix24. There is no call with this callId, or its Follow-up is not accessible — the message is "No access to the Follow-up data". The reason for the specific denial is in error.message |
| HTTP429 | CodeRATE_LIMITED |
DescriptionRequest rate exceeded on the Bitrix24 side |
| HTTP429 | CodeQUEUE_OVERFLOW, QUEUE_TIMEOUT |
DescriptionThe 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 |
| HTTP503 | CodeBITRIX_TIMEOUT |
DescriptionBitrix24 accepted the request but did not respond within 60 seconds. For reads a retry is safe |
| HTTP502 | CodeBITRIX_UNAVAILABLE |
DescriptionBitrix24 is unavailable |
The full list of common API errors — Errors.
Known specifics
The response does not distinguish a non-existent call from an access denial. Both cases come back with the same response. Follow-up list does not answer this either: it contains only calls with a ready Follow-up and only those the employee has access to — a call missing from the list does not mean the call does not exist.
Calls without AI processing. If a call is finished but no Follow-up has been built for it, the method returns an object with metadata: the AI blocks arrive as null and outcomes as an empty array.
Speaker analysis is not available on every Bitrix24 account. If it is unavailable on the account, the insights block arrives with speakerEvaluationAvailable: false and an empty speaker analysis. This is not a request error — the response structure does not change.
Access is limited by employee permissions. The Follow-up is available to whoever took part in the call or is a member of the linked chat — including someone added to the chat after the conversation. The Bitrix24 account administrator sees the Follow-up of any call on the account.