Call CDR & Export
Every call writes a CDR (call detail record): one row per call with its direction, numbers, timestamps, duration, and disposition. CDRs are stored in two tiers: a queryable recent window for dashboards and exports, and an unbounded archive for long-term retention.
The record
Section titled “The record”CREATE TABLE call_cdr ( call_id TEXT PRIMARY KEY, account_id TEXT, direction TEXT, -- inbound | outbound | internal from_num TEXT, to_num TEXT, start_ts INTEGER, -- epoch ms (call start = the routing decision) answer_ts INTEGER, -- epoch ms (when answered) end_ts INTEGER, -- epoch ms (call ended) duration_sec INTEGER, -- wall-clock seconds billsec INTEGER, -- billable (answered) seconds answered INTEGER, disposition TEXT, -- answered | no_answer | … hangup_cause TEXT, queue_id TEXT, -- if it went through a queue agent_id TEXT, -- the connected agent cost_micros INTEGER -- billing (micro-units));A start row is written when the call is routed and upserted to completion when the call ends, so a row exists even if the call never completes cleanly.
Two-tier storage
Section titled “Two-tier storage”- Recent window (queryable): the
call_cdrtable keeps a rolling 30-day window for fast queries and export. - Archive (unbounded): every completed call is also written to a per-account archive in the object-storage data lake (Apache Iceberg), the canonical, long-term record for analytics and compliance.
Query & export
Section titled “Query & export”GET /v1/calls returns CDRs for your account over a time range, as JSON or CSV (the cdr scope):
| Param | Purpose |
|---|---|
since / until | Epoch-ms range (defaults: all / now). |
limit | Max rows (default 1000, capped 10000). |
cursor | Keyset pagination: pass the previous response’s next_cursor for the next page. |
format | csv for a download, else JSON. |
curl 'https://api.sip.io/v1/calls?since=1719600000000&format=csv' \ -H 'x-api-key: sk_…' -o cdr.csvJSON returns { ok, count, rows }; CSV is RFC-4180 quoted for spreadsheets and BI tools.
Call rating
Section titled “Call rating”cost_micros is computed at call end by a rate engine: an account’s rate_plan holds rate rows keyed by destination prefix (longest match wins), each with a per_min_micros, a per-call connection_fee_micros, and a billing increment_sec (e.g. 60/60 or 1/1). Answered seconds are rounded up to the increment and priced; unanswered calls cost 0. It’s a usage-rating layer, not a full billing system.
The queue_id and agent_id are stamped onto the record for queue calls, and the 30-day window is pruned daily.
Related
Section titled “Related”- Queue Metrics & CDR: the per-queue timing CDR that drives ASA/SL/AHT.
- Agent KPIs: occupancy, utilization, and adherence.
- Live Supervisor Wallboard: real-time view.