Documentation Index Fetch the complete documentation index at: https://plivo.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
Plivo XML is a set of instructions you use to tell Plivo what to do when you receive an incoming call or make an outbound call. When someone calls your Plivo phone number, Plivo looks up the URL associated with that phone number and makes a request to that URL. Your web application returns an XML document with instructions on how to handle the call.
How XML Works
Incoming Calls
Someone calls your Plivo phone number
Plivo sends a request to your Answer URL
Your server returns Plivo XML instructions
Plivo executes the instructions (speak, play, dial, etc.)
Caller → Plivo → Your Server (Answer URL) → XML Response → Plivo executes
Outbound Calls
You trigger an outbound call via the API with an answer_url
When the call is answered, Plivo fetches XML from your answer_url
Plivo executes the instructions
Your App → Plivo API → Call Recipient → XML from answer_url → Execute
Basic Structure
Every Plivo XML document starts with a <Response> element containing one or more instruction elements:
< Response >
< Speak > Hello! Welcome to our service. </ Speak >
< Play > https://example.com/audio/menu.mp3 </ Play >
</ Response >
Elements are executed in order. When one element completes, the next begins.
Multiple Elements
< Response >
< Speak > Please hold while we connect you. </ Speak >
< Play > https://example.com/hold-music.mp3 </ Play >
< Dial >
< Number > +14155551234 </ Number >
</ Dial >
< Speak > Sorry, no one is available. Goodbye. </ Speak >
< Hangup />
</ Response >
Execution flow:
Speak the message
Play the audio file
Dial the number
If dial fails, speak the fallback message
Hang up
Generating XML with SDKs
Python
Node.js
Ruby
PHP
Java
.NET
Go
from plivo import plivoxml
response = plivoxml.ResponseElement()
response.add(plivoxml.SpeakElement( 'Hello, world!' ))
response.add(plivoxml.HangupElement())
xml_string = response.to_string()
Available XML Elements
Audio Output
Element Description Speak Convert text to speech Play Play an audio file DTMF Send DTMF tones
Element Description GetDigits Collect DTMF digit input GetInput Collect speech or digit input
Call Routing
Element Description Dial Connect to another number or SIP endpoint Redirect Transfer call flow to another URL Hangup End the call Wait Pause execution
Conferencing
Element Description Conference Connect caller to a conference room MultiPartyCall Advanced multi-party conferencing
Recording
Element Description Record Record the call or a message
Advanced
Element Description PreAnswer Play media before answering Stream Stream real-time audio via WebSocket
Nesting Elements
Some elements can be nested inside others:
< Response >
< GetDigits action = "/handle-input/" numDigits = "1" >
< Speak > Press 1 for sales, 2 for support. </ Speak >
</ GetDigits >
< Speak > We didn't receive any input. Goodbye. </ Speak >
</ Response >
Nesting Rules
Parent Element Allowed Children Response All elements GetDigits Speak, Play GetInput Speak, Play Dial Number, User PreAnswer Speak, Play, Wait
Request Parameters
When Plivo requests your XML endpoint, it includes these parameters:
Voice Call Parameters
Parameter Description CallUUIDUnique identifier for this call FromCaller’s phone number (with country code) ToCalled phone number (with country code) CallStatusCall status: ringing, in-progress, completed Directioninbound or outbound
Inbound vs Outbound
Inbound calls:
From = Caller’s number
To = Your Plivo number
Direction = inbound
Outbound calls (via API):
From = Caller ID you specified
To = Destination number
Direction = outbound
Outbound Call Parameters
Parameter Description ALegUUIDUUID of the first call leg ALegRequestUUIDRequest UUID returned by API
Call Forwarding
Parameter Description ForwardedFromOriginal number (if call was forwarded). Carrier-dependent
Completed Call Parameters
Parameter Description HangupCauseStandard telephony hangup cause DurationCall duration in seconds BillDurationBilled duration in seconds TotalCostTotal cost of the call
Call Status Values
Status Description ringingCall is ringing (inbound, not yet answered) in-progressCall is active completedCall ended normally busyCalled party was busy (outbound only) failedCall failed to connect (outbound only) timeoutNo answer within timeout (outbound only) no-answerCalled party didn’t answer (outbound only)
For SIP calls, custom SIP headers are included with the X-PH- prefix:
Header Format Description X-PH-<HeaderName>Custom SIP header value
Example: If you send sipHeaders="CustomId=123", the request includes X-PH-CustomId=123.
Response Requirements
Your server must return:
Valid XML document
Content-Type: application/xml or text/xml
Maximum size: 100 KB
Framework Examples
# Flask
from flask import Response
return Response(xml_string, mimetype = 'application/xml' )
// Express
res . set ( 'Content-Type' , 'application/xml' );
res . send ( xmlString );
# Sinatra
content_type 'application/xml'
xml_string
// PHP
header ( 'Content-Type: application/xml' );
echo $xml_string ;
Empty Response
An empty <Response> element hangs up the call:
Example: Using Request Parameters
from flask import Flask, request, Response
from plivo import plivoxml
app = Flask( __name__ )
@app.route ( '/answer/' , methods = [ 'GET' , 'POST' ])
def answer ():
call_uuid = request.values.get( 'CallUUID' )
caller = request.values.get( 'From' )
called = request.values.get( 'To' )
direction = request.values.get( 'Direction' )
response = plivoxml.ResponseElement()
if direction == 'inbound' :
# Log the incoming call
print ( f "Incoming call from { caller } to { called } , UUID: { call_uuid } " )
# Custom greeting based on caller ID
if is_vip_customer(caller):
response.add(plivoxml.SpeakElement( 'Welcome back, valued customer!' ))
else :
response.add(plivoxml.SpeakElement( 'Thank you for calling.' ))
else :
response.add(plivoxml.SpeakElement( 'Connecting your call.' ))
return Response(response.to_string(), mimetype = 'application/xml' )
Example: Simple IVR
< Response >
< GetDigits action = "/ivr-response/" numDigits = "1" timeout = "10" >
< Speak >
Welcome to Acme Corp.
Press 1 for sales.
Press 2 for support.
Press 3 to hear our hours.
</ Speak >
</ GetDigits >
< Speak > Sorry, we didn't receive any input. Goodbye. </ Speak >
< Hangup />
</ Response >
Example: Forward Call
< Response >
< Dial callerId = "+14155551234" >
< Number > +14155559876 </ Number >
</ Dial >
</ Response >
Hangup Causes
Common hangup cause values:
Cause Description NORMAL_CLEARINGNormal call termination USER_BUSYCalled party busy NO_ANSWERNo answer within timeout CALL_REJECTEDCall was rejected UNALLOCATED_NUMBERInvalid number NETWORK_OUT_OF_ORDERNetwork issues
Best Practices
Always return valid XML - Malformed XML will cause call failures
Use HTTPS - All callback URLs should use HTTPS
Handle timeouts - Include fallback behavior for user input
Test thoroughly - Use ngrok for local development testing
Log callback data - Store request parameters for debugging
Return quickly - Plivo has a 15-second timeout for XML responses
Error Handling
If your server returns invalid XML:
The call may hang up unexpectedly
Plivo logs the error in your console
Common issues:
Malformed XML (unclosed tags)
Wrong content type
Empty response
Response too large