Get a call
curl https://api.yotel.in/api/v1/calls/{call_id} \
-H "Authorization: Bearer yt_live_YOUR_KEY"
call = client.calls.get("call_id")
print(call.disposition, call.talk_duration_s)
const call = await client.calls.get("call_id");
console.log(call.disposition, call.talk_duration_s);
calls:read | Status: 200 OK
Response fields
| Field | Type | Description |
|---|---|---|
id | string | Call UUID |
campaign_id | string | null | Campaign this call belongs to |
lead_id | string | null | Lead that was dialed |
agent_id | string | null | Agent who handled the call (null for voice-agent-only calls) |
fs_uuid | string | FreeSWITCH channel UUID |
direction | string | "outbound" or "inbound" |
status | string | "dialing", "ringing", "answered", "agent_connected", "completed", "failed" |
dial_time | string | null | ISO 8601 timestamp when the call was originated |
ring_time | string | null | When the remote party started ringing |
answer_time | string | null | When the remote party answered |
agent_connect_time | string | null | When the call was bridged to a human agent |
end_time | string | null | When the call ended |
ring_duration_s | integer | null | Seconds from ring to answer |
talk_duration_s | integer | null | Seconds from answer to hangup |
total_duration_s | integer | null | Seconds from dial to hangup |
hangup_cause | string | null | FreeSWITCH hangup cause (e.g., "NORMAL_CLEARING", "NO_ANSWER") |
hangup_disposition | string | null | Who ended the call, from FreeSWITCH’s sip_hangup_disposition: "recv_bye" — the far end (the customer) sent the BYE; "send_bye" — Yotel did (agent, voice agent, max duration). Pre-answer values (recv_cancel, send_cancel, …) also appear. null until the hangup completes and on legs that carry none |
has_recording | boolean | Whether a recording exists |
recording_url | string | null | Signed URL (available after call.recording_ready webhook) |
disposition | string | null | Agent- or AI-set disposition code |
notes | string | null | Agent notes |
ai_summary | string | null | Gemini-generated call summary |
ai_sentiment | string | null | Detected sentiment ("positive", "negative", "neutral") |
ai_next_action | string | null | Suggested follow-up action |
List calls for a campaign
Returns a paginated list of calls for a specific campaign.curl "https://api.yotel.in/api/v1/campaigns/{campaign_id}/calls?page=1&page_size=50" \
-H "Authorization: Bearer yt_live_YOUR_KEY"
calls = client.calls.list(campaign_id="campaign_id", page=1, page_size=50)
print(f"Total: {calls.total}, Page: {calls.page}")
const calls = await client.calls.list({
campaignId: "campaign_id",
page: 1,
pageSize: 50,
});
console.log(`Total: ${calls.total}, Page: ${calls.page}`);
calls:read | Status: 200 OK
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number (1-indexed) |
page_size | integer | 25 | Results per page (1–200) |
status | string | — | Filter by call status |
disposition | string | — | Filter by disposition code |
Response
{
"items": [ /* CallDetail objects */ ],
"total": 1247,
"page": 1,
"page_size": 50
}
Errors
| Status | Condition |
|---|---|
404 | Call or campaign not found, or belongs to another tenant |

