Get Call Details
Retrieve the call detail record (CDR) for a call using the request_uuid returned by Initiate Outbound Call. Use this endpoint to check the final outcome of a call, fetch its recording, or inspect hangup details after the call has ended.
This endpoint is deprecated in favor of Get Call Info (GET /api/call-info/:request_id), which returns the same data. New integrations should use that endpoint instead — it will remain gated to accounts with the Click-to-Call X-API add-on or SFVoPI active, same as this one.
Requires X-API-Key header. See Authentication for details.
HTTP Request
GET /sfvopi/calls/:request_uuid
Base URL: https://prod-api.superfone.co.in/superfone
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
request_uuid | string | Yes | The request UUID returned when the call was created via POST /sfvopi/calls (format: sfv_ob_req_xxxxxxxxxxxx) |
Recordings are uploaded asynchronously after the call ends. Rather than polling this endpoint, we recommend subscribing to the CDR_RECORDING_AVAILABLE event notification — Superfone POSTs to your URL as soon as the recording is uploaded, instead of you repeatedly calling this endpoint to check. If you do poll, just check whether recording_url is populated — it stays null until the recording is ready.
Code Examples
- cURL
- JavaScript
- TypeScript
- Python
curl --location 'https://prod-api.superfone.co.in/superfone/sfvopi/calls/sfv_ob_req_wz0x_727aotn' \
--header 'X-API-Key: your_api_key_here'
const requestUuid = 'sfv_ob_req_wz0x_727aotn';
const response = await fetch(`https://prod-api.superfone.co.in/superfone/sfvopi/calls/${requestUuid}`, {
method: 'GET',
headers: {
'X-API-Key': 'your_api_key_here'
}
});
if (!response.ok) {
const error = await response.json();
throw new Error(`API Error (${response.status}): ${error.message}`);
}
const result = await response.json();
const call = result.data;
console.log('Call status:', call.call_status);
console.log('Duration (s):', call.duration);
console.log('Recording:', call.recording_status === 'UPLOADING' ? 'not ready yet' : call.recording_url);
interface HangupEvent {
role: 'CALLER' | 'CALLEE';
order: number;
timestamp: string;
channel_id: string;
hangup_code: number;
}
interface SfvopiPayload {
app_id: string;
answer_url: string;
hangup_url: string;
ring_method: 'POST' | 'GET';
request_uuid: string;
answer_method: 'POST' | 'GET';
hangup_method: 'POST' | 'GET';
}
interface CallMetadata {
task_id: number;
sfvopi_payload: SfvopiPayload;
first_hangup_by: 'CALLER' | 'CALLEE' | null;
hangup_sequence: HangupEvent[];
is_whatsapp_call: boolean;
system_outbound_action: string;
}
interface CallDetails {
id: number;
uuid: string;
request_uuid: string;
call_status: string;
call_type: 'INBOUND' | 'OUTBOUND';
duration: number;
phone: string;
voip_number: string;
sip_from: string;
sip_to: string;
start_time: string | null;
end_time: string | null;
answer_time: string | null;
recording_url: string | null;
recording_url_expires_at?: string;
recording_status: 'UPLOADING' | 'EARLY_MEDIA_ONLY' | 'OK' | 'DELETED' | 'EXPIRED';
recording_expire_at: string | null;
init_via_sim: boolean | null;
org_id: number;
metadata: CallMetadata;
updated_at: string;
deleted_at: string | null;
}
interface ApiResponse<T> {
data: T;
message: string;
}
const requestUuid = 'sfv_ob_req_wz0x_727aotn';
const response = await fetch(`https://prod-api.superfone.co.in/superfone/sfvopi/calls/${requestUuid}`, {
method: 'GET',
headers: {
'X-API-Key': 'your_api_key_here'
}
});
const result: ApiResponse<CallDetails> = await response.json();
console.log(result.data.call_status);
import requests
request_uuid = 'sfv_ob_req_wz0x_727aotn'
url = f'https://prod-api.superfone.co.in/superfone/sfvopi/calls/{request_uuid}'
headers = {
'X-API-Key': 'your_api_key_here'
}
response = requests.get(url, headers=headers)
response.raise_for_status()
call = response.json()['data']
print('Call status:', call['call_status'])
print('Duration (s):', call['duration'])
if call['recording_status'] == 'UPLOADING':
print('Recording not ready yet')
else:
print('Recording URL:', call['recording_url'])
Success Response
Status Code: 200 OK
{
"data": {
"recording_url": null,
"recording_status": "UPLOADING",
"id": 82948471,
"call_status": "NOANSWER",
"call_type": "OUTBOUND",
"duration": 0,
"phone": "+918892234495",
"start_time": "2026-07-10T09:08:05.000Z",
"end_time": "2026-07-10T09:08:22.000Z",
"recording_expire_at": null,
"answer_time": null,
"init_via_sim": null,
"org_id": 250541,
"voip_number": "+919403891390",
"metadata": {
"task_id": 0,
"sfvopi_payload": {
"app_id": "sfv_app_c36k8xzprdcf",
"answer_url": "https://example.ngrok-free.app/webhook/answer",
"hangup_url": "https://example.ngrok-free.app/webhook/hangup",
"ring_method": "POST",
"request_uuid": "sfv_ob_req_wz0x_727aotn",
"answer_method": "POST",
"hangup_method": "POST"
},
"first_hangup_by": "CALLER",
"hangup_sequence": [
{
"role": "CALLER",
"order": 1,
"timestamp": "2026-07-10T09:08:21Z",
"channel_id": "918892234495-86762449-sfvoch",
"hangup_code": 16
}
],
"is_whatsapp_call": false,
"system_outbound_action": "SFVOPI_OUTBOUND"
},
"updated_at": "2026-07-10T09:08:23.000Z",
"uuid": "b0e8b4cf-de3c-4b34-b65c-5859c05e323f",
"request_uuid": "sfv_ob_req_wz0x_727aotn",
"sip_from": "su_outbound",
"sip_to": "+918892234495",
"deleted_at": null
},
"message": "success"
}
Response Fields
| Field | Type | Description |
|---|---|---|
id | number | Internal numeric identifier for the call record |
uuid | string | Internal UUID for the call record (distinct from request_uuid) |
request_uuid | string | The request UUID used to create this call via POST /sfvopi/calls — matches the request_uuid path parameter |
call_status | string | Final or current status of the call, e.g. NOANSWER, COMPLETED, BUSY, FAILED, CANCELED. See Call Lifecycle |
call_type | string | Direction of the call — INBOUND or OUTBOUND |
duration | number | Call duration in seconds (0 if the call was never answered) |
phone | string | Counterparty phone number in E.164 format (the to number for outbound calls) |
voip_number | string | Your SFVoPI number used for the call, in E.164 format (the from number for outbound calls) |
sip_from | string | Internal SIP identity the call originated from |
sip_to | string | Internal SIP identity the call was routed to |
start_time | string | null | ISO 8601 timestamp when the call attempt started |
end_time | string | null | ISO 8601 timestamp when the call ended |
answer_time | string | null | ISO 8601 timestamp when the call was answered, null if never answered |
recording_url | string | null | Pre-signed URL to the call recording. Populated once recording_status reaches OK or EARLY_MEDIA_ONLY — null while UPLOADING, or if the call has no recording, or if recording_status is EXPIRED/DELETED |
recording_url_expires_at | string | undefined | ISO 8601 timestamp when the recording_url link itself expires — the sooner of the underlying recording's own expiry (recording_expire_at) or 7 days from when this response was generated. Only present when recording_url is populated in this response — re-fetch this endpoint to get a fresh link |
recording_status | string | Recording state — UPLOADING, EARLY_MEDIA_ONLY, OK, DELETED, or EXPIRED. See Recording Status |
recording_expire_at | string | null | ISO 8601 timestamp when the underlying recording becomes permanently unavailable (recording_status flips to EXPIRED after this), null if not applicable |
init_via_sim | boolean | null | Whether the call was initiated via a SIM-based route, null when not applicable |
org_id | number | Organization ID that owns this call |
updated_at | string | ISO 8601 timestamp the record was last updated |
deleted_at | string | null | ISO 8601 timestamp the record was soft-deleted, null if active |
metadata | object | Additional call metadata — see Metadata Object below |
Metadata Object
| Field | Type | Description |
|---|---|---|
metadata.task_id | number | Internal task identifier associated with the call, 0 if not applicable |
metadata.sfvopi_payload | object | The webhook configuration (app_id, answer_url, hangup_url, methods, request_uuid) that was used to place the call |
metadata.first_hangup_by | string | null | Which party hung up first — CALLER or CALLEE |
metadata.hangup_sequence | array | Ordered list of hangup events, one per party, including SIP hangup_code and timestamp |
metadata.is_whatsapp_call | boolean | Whether this was a WhatsApp voice call |
metadata.system_outbound_action | string | Internal action tag describing how the outbound call was triggered, e.g. SFVOPI_OUTBOUND |
Immediately after a call ends, recording_status is UPLOADING and recording_url is null. We recommend subscribing to the CDR_RECORDING_AVAILABLE event notification instead of polling — it fires as soon as the recording is ready. If polling, listen for your hangup_url webhook, then re-fetch this endpoint a few seconds later — recording_url populates once recording_status transitions to OK (call was answered) or EARLY_MEDIA_ONLY (call was never answered, but pre-answer audio was captured). It stays null if there is no recording, or if recording_status is EXPIRED or DELETED. Each recording_url is a pre-signed link valid until the sooner of the recording's own expiry or 7 days (see recording_url_expires_at) — re-fetch this endpoint to get a fresh one after it expires.
Error Responses
| Status Code | Message | When It Occurs |
|---|---|---|
401 | UnAuthorized, Please Provide Valid API Key | Missing or invalid X-API-Key header |
404 | Call not found | No call exists for the given request_uuid, or it does not belong to your organization |
500 | Failed to get call details: {error} | Unexpected server error |
Example Error Response
{
"message": "Call not found"
}
Related Endpoints
- Get Call Info — The successor to this endpoint, returning the same data
- Initiate Outbound Call — Place a call and obtain a
request_uuid - Hangup Webhook — Receive a real-time notification when a call ends
- Answer Webhook — Handle the answer callback
Next Steps
- Error Codes — Full list of API error codes
- Enums & Constants — Reference values used across the API