لوكلاء AI: ملف markdown لهذه الصفحة — /docs-content-en/telephony/analytics.md فهرس التوثيق — /llms.txt

مقالات التوثيق متاحة حاليًا باللغة الإنجليزية فقط.

Analytics and reference data

Reading statistics of past calls with filtering by date, type, operator and other fields, and a reference of available voices for speech synthesis in automatic calls.

Bitrix24 API: voximplant.statistic.get, voximplant.tts.voices.get Scope: telephony

Call statistics

GET /v1/calls/statistics

Returns a list of records of past calls with support for field filtering, sorting, and pagination with a fixed page of up to 50 records.

Parameters

Parameter Type Default Description
Parameterfilter (query) Typeobject Default— DescriptionFiltering by record fields (UPPER_SNAKE_CASE). The operators >, >=, <, <=, ! are supported as a prefix to the field name. Example: ?filter[CALL_TYPE]=1, ?filter[>CALL_START_DATE]=2026-01-01T00:00:00 Important: this endpoint accepts the BRACKET form only: ?filter[CALL_TYPE]=1. A JSON object (?filter={"CALL_TYPE":1}) is forwarded to Bitrix24 as a string and does not become a filter. Spell every condition once and no deeper than two levels: when a condition is lost while the query string is parsed, the request is refused with 400 INVALID_FILTER rather than half-applied. A lowercase filter carrying a value next to an uppercase FILTER is the same case: the lowercase one takes the parameter and the uppercase one silently disappears. An empty ?filter= next to FILTER[...] loses nothing and works. An empty ?filter= means "no filter".
Parametersort (query) Typestring Default— DescriptionField to sort by, in UPPER_SNAKE_CASE. Example: CALL_START_DATE
Parameterorder (query) Typestring Default— DescriptionSort direction: ASC or DESC
Parameterlimit (query) Typenumber Default50 DescriptionCompatibility parameter; use 50. The route returns one Bitrix24 page of up to 50 records
Parameteroffset (query) Typenumber Default0 DescriptionOffset for pagination

A date range is set with two operators at once. Example: filter[>CALL_START_DATE]=2026-04-01T00:00:00&filter[<CALL_START_DATE]=2026-04-30T23:59:59.

Examples

curl — personal key

Terminal
curl --globoff "https://vibecode.bitrix24.com/v1/calls/statistics?limit=50&sort=CALL_START_DATE&order=DESC&filter[CALL_TYPE]=1" \
  -H "X-Api-Key: YOUR_API_KEY"

curl — OAuth application

Terminal
curl --globoff "https://vibecode.bitrix24.com/v1/calls/statistics?limit=50&sort=CALL_START_DATE&order=DESC&filter[CALL_TYPE]=1" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN"

JavaScript — personal key

javascript
const params = new URLSearchParams({
  limit: '50',
  sort: 'CALL_START_DATE',
  order: 'DESC',
  'filter[CALL_TYPE]': '1',
})

const res = await fetch(`https://vibecode.bitrix24.com/v1/calls/statistics?${params}`, {
  headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})

const { success, data, total } = await res.json()
console.log(`Calls found: ${total}`)

JavaScript — OAuth application

javascript
const params = new URLSearchParams({
  limit: '50',
  sort: 'CALL_START_DATE',
  order: 'DESC',
  'filter[CALL_TYPE]': '1',
})

const res = await fetch(`https://vibecode.bitrix24.com/v1/calls/statistics?${params}`, {
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
  },
})

const { success, data, total } = await res.json()

JavaScript — iterating through all pages

javascript
const pageSize = 50
let offset = 0
const allCalls = []

while (true) {
  const params = new URLSearchParams({
    limit: String(pageSize),
    offset: String(offset),
    sort: 'CALL_START_DATE',
    order: 'DESC',
  })

  const res = await fetch(`https://vibecode.bitrix24.com/v1/calls/statistics?${params}`, {
    headers: { 'X-Api-Key': 'YOUR_API_KEY' },
  })
  // total is at the root of the response — total records under the filter
  const { data, total } = await res.json()

  allCalls.push(...data)
  offset += data.length

  // fetch the next page until all records are collected
  if (offset >= total || data.length === 0) break
}

console.log(`Calls collected: ${allCalls.length}`)

Response fields

