For AI agents: markdown of this page — /docs-content-en/telephony/analytics.md documentation index — /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 filtering by fields, sorting and pagination.

Parameters

Parameter Type Default Description
filter (query) object Filtering 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
sort (query) string Field to sort by, in UPPER_SNAKE_CASE. Example: CALL_START_DATE
order (query) string Sort direction: ASC or DESC
limit (query) number 50 Maximum number of records in the response (up to 500)
offset (query) number 0 Offset 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 "https://vibecode.bitrix24.com/v1/calls/statistics?limit=10&sort=CALL_START_DATE&order=DESC&filter[CALL_TYPE]=1" \
  -H "X-Api-Key: YOUR_API_KEY"

curl — OAuth application

Terminal
curl "https://vibecode.bitrix24.com/v1/calls/statistics?limit=10&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: '10',
  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: '10',
  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 = 100
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
success boolean Always true on success
data array Array of call records
data[].id string Internal record identifier
data[].portalUserId string Operator ID. List: GET /v1/users
data[].portalNumber string Line identifier: reg<id> — a rented Voximplant line, sip<id> — a SIP line, REST_APP:<id> — a line via a REST application
data[].phoneNumber string Client's phone number
data[].callId string Call identifier. Prefixes: externalCall. — from register, callback. — from a callback, infocall. — from an automatic call
data[].externalCallId string | null External identifier passed at registration
data[].callCategory string Category: external for calls via the REST API
data[].callLog string | null URL of the Voximplant detailed log. null for calls via a REST application
data[].callDuration string Call duration in seconds (string)
data[].callStartDate string Call start date, ISO 8601 with the Bitrix24 account time zone
data[].callRecordUrl string URL of the call audio recording
data[].callVote string | null Call rating from 1 to 5
data[].cost string Call cost (decimal string)
data[].costCurrency string Currency code (USD and others)
data[].callFailedCode string Result code: 200 — success, 603-S — cancelled, 304 — missed, 500 — scenario error, 402 — insufficient funds, 403 — forbidden
data[].callFailedReason string Text reason for the result
data[].crmEntityType string Type of the linked CRM entity: LEAD, CONTACT or an empty string. Source: leads, contacts
data[].crmEntityId string ID of the linked CRM entity
data[].crmActivityId string CRM activity ID. "0" — no activity created
data[].restAppId string | null ID of the application that initiated the call
data[].restAppName string | null Name of the application that initiated the call
data[].transcriptId string | null ID of the attached transcription. Attach: POST /v1/calls/:callId/transcription
data[].transcriptPending string Y — transcription is being processed, N — transcription is ready or absent
data[].sessionId string Voximplant session identifier
data[].redialAttempt string | null Redial attempt number
data[].comment string | null Operator comment
data[].recordDuration string | null Conversation recording duration in seconds
data[].recordFileId string | null ID of the recording file on the Drive
data[].callType string Call type: "1" — outbound, "2" — inbound, "3" — inbound with redirect, "4"callback, "5" — informational (automatic call)
total number Total 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
401 MISSING_API_KEY The X-Api-Key header was not provided
401 INVALID_API_KEY Invalid API key
401 TOKEN_MISSING The key has no configured Bitrix24 tokens
401 KEY_INACTIVE The API key is inactive or revoked
403 SCOPE_DENIED The key lacks the telephony scope
422 BITRIX_ERROR Bitrix24 returned an error (text in error.message)
429 RATE_LIMITED Request limit exceeded
502 BITRIX_UNAVAILABLE Bitrix24 is unavailable

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