Skip to main content
Plivo XML controls call behavior. Your answer_url returns XML instructions that Plivo executes. This page covers the essential elements for AI voice agents.

Response

The root element for all Plivo XML. Every response must be wrapped in <Response>.
<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <!-- Elements go here -->
</Response>

Stream

Stream real-time audio over WebSocket. See Audio Streaming XML for full details.
<Response>
    <Stream bidirectional="true" keepCallAlive="true">
        wss://yourserver.com/websocket
    </Stream>
</Response>
AttributeDefaultDescription
bidirectionalfalseEnable two-way audio
keepCallAlivefalseWait for stream to end before continuing
audioTrackinboundinbound, outbound, or both

Speak

Text-to-speech during calls. Useful for greetings or fallbacks.
<Response>
    <Speak voice="WOMAN" language="en-US">
        Hello, connecting you to our AI assistant.
    </Speak>
    <Stream bidirectional="true" keepCallAlive="true">
        wss://ai.example.com/agent
    </Stream>
</Response>
AttributeDefaultDescription
voiceWOMANWOMAN or MAN
languageen-USLanguage code (e.g., en-GB, es-ES)
loop1Number of times to repeat

Play

Play audio files (.mp3 or .wav).
<Response>
    <Play>https://example.com/welcome.mp3</Play>
    <Stream bidirectional="true" keepCallAlive="true">
        wss://ai.example.com/agent
    </Stream>
</Response>
AttributeDefaultDescription
loop1Number of times to repeat

Dial

Connect calls to another number, SIP endpoint, or user.
<Response>
    <Dial callerId="+14151234567" timeout="30">
        <Number>+14157654321</Number>
    </Dial>
</Response>
AttributeDefaultDescription
callerId-Caller ID to display
timeout30Ring timeout in seconds
action-URL to call when dial completes
methodPOSTHTTP method for action URL

Dial to SIP

<Response>
    <Dial>
        <Sip>sip:[email protected]</Sip>
    </Dial>
</Response>

Hangup

End the call.
<Response>
    <Speak>Thank you for calling. Goodbye.</Speak>
    <Hangup/>
</Response>
AttributeDescription
reasonOptional: rejected, busy
scheduleSeconds to wait before hanging up

Redirect

Fetch and execute XML from a different URL. Useful for dynamic call flows.
<Response>
    <Redirect method="POST">https://example.com/next-step</Redirect>
</Response>
AttributeDefaultDescription
methodPOSTGET or POST

Wait

Pause execution for a specified duration.
<Response>
    <Wait length="5"/>
    <Stream bidirectional="true" keepCallAlive="true">
        wss://ai.example.com/agent
    </Stream>
</Response>
AttributeDefaultDescription
length1Seconds to wait
silencefalseIf true, no hold music
beepfalsePlay beep after waiting

GetDigits

Collect DTMF input from the caller. Useful for IVR before connecting to AI.
<Response>
    <GetDigits action="https://example.com/handle-input" timeout="10" numDigits="1">
        <Speak>Press 1 for sales, 2 for support.</Speak>
    </GetDigits>
    <Speak>We didn't receive any input.</Speak>
</Response>
AttributeDefaultDescription
action-URL to send digits to
timeout5Seconds to wait for input
numDigits99Max digits to collect
finishOnKey#Key that ends input
retries1Number of retry attempts

Record

Record call audio. Useful for compliance or training.
<Response>
    <Speak>This call may be recorded.</Speak>
    <Record action="https://example.com/recording-done" maxLength="3600"/>
    <Stream bidirectional="true" keepCallAlive="true">
        wss://ai.example.com/agent
    </Stream>
</Response>
AttributeDefaultDescription
action-URL called when recording ends
maxLength60Max recording duration in seconds
fileFormatmp3mp3 or wav
transcriptionType-Set to auto for transcription

Common Patterns

AI Agent with Greeting

<Response>
    <Speak>Welcome to Acme Support. I'm connecting you with our AI assistant.</Speak>
    <Stream bidirectional="true" keepCallAlive="true" contentType="audio/x-l16;rate=16000">
        wss://ai.example.com/agent
    </Stream>
    <Speak>Thank you for calling. Goodbye.</Speak>
    <Hangup/>
</Response>

IVR Before AI Agent

<Response>
    <GetDigits action="https://example.com/route" timeout="10" numDigits="1">
        <Speak>Press 1 for AI assistant, 2 to speak with a human.</Speak>
    </GetDigits>
    <Redirect>https://example.com/default</Redirect>
</Response>

Transfer to Human

When your AI agent needs to transfer to a human:
<Response>
    <Speak>Connecting you to a human agent now.</Speak>
    <Dial callerId="+14151234567" timeout="60" action="https://example.com/dial-status">
        <Number>+14157654321</Number>
    </Dial>
    <Speak>We couldn't connect you. Please try again later.</Speak>
    <Hangup/>
</Response>