***
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.