Phone, SMS & voice

Call history and recordings

Read every call across your numbers and channels from one feed, open a call with its transcript, and fetch a fresh recording link.

GET /v1/calls is one feed of every call on your numbers: phone and WhatsApp, inbound and outbound, newest first. Each call record carries its duration, end reason, cost, and the recording and transcript when those were on.

#Read from one place, act on the channel

Surface Use it to
/v1/calls Read. List, fetch and get recordings for every call on both channels, with contactId and contactName when the other party is a known contact.
/v1/voice/calls Act on phone calls: place, transfer, end, browser dial, estimate. Its list and get return phone calls only.
/v1/whatsapp/calls Act on WhatsApp calls. See WhatsApp calling.

#List calls

curl "https://api.pozy.ai/v1/calls?direction=inbound&status=ended&limit=50" \
  -H "Authorization: Bearer $POZY_API_KEY"
Filter Values
channel pstn (phone network) or whatsapp
direction inbound or outbound
status ringing, answered, ended or failed
number Calls involving one of your numbers
search Digits from either side of the call
limit Default 50, up to 200
before The nextCursor from the previous page. It is null on the last page.

List rows leave out the full transcript. lastTranscriptSnippet is a preview.

#Open one call

GET /v1/calls/{id} returns the full record for a call on either channel.

Response (trimmed)
{
  "call": {
    "_id": "66e5f6a7b8c9d0e1f2a3b4c5",
    "channel": "pstn",
    "direction": "inbound",
    "from": "+13125550188",
    "to": "+14155550142",
    "status": "ended",
    "endReason": "hangup",
    "durationSeconds": 184,
    "isVoicemail": false,
    "recordingEnabled": true,
    "transcriptionEnabled": true,
    "transcript": [
      { "text": "Hi, I am calling about order 1234.", "confidence": 0.96, "at": "2026-10-30T09:00:06Z" }
    ],
    "billing": { "billableCostUSD": 0.135, "currency": "USD" },
    "conversationId": "66c3d2ae7b4f6c8d0e1f2a3b"
  }
}
Field Meaning
endReason hangup, no_answer, rejected or error
hangupCause, sipHangupCause The raw carrier cause and SIP code behind endReason, for example to tell a busy line from a refused destination
isVoicemail The call was taken by voicemail
answeredMachine With answering-machine detection on, whether a machine picked up
callErrors Problems recorded during the call (failed bridge, recording error). The message text is for humans and may change, so do not parse it.
billing.billableCostUSD What Pozy bills for the call

#Get the recording

recordingUrl on a call record is signed and expires about 10 minutes after it is issued. For a fresh link, call GET /v1/calls/{id}/recording. By default it redirects (302) to a playable MP3. Add as=json to get { "url": "..." } instead.

Fresh recording link
curl "https://api.pozy.ai/v1/calls/66e5f6a7b8c9d0e1f2a3b4c5/recording?as=json" \
  -H "Authorization: Bearer $POZY_API_KEY"

Fetch the link when someone presses play rather than storing it. If you need to keep recordings, download the file and store it yourself.

#Turn recording and transcription on

Both are off by default. Set them on the number for every call, or per call when you dial out.

Where Fields
Every call on a number recordingEnabled, transcriptionEnabled, transcriptionLanguage on POST /v1/phone-numbers/{id}/voice
One outbound call recordOverride, transcribeOverride, transcriptionLanguage on POST /v1/voice/calls
One browser call recordOverride on POST /v1/voice/calls/web/dial

Recording never starts silently: on bridged calls a consent notice plays first. A recording exists only if recording was on when the call started. Voicemail messages are recorded whenever voicemail takes a call.

Note

Recording and transcription laws differ by country and state. Some places require every party to agree before a call is recorded. The consent notice helps, but you are responsible for using recordings lawfully.

#What it costs

Recording and transcription are billed per minute on top of the call. See the usage table on Phone numbers or Pricing.

#Get calls pushed instead of polling

call.ended carries the finished call (duration, end reason, cost, and a signed recordingUrl with recordingExpiresAt when recording was on). The transcript is not in the event: fetch the call record when you need it.

Event When it fires
call.ended Call ended.
call.failed Call failed.

#Errors

Status Cause Fix
404 The call does not exist for this key, or it has no recording Check recordingEnabled on the call. Recording must be on before the call starts.
502 The recording lookup failed Retry

#Endpoints

Endpoint What it does
GET /v1/calls List all calls (unified history)
GET /v1/calls/{id} Get a call (any channel)
GET /v1/calls/{id}/recording Get a call recording