*** title: Call Metrics sidebarTitle: Call Metrics description: 'Retrieve call details, transcripts, recordings, and performance data.' ------------------------------------------------------------------------------------ Access detailed information about every call through the SDK. ## Getting Recent Calls Fetch a paginated list of calls: ```python from smallestai.atoms.call import Call call = Call() calls = call.get_calls(limit=5) for log in calls["data"]["logs"]: print(f"{log['callId']}: {log['status']} ({log['duration']}s)") ``` The response includes pagination info: ```json { "status": true, "data": { "logs": [...], "pagination": { "total": 94, "page": 1, "hasMore": true, "limit": 5 } } } ``` *** ## Filtering Calls Narrow results using filter parameters: ```python from smallestai.atoms.call import Call call = Call() # By status completed = call.get_calls(status="completed", limit=10) # By agent agent_calls = call.get_calls(agent_id="696ddd281ea16a73cb8aafbe", limit=10) # By campaign campaign_calls = call.get_calls(campaign_id="696ddd2a04ff172dbd8eddad", limit=10) # By call type outbound = call.get_calls(call_type="telephony_outbound", limit=10) # By phone number found = call.get_calls(search="+916366821717", limit=10) ``` ### Filter Parameters | Parameter | Type | Description | | ------------- | ------ | ------------------------------------------------- | | `agent_id` | string | Filter by agent ID | | `campaign_id` | string | Filter by campaign ID | | `page` | int | Page number (default: 1) | | `limit` | int | Results per page (default: 10) | | `status` | string | completed, failed, in\_progress, no\_answer, busy | | `call_type` | string | telephony\_inbound, telephony\_outbound, chat | | `search` | string | Match callId, fromNumber, or toNumber | *** ## Getting Single Call Details Retrieve complete details for one call: ```python from smallestai.atoms.call import Call call = Call() call_id = "CALL-1768807723178-4561d0" details = call.get_call(call_id) data = details["data"] print(f"Status: {data['status']}") print(f"Duration: {data['duration']} seconds") print(f"From: {data['from']} → To: {data['to']}") ``` ### Response Fields | Field | Description | | --------------------- | --------------------------------------------- | | `callId` | Unique call identifier | | `status` | completed, failed, in\_progress, no\_answer | | `duration` | Length in seconds | | `type` | telephony\_outbound, telephony\_inbound, chat | | `from` / `to` | Phone numbers | | `transcript` | Array of conversation messages | | `recordingUrl` | Mono audio file URL | | `recordingDualUrl` | Stereo audio file URL | | `callCost` | Cost in credits | | `disconnectionReason` | user\_hangup, agent\_hangup, timeout | | `postCallAnalytics` | AI summary and extracted metrics | *** ## Accessing Transcripts The transcript is an array of messages with speaker roles: ```python details = call.get_call(call_id) transcript = details["data"].get("transcript", []) for msg in transcript: print(f"{msg['role']}: {msg['content']}") ``` *** ## Accessing Recordings Recordings are available after the call completes: ```python details = call.get_call(call_id) data = details["data"] if data.get("recordingUrl"): print(f"Mono: {data['recordingUrl']}") if data.get("recordingDualUrl"): print(f"Stereo: {data['recordingDualUrl']}") ``` *** ## Batch Search Fetch multiple calls at once with `search_calls()`: ```python call_ids = ["CALL-1768807723178-4561d0", "CALL-1768807723177-4561cd"] result = call.search_calls(call_ids) print(f"Found {result['data']['total']} of {len(call_ids)} calls") ``` Maximum 100 call IDs per request. *** ## Performance Metrics Each call includes latency breakdowns: ```python details = call.get_call(call_id) data = details["data"] print(f"Transcriber: {data.get('average_transcriber_latency')}ms") print(f"Agent (LLM): {data.get('average_agent_latency')}ms") print(f"Synthesizer: {data.get('average_synthesizer_latency')}ms") ``` | Metric | Description | | ----------------------------- | ------------------------------ | | `average_transcriber_latency` | Speech-to-text processing time | | `average_agent_latency` | LLM response generation time | | `average_synthesizer_latency` | Text-to-speech processing time | *** ## SDK Reference | Method | Description | | ------------------------ | -------------------------------- | | `get_calls(...)` | List calls with optional filters | | `get_call(call_id)` | Get single call with all details | | `search_calls(call_ids)` | Batch fetch by call IDs | *** ## Tips `status` is the outcome (completed, failed). `disconnectionReason` explains *why* it ended: * `user_hangup` — Caller hung up * `agent_hangup` — Agent ended the call * `dial_no_answer` — No pickup * `timeout` — Call timeout Recordings generate after the call ends. They may take a few seconds to appear. Check if `recordingUrl` is non-empty before accessing. Fetch calls with `get_calls()`, then calculate: ```python calls = call.get_calls(status="completed", limit=100) durations = [log["duration"] for log in calls["data"]["logs"]] avg = sum(durations) / len(durations) ``` Use the `search` parameter: ```python calls = call.get_calls(search="+916366821717") ``` Currently, use pagination and filter client-side by `createdAt`. Date range filters are coming soon.