Skip to main content
  • What: Hand a live call from your AI agent to a human — over a phone number, or over SIP to your contact center.
  • Watch out: A SIP transfer needs two Plivo IP ranges whitelisted, not one.
When your AI agent hits an escalation, a query it can’t handle, or a fallback, return <Dial> XML and Plivo bridges the caller to a human agent. You have two ways to do it. You’ll do most of this in your own application. The firewall and SIP settings at the far end aren’t yours to change — they belong to whoever runs your contact center. Those are collected in What Your Contact Center Must Do, which you can send them directly.

Two Options


How It Works

1

AI agent decides to transfer

Your AI agent (Pipecat, LiveKit, etc.) detects an escalation trigger (caller asks for a human, intent unclear, etc.) and signals a transfer.
2

Your server returns transfer XML

Your application returns a <Dial> XML response that routes the call to either a phone number or a SIP endpoint.
3

Plivo places the outbound leg

Plivo dials the destination. For SIP transfers, the INVITE is sent from Plivo’s External SIP endpoint addresses, and Plivo handles authentication with the agent’s SIP infrastructure if credentials are provided.
4

Conversation continues with human

Plivo bridges the caller to the human agent and drops your AI agent’s leg. The caller stays on the same call throughout — there is no redial and no second ring.

If Your Call Is on a Live Audio Stream

This applies when your AI agent runs over audio streaming and the call is on a <Stream> with keepCallAlive="true". With keepCallAlive="true", the <Stream> element runs exclusively and subsequent XML executes only after the stream disconnects. Your transfer XML is subsequent XML, so it does not run while the stream is still open.
Close your bot’s WebSocket when you decide to transfer. Keep keepCallAlive="true" — closing the socket is what lets the call continue to your transfer XML, not removing the attribute.
If you stop the stream through the API rather than closing the socket, trigger the transfer first, then send DELETE /v1/Account/{auth_id}/Call/{call_uuid}/Stream/. Stopping the stream first lets the leg continue to the end of the XML document it is already running, which can end the call instead of transferring it. streamTimeout defaults to 86400 seconds. Set it to a realistic ceiling for your call shape so a stream that never closes cannot hold a call open.

Option 1: DID Forward

The simplest transfer. Dial a regular phone number using the <Number> element in your Dial XML.

How It Works

  • Plivo originates an outbound call from your AI agent’s leg to the human agent’s phone number
  • When the human agent answers, the two legs are bridged
  • The caller and the human agent are connected, and your AI agent leaves the call

Trade-offs of a DID forward

Pros
  • Works with any phone - mobile, landline, or a softphone with a DID
  • Simple to set up - needs nothing from your network team
Cons
  • Outbound call cost - billed for the full duration of the transferred call
  • Agents need a real phone number
  • Less flexibility - no custom SIP headers, no routing to specific agent IDs or queues
A DID forward is also the fastest way to prove a transfer problem is not your application. If a transfer to a phone number connects but a SIP transfer to the same team doesn’t, the fault is on the SIP path — the firewall or the credentials — not in your XML.

Most modern contact center software (Five9, Genesys, NICE, Talkdesk, custom WebRTC apps, etc.) accepts inbound SIP calls. Transfer the call directly over SIP using the <User> element.
Give <User> a SIP URI with a hostname, as shown. Every example in the Dial XML reference uses this form.

How It Works

  • Plivo sends an initial SIP INVITE to your contact center’s SIP endpoint without credentials
  • If the contact center responds with 401 Unauthorized or 407 Proxy Authentication Required, the outbound SBC re-sends the INVITE with the supplied sipAuthUsername / sipAuthPassword
  • Contact center validates credentials; call connects
  • Caller and agent are bridged
sipAuthPassword is 8-128 characters, and is required whenever sipAuthUsername is set.
When passing agent IDs, queue IDs, or call context via sipHeaders, be aware that headers with reserved prefixes (PH-, Plivo, FS-, SipAuth, ZT-, Twilio) and the name ClientRegion are silently dropped. See SIP Authentication for the full list.

Trade-offs of a SIP auth forward

