Calls & Recordings
List and inspect voice calls — both phone calls and browser voice sessions — and fetch playback links for their recordings.
| Operation | Endpoint | Scope |
|---|---|---|
| List calls | GET /api/v1/calls | conversations:read |
| Get one call | GET /api/v1/calls/{id} | conversations:read |
| Recording playback links | GET /api/v1/conversations/{id}/recordings | conversations:read |
A call is a conversation
Every row carries conversation_id, and it is the same identifier the conversation operations take. So you can list calls here and pull the full transcript from GET /api/v1/conversations/{id}/events without holding two ids for one thing.
bash
curl "https://<your-workspace>-api.perfox.ai/api/v1/calls?limit=50" \
-H "Authorization: Bearer sk_…"| Field | Meaning |
|---|---|
conversation_id | Cross-links to the conversation and its transcript |
customer_id | The customer on the call |
channel | The voice channel — a phone call or a browser voice session |
direction | Currently always unknown — see below |
status | Conversation status |
started_at / ended_at | When the call began and finished |
duration_seconds | Call length; null when it cannot be determined |
has_recording | Whether playback links are currently available |
summary | Present once a summary has been written |
end_user | Name and phone, where known |
Paging
Newest first. limit accepts up to 200 and defaults to 50. When more rows exist the response carries next_cursor — send it back as cursor.
The cursor is a position in time rather than an offset, so calls arriving while a user scrolls cannot make you skip or repeat a row. status, start_date and end_date (both inclusive, ISO dates) narrow the list further.
Two honest limits
direction reports unknown. Whether a call was placed or received is not recorded on the call itself today, and a wrong direction in a call log is worse than a blank one.
has_recording turns false once a recording passes your workspace's retention window, even though the call itself remains — so the flag never points at a file that has already been deleted.
Recordings
bash
curl "https://<your-workspace>-api.perfox.ai/api/v1/conversations/$CONVERSATION_ID/recordings" \
-H "Authorization: Bearer sk_…"json
{
"conversation_id": "01a0…",
"expires_in_seconds": 900,
"recordings": [
{ "leg": "caller", "url": "https://…" },
{ "leg": "ai", "url": "https://…" },
{ "leg": "combined", "url": "https://…" }
]
}A recorded session produces up to three legs: caller and ai as separate mono tracks, and combined as a stereo mix with the caller on the left and the agent on the right. Play the stereo mix for review; reach for the separate legs when you need to isolate one side. Only the legs that exist are returned.
Fetch these when the player opens — do not store them
The links are deliberately short-lived. A recording URL that outlives the page it was rendered on is a recording URL that can be forwarded. Ask again for a fresh link rather than caching one.
A call whose recordings have passed your retention window returns an empty list, rather than links that would fail to play.