[{"data":1,"prerenderedAt":7},["ShallowReactive",2],{"docs-calls\u002Fsync-followup":3,"docs-tabs-calls\u002Fsync-followup":6},{"content":4,"lastmod":5},"# Calls meeting follow-ups\n\nRead meeting follow-ups from Calls with the `syncconnector` scope. These read-only methods use Bitrix24 REST 3.0 and require `syncconnector` 26.100.0 and `rest` 26.1300.0 or later. The scope is available without a feature flag. Method availability depends on the Bitrix24 account update.\n\nCowork keys and automatically assembled scope sets do not include `syncconnector`. To read Calls follow-ups, explicitly select this scope for a personal key or an application.\n\n**Base URL:** `https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1` | **Scope:** `syncconnector`\n\n## Operations\n\n| Method | Route | Bitrix24 method |\n|---|---|---|\n| POST | `\u002Fv1\u002Fcalls\u002Fsync-followups\u002Flist` | `syncconnector.followup.list` |\n| GET | `\u002Fv1\u002Fcalls\u002Fsync-followups\u002F:followupId` | `syncconnector.followup.get` |\n\n## Access and identifiers\n\nThe response contains only meetings of the webhook owner or the user whose OAuth token is forwarded. This restriction applies to administrators too. `filter.participantId` cannot expand access: the platform refuses it with `400 INVALID_PARAMS` because Calls only returns the key owner meetings. Optional `filter.chatId` narrows this set.\n\n`followupId` is the number of a follow-up page: take it from the list item `callId`. It is not a call number and cannot be matched to classic follow-up ids from [Call follow-up](\u002Fdocs\u002Fcalls\u002Ffollowup).\n\nAn application using a personal key shows the key owner meetings to **all** its users. A multiuser application needs an OAuth application key and the current user session. This determines which user meetings each request reads.\n\n## List parameters\n\nSend a JSON body to `POST \u002Fv1\u002Fcalls\u002Fsync-followups\u002Flist`.\n\n| Parameter | Type | Required | Meaning |\n|---|---|---|---|\n| `filter` | object | Yes | Meeting filter |\n| `filter.startDate` | object | Yes | Closed date range |\n| `filter.startDate.from` | ISO 8601 string | Yes | Start, including timezone |\n| `filter.startDate.to` | ISO 8601 string | Yes | End, including timezone; no earlier than `from` |\n| `filter.chatId` | positive integer | No | Restrict to a chat |\n| `select` | string array | No | Supported fields below; omitted or `[]` selects base fields |\n| `order.startDate` | `asc` or `desc` | No | The only supported order field |\n| `mentionFormat` | `bb`, `html` or `none` | No | Mention formatting |\n| `pagination.limit` | integer | No | With any AI block or dotted AI field: default 20, max 20; otherwise default 50, max 200; minimum 1 |\n| `pagination.afterCursor` | object | No | Previous response cursor, unchanged |\n\n`page`, `offset`, `start`, unsupported fields, invalid dates and unsupported selection\u002Forder\u002Fformat values return `400 INVALID_PARAMS` before Bitrix24 is called. Request bodies and nested parameter objects accept only the fields listed above.\n\n### Example requests\n\nIllustrative requests, using your own key and date window:\n\n```bash\ncurl -X POST 'https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Fcalls\u002Fsync-followups\u002Flist' \\\n  -H \"X-Api-Key: $VIBE_API_KEY\" -H 'Content-Type: application\u002Fjson' \\\n  -d '{\"filter\":{\"startDate\":{\"from\":\"2026-11-01T00:00:00Z\",\"to\":\"2026-11-10T23:59:59Z\"}},\"select\":[\"callId\",\"chatId\",\"overview\"],\"pagination\":{\"limit\":20}}'\n```\n\nFor an OAuth application key, add `Authorization: Bearer \u003Ccurrent-user-session-token>` alongside `X-Api-Key: \u003Capplication-key>`. Do not substitute a shared personal key.\n\n```javascript\nconst response = await fetch(`${baseUrl}\u002Fv1\u002Fcalls\u002Fsync-followups\u002Flist`, {\n  method: 'POST',\n  headers: { 'X-Api-Key': apiKey, 'Content-Type': 'application\u002Fjson' },\n  body: JSON.stringify({\n    filter: { startDate: { from: '2026-11-01T00:00:00Z', to: '2026-11-10T23:59:59Z' } },\n    select: ['callId', 'chatId', 'overview'], pagination: { limit: 20 },\n  }),\n});\nconst page = (await response.json()).data;\n```\n\n## Get parameters\n\n`GET \u002Fv1\u002Fcalls\u002Fsync-followups\u002F:followupId` accepts a positive integer page number. Internally the same number is sent as `callId`.\n\n| Query parameter | Type | Meaning |\n|---|---|---|\n| `select` | repeated or comma-separated field names | Omit for the full form. `?select=` or `?select=[]` explicitly selects base fields. These are different requests |\n| `mentionFormat` | `bb`, `html` or `none` | Mention formatting |\n\nExample: `GET \u002Fv1\u002Fcalls\u002Fsync-followups\u002F17?select=overview.actionItems&mentionFormat=none`. Obtain `17` from your own list response.\n\n## Supported selection\n\nBlocks and the listed dotted subfields are supported. Any unknown field returns `400 INVALID_PARAMS`.\n\n| Field or block | Supported dotted subfields |\n|---|---|\n| `callId`, `callType`, `initiatorId`, `startDate`, `endDate`, `durationSeconds`, `uuid`, `chatId`, `participants`, `tracks`, `outcomes`, `language`, `version`, `createdAt` | Metadata |\n| `transcription` | `transcription.language`, `transcription.segments` |\n| `overview` | `overview.topic`, `overview.detailedTakeaways`, `overview.meetingType`, `overview.agenda`, `overview.agreements`, `overview.actionItems`, `overview.meetings` |\n| `summary` | Entire block |\n| `insights` | `insights.speakerEvaluationAvailable`, `insights.speakerAnalysis`, `insights.meetingStrengths`, `insights.meetingWeaknesses`, `insights.speechStyleInfluence`, `insights.engagementLevel`, `insights.areasOfResponsibility`, `insights.finalRecommendations` |\n| `evaluation` | `evaluation.efficiencyValue`, `evaluation.calendar`, `evaluation.criteria` |\n\nSelecting **any** of `transcription`, `overview`, `summary`, `insights`, `evaluation` or their supported dotted subfields reduces the list page limit to 20.\n\n## Response fields and pagination\n\nThe list response is `{ success: true, data: { items, hasMore, afterCursor } }`; get returns `{ success: true, data: { item } }`. Items contain metadata and the selected blocks listed above, as supplied by Bitrix24.\n\n| Field | Meaning |\n|---|---|\n| `data.items` | Array of follow-up pages; it can be empty while `hasMore` is true |\n| `data.hasMore` | Whether to continue paging |\n| `data.afterCursor` | Opaque cursor: pass it unchanged in the next request `pagination.afterCursor` |\n| `data.item` | One follow-up page on get |\n| `item.callId` | Follow-up page number to use as `followupId` |\n| AI blocks | May be `null` while analysis is not ready; they can be filled later. Read again when needed |\n| `tracks` | Track links do not guarantee that a recording can be downloaded |\n\nStop only when `hasMore` is false. An empty `items` page with `hasMore: true` is not the end; continue with its `afterCursor`. Do not derive an offset or reinterpret the cursor.\n\n## Errors\n\n| HTTP | Code | Condition |\n|---|---|---|\n| 400 | `INVALID_PARAMS` | Invalid or unsupported parameters, including `participantId`, `page`, `offset`, `start`, or an AI limit over 20 |\n| 401 | `UNAUTHORIZED` | Invalid or missing API key |\n| 403 | `SCOPE_DENIED` | The key has no `syncconnector` scope |\n| 403 | `BITRIX_ACCESS_DENIED` | Bitrix24 refused access, including a webhook without the scope |\n| 422 | `METHOD_NOT_YET_AVAILABLE` | Required account update\u002Fmodule is unavailable; `error.release` names `syncconnector 26.100.0; rest >= 26.1300.0` |\n| 422 | `BITRIX_ERROR` | Other Bitrix24 refusal |\n\nSee [Errors](\u002Fdocs\u002Ferrors) for common authentication, credential and account refusals. Choosing `syncconnector` explicitly on a personal key fails if the account does not support that scope; it is never silently removed from a human selection.\n\n## See also\n\n- [Calls](\u002Fdocs\u002Fcalls)\n- [Call follow-up](\u002Fdocs\u002Fcalls\u002Ffollowup)\n- [Errors](\u002Fdocs\u002Ferrors)\n","2026-11-11",{},1794739466199]