CDR Export & Billing Reconciliation API
Every finished message (SMS, MMS, WhatsApp, email, RCS, …) and every finished call in your workspace is recorded with the exact unit it was billed on — SMSsegments, voice duration_seconds, the persisted price + currency the wallet was charged at send or call-close time, and terminal timestamps. This surface returns those records as one flat, recency-ordered feed you filter, page, and export.
Use it to reconcile delivered usage against the billed record row-for-row. Reporting only: the feed never re-rates a record, never mutates a wallet, and never touches a provider.
Base path: /usage
Authentication: An organization API key (sent as X-API-Key or Authorization: Bearer dv_live_sk_…), or a session JWT for dashboard integrations. Either way, the caller must hold an owner, admin, or developer role with the billing:read scope — this feed is bulk billing data over the whole workspace, so both gates apply on both endpoints.
Export a JSON page
Page through CDRs
GET /usage/cdr
Returns one page of records, newest first, scoped to the calling tenant. Filtered with the same query string as the CSV export below, so the two formats always agree on which rows match.
Query parameters
Row fields
Every row carries the billing and ops fields needed for line-level reconciliation — endpoints, statuses, prices, never free-text message bodies:Page forward by passing the opaque
pagination.cursor from each response as the cursor query parameter. A malformed cursor degrades to the first page of the window rather than an error.Export a CSV file
Download CDRs as CSV
GET /usage/cdr/export.csv
The same filter set as the JSON feed, returned as a downloadable CSV attachment. Rate-limited to 5 requests per minute and capped at 50,000 rows per pull; page through the JSON endpoint for larger windows.
Additional query parameters
Every export is audit-logged as
usage.cdr_exported with the row count, window, and truncation flag.
When a pull exceeds the per-page cap, the response sets
X-Export-Truncated: true — page through with the JSON endpoint to drain the window.