Field Type Description
Fieldsuccess Typeboolean DescriptionAlways true on success
Fielddata Typearray DescriptionArray of call records
Fielddata[].id Typestring DescriptionInternal record identifier
Fielddata[].portalUserId Typestring DescriptionOperator ID. List: GET /v1/users
Fielddata[].portalNumber Typestring DescriptionLine identifier: reg<id> — a rented Voximplant line, sip<id> — a SIP line, REST_APP:<id> — a line via a REST application
Fielddata[].phoneNumber Typestring DescriptionClient's phone number
Fielddata[].callId Typestring DescriptionCall identifier. Prefixes: externalCall. — from register, callback. — from a callback, infocall. — from an automatic call
Fielddata[].externalCallId Typestring | null DescriptionExternal identifier passed at registration
Fielddata[].callCategory Typestring DescriptionCategory: external for calls via the REST API
Fielddata[].callLog Typestring | null DescriptionURL of the Voximplant detailed log. null for calls via a REST application
Fielddata[].callDuration Typestring DescriptionCall duration in seconds (string)
Fielddata[].callStartDate Typestring DescriptionCall start date, ISO 8601 with the Bitrix24 account time zone
Fielddata[].callRecordUrl Typestring DescriptionURL of the call audio recording
Fielddata[].callVote Typestring | null DescriptionCall rating from 1 to 5
Fielddata[].cost Typestring DescriptionCall cost (decimal string)
Fielddata[].costCurrency Typestring DescriptionCurrency code (USD and others)
Fielddata[].callFailedCode Typestring DescriptionResult code: 200 — success, 603-S — cancelled, 304 — missed, 500 — scenario error, 402 — insufficient funds, 403 — forbidden
Fielddata[].callFailedReason Typestring DescriptionText reason for the result
Fielddata[].crmEntityType Typestring DescriptionType of the linked CRM entity: LEAD, CONTACT or an empty string. Source: leads, contacts
Fielddata[].crmEntityId Typestring DescriptionID of the linked CRM entity
Fielddata[].crmActivityId Typestring DescriptionCRM activity ID. "0" — no activity created
Fielddata[].restAppId Typestring | null DescriptionID of the application that initiated the call
Fielddata[].restAppName Typestring | null DescriptionName of the application that initiated the call
Fielddata[].transcriptId Typestring | null DescriptionID of the attached transcription. Attach: POST /v1/calls/:callId/transcription
Fielddata[].transcriptPending Typestring DescriptionY — transcription is being processed, N — transcription is ready or absent
Fielddata[].sessionId Typestring DescriptionVoximplant session identifier
Fielddata[].redialAttempt Typestring | null DescriptionRedial attempt number
Fielddata[].comment Typestring | null DescriptionOperator comment
Fielddata[].recordDuration Typestring | null DescriptionConversation recording duration in seconds
Fielddata[].recordFileId Typestring | null DescriptionID of the recording file on the Drive
Fielddata[].callType Typestring DescriptionCall type: "1" — outbound, "2" — inbound, "3" — inbound with redirect, "4" — callback, "5" — informational (automatic call)
Fieldtotal Typenumber DescriptionTotal number of records matching the filter

Response example

JSON
{
  "success": true,
  "data": [
    {
      "id": "1",
      "portalUserId": "1",
      "portalNumber": "reg133788",
      "phoneNumber": "+12025550123",
      "callId": "11018129443EB80D.1754478520.11438214",
      "externalCallId": null,
      "callCategory": "external",
      "callLog": "https://storage-gw-ru-02.voximplant.com/voximplant-logs/2025/08/06/...",
      "callDuration": "0",
      "callStartDate": "2025-08-06T14:08:40+00:00",
      "callRecordUrl": "",
      "callVote": null,
      "cost": "0.0000",
      "costCurrency": "USD",
      "callFailedCode": "603-S",
      "callFailedReason": "Decline self",
      "crmEntityType": "CONTACT",
      "crmEntityId": "275",
      "crmActivityId": "7739",
      "restAppId": null,
      "restAppName": null,
      "transcriptId": null,
      "transcriptPending": "N",
      "sessionId": "3841557776",
      "redialAttempt": null,
      "comment": null,
      "recordDuration": null,
      "recordFileId": null,
      "callType": "1"
    }
  ],
  "total": 30
}

Error response example

403 — no telephony scope:

JSON
{
  "success": false,
  "error": {
    "code": "SCOPE_DENIED",
    "message": "This endpoint requires 'telephony' scope"
  }
}

Errors

HTTP Code Description
HTTP401 CodeMISSING_API_KEY DescriptionThe X-Api-Key header was not provided
HTTP401 CodeINVALID_API_KEY DescriptionThe key is not recognized — no such key exists on the platform
HTTP401 CodeTOKEN_MISSING DescriptionThe key has no configured Bitrix24 tokens
HTTP401 CodeKEY_INACTIVE DescriptionThe API key is inactive or revoked
HTTP403 CodeSCOPE_DENIED DescriptionThe key lacks the telephony scope
HTTP422 CodeBITRIX_ERROR DescriptionBitrix24 returned an error (text in error.message)
HTTP429 CodeRATE_LIMITED DescriptionRequest limit exceeded
HTTP502 CodeBITRIX_UNAVAILABLE DescriptionBitrix24 is unavailable
HTTP400 CodeINVALID_FILTER DescriptionAn ambiguous filter envelope: bracket and JSON forms mixed, or a bracket condition deeper than two levels. Pass the whole filter in a single form

The full list of common API errors — Errors.

Known specifics

Field names in filter and sort are UPPER_SNAKE_CASE, but in the response they are camelCase. The filter and sort parameters accept the original Bitrix24 names (CALL_TYPE, CALL_START_DATE), while the response fields come back in camelCase (callType, callStartDate). A filter on a camelCase name is silently ignored — all records are returned.

total is at the root of the response. Unlike other Vibecode list endpoints, the total field is located directly at the root of the response, not in meta.total.

A filter on a nonexistent field does not return an error — an invalid field name is silently ignored and all records are returned.

See also