This page covers the essential APIs for building AI voice agents: initiating calls, handling incoming calls, and streaming audio.
Calls API Essentials
Audio streaming requires an active call. Use the Calls API to initiate outbound calls or configure incoming call handling.
Make an Outbound Call
POST https://api.plivo.com/v1/Account/{auth_id}/Call/
Parameter Required Description fromYes Caller ID (your Plivo number) in E.164 format toYes Destination number in E.164 format answer_urlYes URL returning XML when call is answered answer_methodNo GET or POST (default: POST)
import plivo
client = plivo.RestClient( '<auth_id>' , '<auth_token>' )
response = client.calls.create(
from_ = '+14151234567' ,
to_ = '+14157654321' ,
answer_url = 'https://yourserver.com/answer' ,
answer_method = 'POST'
)
print (response)
Your answer_url should return XML with the <Stream> element to start audio streaming:
<? xml version = "1.0" encoding = "UTF-8" ?>
< Response >
< Stream bidirectional = "true" keepCallAlive = "true" >
wss://yourserver.com/websocket
</ Stream >
</ Response >
Handle Incoming Calls
Configure your Plivo phone number’s Answer URL in the console to point to your server. When a call arrives, Plivo sends a POST request with:
Parameter Description CallUUIDUnique call identifier FromCaller’s phone number ToYour Plivo number Directioninbound
Your server returns XML to start the audio stream.
Hang Up a Call
DELETE https://api.plivo.com/v1/Account/{auth_id}/Call/{call_uuid}/
client.calls.delete( call_uuid = 'call-uuid-here' )
Transfer a Call
Redirect an active call to fetch new XML (e.g., to change behavior mid-call):
POST https://api.plivo.com/v1/Account/{auth_id}/Call/{call_uuid}/
Parameter Description legsWhich leg to transfer: aleg, bleg, both aleg_urlURL to fetch new XML for A leg
client.calls.transfer(
call_uuid = 'call-uuid-here' ,
legs = 'aleg' ,
aleg_url = 'https://yourserver.com/new-flow'
)
For the complete Calls API reference, see Voice API - Calls .
Audio Streams API
The Audio Streams API lets you receive raw audio from active calls over a WebSocket connection in near real-time. Use it for real-time transcription, voice AI, call analytics, or custom audio processing.
API Endpoint
https://api.plivo.com/v1/Account/{auth_id}/Call/{call_uuid}/Stream/
The Audio Stream Object
Attribute Type Description stream_idstring Unique identifier for the audio stream call_uuidstring UUID of the call being streamed service_urlstring WebSocket URL receiving the stream bidirectionalboolean Whether stream supports two-way audio audio_trackstring Audio direction: inbound, outbound, both content_typestring Audio codec and sample rate start_timestring When streaming started end_timestring When streaming ended bill_durationinteger Streaming duration in seconds billed_amountstring Cost in USD
Example Response
{
"api_id" : "f7615566-13c5-11ee-b552-0242ac110005" ,
"stream_id" : "20170ada-f610-433b-8758-c02a2aab3662" ,
"call_uuid" : "78737f83-4660-490d-98e1-025dfe4b5c8f" ,
"service_url" : "wss://mysocket.com/wss/v2/1/demo/" ,
"audio_track" : "both" ,
"bidirectional" : false ,
"content_type" : "audio/x-l16;rate=8000" ,
"start_time" : "2023-06-21 18:53:16+05:30" ,
"end_time" : "2023-06-21 18:53:43+05:30" ,
"bill_duration" : 27 ,
"billed_amount" : "0.00300" ,
"rounded_bill_duration" : 60
}
Start an Audio Stream
Initiate streaming for an active call.
POST https://api.plivo.com/v1/Account/{auth_id}/Call/{call_uuid}/Stream/
Parameters
Parameter Type Required Description service_urlstring Yes WebSocket URL (wss://) to receive audio bidirectionalboolean No Enable two-way audio. Default: false audio_trackstring No Track to stream: inbound, outbound, both. Default: inbound stream_timeoutinteger No Max duration in seconds. Default: 86400 (24 hours) content_typestring No Audio format. Default: audio/x-l16;rate=8000 status_callback_urlstring No URL for stream status events status_callback_methodstring No GET or POST. Default: POSTextra_headersstring No Custom headers: key1=val1,key2=val2
Content Type Description audio/x-l16;rate=8000Linear PCM, 8kHz (default) audio/x-l16;rate=16000Linear PCM, 16kHz audio/x-mulaw;rate=8000G.711 mu-law, 8kHz
When bidirectional is true, audio_track cannot be outbound or both.
Python
Node.js
Ruby
PHP
Java
.NET
Go
cURL
import plivo
client = plivo.RestClient( '<auth_id>' , '<auth_token>' )
response = client.calls.create_stream(
'call_uuid_here' ,
service_url = 'wss://yourserver.example.com/audiostream' ,
bidirectional = False ,
audio_track = 'both' ,
stream_timeout = 3600 ,
content_type = 'audio/x-l16;rate=16000'
)
print (response)
Retrieve an Audio Stream
Get details of a specific audio stream.
GET https://api.plivo.com/v1/Account/{auth_id}/Call/{call_uuid}/Stream/{stream_id}/
response = client.calls.get_stream( 'call_uuid' , 'stream_id' )
List All Audio Streams
Get all audio streams for a call.
GET https://api.plivo.com/v1/Account/{auth_id}/Call/{call_uuid}/Stream/
response = client.calls.get_all_streams( 'call_uuid' )
Response
{
"api_id" : "87399872-13cb-11ee-9da1-0242ac110003" ,
"meta" : {
"limit" : 20 ,
"offset" : 0 ,
"total_count" : 1
},
"objects" : [
{
"stream_id" : "4543157e-60d3-4c3a-b9d8-189c47686bf0" ,
"call_uuid" : "816e0b22-6913-4b43-88a9-6d3054b77df9" ,
"service_url" : "wss://example.com/stream" ,
"audio_track" : "both" ,
"bidirectional" : false ,
"start_time" : "2023-06-26 08:14:29+05:30" ,
"end_time" : "2023-06-26 08:14:50+05:30"
}
]
}
Stop a Specific Audio Stream
Stop streaming for a specific stream.
DELETE https://api.plivo.com/v1/Account/{auth_id}/Call/{call_uuid}/Stream/{stream_id}/
client.calls.delete_specific_stream( 'call_uuid' , 'stream_id' )
Response: HTTP 204 No Content
Stop All Audio Streams
Stop all active streams on a call.
DELETE https://api.plivo.com/v1/Account/{auth_id}/Call/{call_uuid}/Stream/
client.calls.delete_all_streams( 'call_uuid' )
Bidirectional Streaming
When bidirectional=true, your WebSocket server can send audio back to the call.
Sending Audio to Call
Send a JSON message to the WebSocket:
{
"event" : "playAudio" ,
"media" : {
"contentType" : "audio/x-l16" ,
"sampleRate" : "8000" ,
"payload" : "<base64-encoded-audio>"
}
}
Field Values contentTypeaudio/x-l16, audio/x-mulawsampleRate8000, 16000payloadBase64-encoded raw audio
Status Callback Events
Notifications sent to status_callback_url:
Event Description Stream connected Audio streaming has started Stream stopped Streaming stopped intentionally Stream timeout stream_timeout duration reachedStream failed Connection failed or dropped