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

List calls
GET /v1/calls
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
pageSize | number | 50 | Records per page (max 1000) |
cursor | string | — | Pagination cursor from nextPageUrl |
startTime[gte] | ISO date | — | Filter: calls started after this timestamp |
startTime[lte] | ISO date | — | Filter: calls started before this timestamp |
direction | inbound | outbound | — | Filter by call direction |
to | string | — | Filter by destination (partial match) |
hangupCause | string | — | Filter 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
| Field | Type | Description |
|---|---|---|
from | string | Caller number (A-number) |
to | string | Called number (B-number) |
direction | string | inbound or outbound |
duration | number | Total duration in seconds |
billDuration | number | Billable duration in seconds |
pdd | number | null | Post Dial Delay in seconds |
hangupCause | string | null | Call hangup cause |
q850Cause | number | null | Q.850 cause code |
readCodec | string | null | Inbound codec |
writeCodec | string | null | Outbound codec |
price | number | Sell price |
currency | string | Currency code |
recordingUrl | string | null | Recording 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.