CDR API

The CDR (Call Detail Record) API lets you query call history with cursor-based pagination and filtering.

CDR page in ZPBX

List calls

GET /v1/calls

Query parameters

ParameterTypeDefaultDescription
pageSizenumber50Records per page (max 1000)
cursorstringPagination cursor from nextPageUrl
startTime[gte]ISO dateFilter: calls started after this timestamp
startTime[lte]ISO dateFilter: calls started before this timestamp
directioninbound | outboundFilter by call direction
tostringFilter by destination (partial match)
hangupCausestringFilter by hangup cause

Example request

curl "https://api.zpbx.es/v1/calls?pageSize=20&direction=outbound" \
  -H "Authorization: Bearer zpbx_your_api_key_here"

Example response

{
  "calls": [
    {
      "id": "clx...",
      "uuid": "47ffa48a-888c-...",
      "direction": "outbound",
      "from": "441632960123",
      "to": "12025550123",
      "startTime": "2026-06-15T14:51:18Z",
      "endTime": "2026-06-15T14:53:43Z",
      "duration": 145,
      "billDuration": 140,
      "pdd": 1.2,
      "hangupCause": "NORMAL_CLEARING",
      "q850Cause": 16,
      "readCodec": "PCMA",
      "writeCodec": "PCMU",
      "price": 0.039,
      "currency": "USD",
      "recordingUrl": null
    }
  ],
  "nextPageUrl": "https://api.zpbx.es/v1/calls?pageSize=20&cursor=eyJj...",
  "meta": { "pageSize": 20, "hasMore": true }
}

Fields buyCost, margin, and supplierId are only included if your API key has the calls:read_cost scope. Without it, those fields are omitted.

Get a single call

GET /v1/calls/{id}
curl https://api.zpbx.es/v1/calls/clxabc123 \
  -H "Authorization: Bearer zpbx_your_api_key_here"

Returns the full call detail, including accountcode and networkAddr.

Call fields

FieldTypeDescription
fromstringCaller number (A-number)
tostringCalled number (B-number)
directionstringinbound or outbound
durationnumberTotal duration in seconds
billDurationnumberBillable duration in seconds
pddnumber | nullPost Dial Delay in seconds
hangupCausestring | nullCall hangup cause
q850Causenumber | nullQ.850 cause code
readCodecstring | nullInbound codec
writeCodecstring | nullOutbound codec
pricenumberSell price
currencystringCurrency code
recordingUrlstring | nullRecording path (if recorded)

Pagination

The API uses cursor-based pagination (not offset). When meta.hasMore is true, use the nextPageUrl to fetch the next page:

curl "https://api.zpbx.es/v1/calls?pageSize=50&cursor=eyJjcmVhdGVkQXQiO..." \
  -H "Authorization: Bearer zpbx_your_api_key_here"

The cursor is opaque — don't modify it, just pass it through.