Phone, SMS & voice

AI voice agents

Have an AI voice agent answer your number or take outbound calls, either a hosted agent over SIP or your own speech pipeline over a WebSocket.

An AI voice agent is a forward destination like any other. Point a number at it and the agent answers every inbound call. Pass it as forwardTo on one outbound call and the agent talks to whoever picks up. Pozy owns the phone side: the number, the carrier leg, routing, recording and the call history. The agent owns the conversation.

#Pick a shape

Hosted agent over SIP Your own agent over WebSocket
Destination sip:<user>@<host> wss://your-server.example.com/media
Where the prompt, voice and tools live In the agent platform you use In your own code: speech-to-text, an LLM, text-to-speech
What you build Nothing on the phone side A WebSocket server that reads and writes call audio
Agent can place its own calls Use a SIP trunk Start calls with POST /v1/voice/calls

Either way there is no second phone leg, so you pay only for the call itself.

#Point a number at the agent

curl -X POST https://api.pozy.ai/v1/phone-numbers/6650d2e1b3c4d5e6f7081923/voice \
  -H "Authorization: Bearer $POZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "forwardTo": "wss://agent.acme.example.com/media", "transcriptionEnabled": true }'

A hosted agent works the same way with a sip: address in forwardTo. Many hosted platforms identify the number from the SIP user part: keep the number in E.164 with the leading +, written the same way on both sides. A + missing on one side is the usual reason a call connects and drops at once.

The agent sits inside the normal inbound flow, so the blocklist, business hours, an IVR option that sends one digit to the agent, and voicemail all still apply. See Voice calls.

#Hand one outbound call to an agent

Pass the agent as the per-call destination. The number's inbound setting stays as it is.

Agent-led outbound call
curl -X POST https://api.pozy.ai/v1/voice/calls \
  -H "Authorization: Bearer $POZY_API_KEY" \
  -H "Idempotency-Key: reminder-appt-7781" \
  -H "Content-Type: application/json" \
  -d '{
    "fromNumber": "+14155550142",
    "to": "+13125550188",
    "forwardTo": "wss://agent.acme.example.com/media",
    "amd": true,
    "voicemailDropMessage": "Hi, this is Acme confirming your appointment tomorrow at 10. Call us back if you need to change it."
  }'

With amd: true, the agent is only bridged in when a person answers. An answering machine gets the voicemailDropMessage instead.

#Build your own agent over WebSocket

When the destination is wss://, the call's audio streams to your server as soon as the call is answered, and audio you send back is played to the caller. Pozy does not re-encode the audio.

Setting Value
Audio you receive The caller's side of the call
Codec, both directions PCMU (G.711 u-law), 8 kHz
Framing JSON text frames with an event field (start, media, stop, error). Audio travels base64-encoded in media.payload.
Speaking back Write media frames with base64 PCMU on the same socket
Ending Closing the socket ends the call

These settings are fixed today, so build the pipeline around 8 kHz PCMU.

A typical loop:

  1. Accept the WebSocket and wait for start.
  2. Feed media payloads to speech-to-text.
  3. Send each finished user turn to your LLM with the system prompt and tools.
  4. Turn the reply into speech, encode it as PCMU at 8 kHz, and write it back as media frames.
  5. On stop, or when the conversation is done, close the socket.

#Give the agent tools

Your agent's backend holds the Pozy API key, so Pozy endpoints make good agent tools. Match the call to its Pozy id with the call.received webhook, which fires as an inbound call starts and carries call.id, from, to and conversationId. For outbound calls, keep the callId from the create response.

Tool Endpoint
Hand the caller to a person POST /v1/voice/calls/{id}/transfer with a tel: or sip: destination. Do this before you close the socket.
Hang up POST /v1/voice/calls/{id}/end
Text a link or a summary POST /v1/sms/messages from the number that was called
Reply in the inbox thread The inbox send endpoints with the conversationId from call.received
Look up or save the caller The contacts endpoints
Tip

The same media bridge serves WhatsApp calls. An agent you build once can answer both channels.

#Capture the conversation

Turn on recordingEnabled and transcriptionEnabled on the number when you want Pozy to keep its own copy of the call. The recording and transcript attach to the call record after hangup. See Call recordings.

#When it does not connect

Symptom Likely cause What to check
Caller hears voicemail right after answering The WebSocket handshake failed The wss:// URL, TLS certificate, and that your server accepts the connection. Read callErrors on the call.
Call connects then drops at once (SIP) The number format differs between Pozy and the agent platform Use the same E.164 with + on both sides
409 invalid_resource_state on the voice settings The number is attached to a SIP trunk Detach it, or configure the agent on the trunk side

If the stream cannot be set up, an already-answered caller falls to voicemail when it is on. Otherwise the call ends.

#Endpoints

Endpoint What it does
POST /v1/phone-numbers/{id}/voice Enable phone calling on a number
POST /v1/voice/calls Place an outbound phone call
POST /v1/voice/calls/{id}/transfer Blind-transfer a live call
POST /v1/voice/calls/{id}/end Hang up a live call
GET /v1/calls/{id} Get a call (any channel)

#Webhook events

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