Call history and recordings
The API has 2 read scopes. The cdrs:read scope opens GET /cdrs, the call history of the
account. The recordings:read scope opens GET /recordings, the audio download, and the transcript.
List calls
The list is cursor-paginated and shows the newest call first. If you send no from, the list has
only the calls of the last 7 days. A range of more than 92 days returns 422. A from value after to also returns 422. A from or to
value without a timezone also returns 422:
Send next_cursor as cursor to get the next page. limit is 1 to 100. The default is 25. Set
include_total=true to fill total_count. This causes an extra count query.
What a record contains
Each row is one call. The system seals the row a few seconds after the call ends. The id is the
one id of the call. It is the same id that the live board and every webhook use.
The record has no sip_call_id. The SIP Call-ID is not part of the list. Use id to identify a call.
Analysis fields
The analysis fields come from post-call analysis. They are null when the call has no analysis. See
Post-call analysis.
The list has no analysis filters. For the summary and the other fields of a result, use the
call.analysis_completed webhook.
Numbers on an outbound call
On an outbound record, from_number is the caller ID that the carrier saw. from_type is did.
to_number is the number that the system dialed, after the callee_out rules of the route. The
extension that placed the call is in agent_extension_snapshot.
Outcome and outcome detail
outcome has a closed list of values. Branch on this field. The values are answered,
no_answer, busy, abandoned, canceled, failed, and voicemail.
outcome_detail gives the reason. The values are:
A blind transfer counts as answered only when the target answers. The system adds new details without notice. Treat a value that you do not know as information only.
Recordings
A recording row has these fields:
page starts at 1. items_per_page is 1 to 100. The default is 10. To match a recording to a call,
use the call_id of the recording or the recording_id of the call.
GET /recordings/{id} returns one row. GET /recordings/{id}/audio answers 307 with a
short-lived signed URL for the merged stereo WAV. The customer is on the left channel. The agent is on
the right channel. Add ?blended=true to get a rendition with less channel separation. If that rendition does not exist, the API returns 404.
Follow the 307 redirect. The audio endpoint does not send audio bytes itself, so a client that does
not follow redirects gets no audio. Do not store the signed URL, because it expires.
Only calls that a trunk, DID, outbound route, or queue marks for recording have a recording. See Call history and recordings for the recording policies.
Public audio link
The call.recording_ready webhook carries recording_url. This link points to
GET /recordings/public/{token}/audio. The route needs no API key. It answers 307 with a signed
URL for the merged stereo WAV. Your client must follow the redirect. The link expires at recording_url_expires_at, 24 hours after the webhook by default. After
that time it returns 404. A forged token also returns 404. After the link expires, use
GET /recordings/{id}/audio with your key.
Transcripts
A transcript is the text of a recording. The system merges the customer channel and the agent channel into one dialogue in time order. A transcript exists only when call transcription is on for your account. When a recording finishes its merge and transcription is on, the system makes the transcript automatically. An administrator can also request a transcript in the dashboard. The developer API only reads transcripts.
transcript_status on a recording row and on a call record shows the state:
transcript_error is too_long when the recording is too long to transcribe. It is unavailable
for any other failure.
GET /recordings/{id}/transcript needs the recordings:read scope. The response contains
id, recording_id, status, provider, dialogue, created_at, and updated_at:
Each turn has a speaker (customer or agent), the text, and the start_sec and end_sec of
the speech in the recording.
Reconcile from webhooks
call.completed carries the same core fields as a call record. call.recording_ready gives the
recording_id and the call_id when the audio is ready. call.analysis_completed gives the full
result of a post-call analysis. If you store these events, you need
the endpoints on this page only to fill gaps or to answer a single question. See
Webhooks.