Retrieve a phone call
Retrieves one call — outbound or inbound (direction) — by id.
Retrieves one call — outbound or inbound (direction) — by id. While a call is still in flight (queued, initiating, ringing, or in_progress) its status, duration, cost, and transcript are refreshed on read, so polling this endpoint is how you follow a call to completion; a terminal call is served from its stored record. Terminal statuses are completed, failed, no_answer, busy, and canceled, and a settled call carries durationSeconds, hangupCause, answeredBy (whether a person or a machine picked up), costUsd, summary, — when the call was placed with questions — structured answers, and for an inbound call the caller's structured notes (each { kind, text, due }, kind one of task, note, reminder, message). A call belonging to another account returns 404. Requires the phone:read scope.
Scope: phone:read. Send the API key as a bearer token; Scopes lists what each one reaches.
Request
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string (uuid) | yes | The phone call's ID. |
Response
200 Success. Body: application/json, PhoneCall.
| Field | Type | Required | Description |
|---|---|---|---|
object | "phone_call" | yes | |
id | string (uuid) | yes | |
direction | "outbound", "inbound" | yes | outbound for calls placed with POST /v1/phone/calls, inbound for calls answered by a number's inbound agent. |
status | "queued", "initiating", "ringing", "in_progress", "completed", "failed", "no_answer", "busy", "canceled" | yes | Terminal: completed, failed, no_answer, busy, canceled. |
fromNumber | string | yes | |
toNumber | string | yes | |
instructions | string or null | no | |
greeting | string or null | no | |
voice | string or null | no | The Dairo Live voice id. |
model | string or null | no | Always dairo-live. |
language | string or null | no | |
maxDurationSeconds | integer or null | no | |
voicemailMessage | string or null | no | |
queuedAt | string (date-time) or null | no | |
startedAt | string (date-time) or null | no | |
answeredAt | string (date-time) or null | no | |
endedAt | string (date-time) or null | no | |
durationSeconds | integer or null | no | |
hangupCause | string or null | no | |
answeredBy | string or null | no | human or machine, from answering-machine detection. |
summary | string or null | no | |
notes | array of PhoneCallNote or null | no | Inbound calls: the caller's structured notes (tasks, notes, reminders, messages). |
costUsd | number or null | no | Billed per started minute: the $0.09/min Dairo Live rate plus the destination's telephony rate. Calls that never connect are free. |
error | string or null | no | |
metadata | object | no | |
idempotencyKey | string or null | no | |
createdAt | string (date-time) | yes |
Errors
Every error has the same body, {"error": {"type", "code", "message", "param"}}; branch on code. Errors lists every code.
| Status | Meaning |
|---|---|
400 | The request is malformed or a value is invalid (invalid_request, invalid_domain, idempotency_key_mismatch). |
401 | The API key is missing or invalid. |
403 | The key lacks the scope this endpoint needs (scope_missing) or may not do this (not_permitted). |
404 | No such resource in this account (resource_not_found). |
429 | Rate limit, plan limit, budget or spend cap reached (rate_limited, plan_limit_reached, budget_exceeded, spend_cap_reached). |
500 | An unexpected error; retry with backoff, then contact support (internal_error). |
Place an outbound AI phone call
Places an outbound AI voice call and returns immediately with the call in queued status; the dial runs asynchronously, so poll GET /v1/phone/calls/{id} or subscribe to call.status_changed to follow it to a terminal state.
Retrieve a call's transcript
Returns the turn-by-turn transcript as { object: "phone_call.transcript", callId, turns }, where each turn has role, content, and timestamp.