Pros
  • Lower cost - single SIP termination charge, no PSTN minutes
  • Lower latency - direct SIP, no PSTN intermediary
  • More flexibility - pass custom SIP headers, route to specific agent IDs or queues
  • Better for AI workflows - agents are typically already on softphones or contact center software
Cons
  • Needs your contact center’s cooperation - digest credentials, or its firewall opened to Plivo. Work you cannot do yourself, often behind a change-control queue you do not control
  • Subtler failure modes - most of the Troubleshooting table below is specific to this path

Setup

1

Get your contact center's SIP endpoint

Find the SIP URI provided by your contact center software (e.g., sip:queue-1@your-cc.example.com). Most platforms expose this in their admin dashboard.
2

Get authentication credentials

Most SIP-based contact center software requires digest authentication. Get the username and password from your contact center setup.
3

Open the firewall at your contact center

If your contact center filters inbound SIP by IP address, it has to whitelist Plivo first. Send them What Your Contact Center Must Do — this is the one part you cannot do yourself.
4

Update your AI agent's transfer logic

When your agent decides to transfer, return a <Dial> XML response with the <User> element. Set sipAuthUsername and sipAuthPassword to the credentials from Step 2. Point the SIP URI to your contact center endpoint.
5

Test

Trigger a transfer from your AI agent and confirm three things: the human agent’s phone rings, both sides can hear each other, and your Dial action URL receives DialStatus=completed. If authentication fails, the call ends with hangup cause sip_auth_failed (code 4240).

Server-Initiated Handoff

Instead of waiting for your answer URL to return Dial XML, you can trigger the transfer programmatically with the Transfer a Call API, which points a live call leg at a new URL. That URL returns the same <Dial> XML shown above, including sipAuthUsername and sipAuthPassword on <User>. This is useful for warm transfers where the agent application needs to consult before connecting the caller.

Test Your Transfer

1

Transfer to a phone number first

Point a test transfer at a phone number that reaches the same team. If this connects, your XML, your application, and your Plivo account are all working — which narrows any later failure to the SIP path.
2

Transfer to the SIP endpoint

Run the same transfer against your SIP endpoint. A failure here, after the phone number transfer succeeded, points at the firewall or the SIP credentials rather than at your agent logic.
3

Check audio in both directions

Speak from each end. Audio in one direction only means the RTP media ranges are whitelisted in one direction only.
4

Confirm your application reads DialStatus

Your Dial action URL should receive DialStatus and DialHangupCause, so your application can fall back or inform the caller when a handoff fails.

What Your Contact Center Must Do

Everything above happens in your own application. This section does not — it is work for whoever runs your contact center or PBX, which is often a different company. Send them this section.

Whitelist Plivo’s IP addresses

If your contact center restricts inbound SIP traffic by IP, it has to whitelist Plivo before a transfer can reach your agents.
If Plivo’s IPs are not whitelisted, the transfer fails at the network level before your contact center even sees the call. Nothing appears in its logs, because the call never arrived.
A SIP call runs over two separate connections, and they come from different Plivo IP ranges. Whitelist both — whitelisting one without the other leaves the call broken. The External SIP endpoint addresses are not inside any RTP media range. Whitelisting only the media server IPs leaves call setup blocked: the INVITE is dropped at the firewall, the contact center never sees the call, and the transfer fails with no trace on either side. Three more things to get right:
  • Whitelist the IPs in the region closest to your contact center deployment. If your contact center has agents distributed globally, whitelist all relevant regions.
  • If your Plivo account is in the India region, open the India tab under External SIP endpoints for call setup, and whitelist the Mumbai, India row under RTP media servers for audio.
  • The complete address lists by region (San Jose, Ashburn, Frankfurt, Sao Paulo, Sydney, Singapore, Mumbai) are in Firewall and Network Configuration.

Other settings that must be right

If they can’t whitelist by IP

Not every platform can whitelist by IP. Two alternatives, in order of preference:

Hangup Causes and Dial Status

When a transfer fails, the Dial action URL and hangup callback include specific values: Your agent application receives DialStatus and DialHangupCause on the Dial action URL, so it can detect a failed handoff and respond (e.g., retry with a different endpoint, fall back to a phone number, or inform the caller). Every hangup code is listed in Hangup Causes.

Troubleshooting


Full API Reference