> ## 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.

# Transfer to a Human Agent by SIP Auth Forward

> Transfer an AI-handled call to a SIP contact center, softphone, or PBX with credentials, including the firewall setup the contact center needs.

> [!NOTE]
>
> * **What:** Transfer a call from your AI agent to a SIP endpoint, such as your contact center, with `<Dial>` and `<User>`.
> * **Watch out:** A SIP transfer needs [two Plivo IP ranges whitelisted](#what-your-contact-center-must-do), not one.

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](#what-your-contact-center-must-do), which you can send them directly.

Most modern contact center software (Five9, Genesys, NICE, Talkdesk, custom WebRTC apps, etc.) accepts inbound SIP calls. When your AI agent decides to transfer, return this XML. Plivo calls the SIP address in `<User>`:

```xml theme={null}
<Response>
    <Speak>Connecting you to a human agent now.</Speak>
    <Dial>
        <User sipAuthUsername="<sip_username>" sipAuthPassword="<sip_password>">
            sip:agent@your-contact-center.example.com
        </User>
    </Dial>
</Response>
```

Give `<User>` a SIP URI with a hostname, as shown. Every example in the [Dial XML reference](/docs/voice/xml/routing/) uses this form.

## How a SIP Auth Forward Works

![SIP auth forward in five steps. 1: the caller is on a call with your AI agent. 2: your app returns Dial with User to Plivo. 3: Plivo calls the SIP address. 4: the human agent answers. 5: the caller now talks to the human agent.](https://mintcdn.com/plivo/9zIRdvx4doyoicBb/images/transfer-to-human-agent/sip-auth-forward-sequence-light.svg?fit=max\&auto=format\&n=9zIRdvx4doyoicBb\&q=85\&s=3de5794f50bd90bc0228b7739ea002a7)

* 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.

## Pass Call Context to the Human Agent

Your AI agent can't brief the human agent on this path, but it can send what it learned with the call. Add [`sipHeaders`](/docs/voice/xml/routing/) to `<User>` with the call's context, such as the reason for the transfer or an order number. Your contact center receives them on the incoming call and can show them to the human agent when it rings.

```xml theme={null}
<Response>
    <Dial>
        <User sipAuthUsername="<sip_username>" sipAuthPassword="<sip_password>"
              sipHeaders="Reason=refund,OrderId=1234">
            sip:agent@your-contact-center.example.com
        </User>
    </Dial>
</Response>
```

* Each header arrives prefixed with `X-PH-`, so `Reason=refund` arrives as `X-PH-Reason`. The [Dial reference](/docs/voice/xml/routing/) lists the one exception, for calls that came in over SIP authentication.
* Use only letters and digits in header names and values ([Pass Custom Headers](/docs/voice/use-cases/pass-custom-headers/)).
* Headers with reserved prefixes (`PH-`, `Plivo`, `FS-`, `SipAuth`, `ZT-`, `Twilio`) and the name `ClientRegion` are silently dropped. See [SIP Authentication](/docs/voice/concepts/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 the call's context in SIP headers](#pass-call-context-to-the-human-agent), 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** - its firewall opened to Plivo for call setup and audio, and digest credentials if it uses them. Work you cannot do yourself, often behind a change-control queue you do not control
* **No warm transfer** - your AI agent can't brief the human agent before the caller is connected, though it can [pass the call's context in SIP headers](#pass-call-context-to-the-human-agent). For a spoken briefing, use [Option 3: Multiparty Call](/docs/voice/use-cases/transfer-to-human-agent/multiparty-call/)
* **Subtler failure modes** - most of the [Troubleshooting](/docs/voice/use-cases/transfer-to-human-agent/troubleshooting/#troubleshooting) table is specific to this path

## Set Up a SIP Auth Forward

**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 traffic by IP address, it has to whitelist Plivo for both call setup and audio first. Send them [What Your Contact Center Must Do](#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`).

***

## If Your Call Is on a Live Audio Stream

This applies when your AI agent runs over [audio streaming](/docs/voice/xml/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](/docs/voice/xml/audio-streaming/). Your transfer XML is subsequent XML, so it does not run while the stream is still open. If the WebSocket never closes, the transfer never runs.

> [!WARNING]
>
> 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.

![When your AI agent closes its WebSocket. Too early: the call ends; fix by adding Wait right after Stream. On time: the transfer works. Stays open: the transfer never runs; fix by closing the WebSocket when you transfer, or use Option 3.](https://mintcdn.com/plivo/9zIRdvx4doyoicBb/images/transfer-to-human-agent/websocket-close-window-light.svg?fit=max\&auto=format\&n=9zIRdvx4doyoicBb\&q=85\&s=4146a9d4b85d1ce4c46c8e9e2fc29f59)

Add a `<Wait>` right after `<Stream>` in your answer XML. If your AI agent closes its WebSocket before your transfer arrives, the call waits for it instead of ending:

```xml theme={null}
<Response>
    <Stream bidirectional="true" keepCallAlive="true">wss://your-ai-agent.example.com/stream</Stream>
    <Wait length="30"/>
</Response>
```

Set `length` to cover the time between your AI agent closing its WebSocket and your server calling [Transfer a Call](/docs/voice/api/calls/#transfer-a-call). See the [Wait](/docs/voice/xml/routing/#wait) reference for its attributes.

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.

If transfers still drop the call or never run, use [Option 3: Multiparty Call](/docs/voice/use-cases/transfer-to-human-agent/multiparty-call/) instead. In a Multiparty Call, the caller's call doesn't run `<Stream>`, so nothing waits for the WebSocket to close.

***

## 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](/docs/voice/api/calls/#transfer-a-call), which points a live call leg at a new URL. That URL returns the same `<Dial>` XML shown above. For SIP auth forward, include `sipAuthUsername` and `sipAuthPassword` on `<User>`. For a warm transfer, where your AI agent briefs the human agent before the caller is connected, use [Option 3: Multiparty Call](/docs/voice/use-cases/transfer-to-human-agent/multiparty-call/#warm-transfer-with-a-multiparty-call).

***

## What Your Contact Center Must Do

Send this list to whoever runs your contact center. Their system must:

* Whitelist Plivo's [External SIP endpoints](/docs/voice/concepts/firewall-network-configuration/#external-sip-endpoints) for call setup and [RTP media servers](/docs/voice/concepts/firewall-network-configuration/#rtp-media-servers) for audio, if its firewall filters by IP address. Credentials don't replace this: they get the call accepted, but the audio still has to reach the contact center
* Issue the SIP credentials you put in `sipAuthUsername` and `sipAuthPassword`, if it authenticates inbound calls
* Advertise a **public** IP address in its `Contact` header and SDP
* Offer **PCMU or PCMA**
* Whitelist Plivo without pinning the rule to a source port

If it can't whitelist Plivo, transfer to one of its phone numbers with [Option 1: DID forward](/docs/voice/use-cases/transfer-to-human-agent/did-forward/). What breaks when an item is missing is on the [Troubleshooting](/docs/voice/use-cases/transfer-to-human-agent/troubleshooting/#troubleshooting) page.

***

## Related

* [Transfer to Human Agent](/docs/voice/use-cases/transfer-to-human-agent/) — When to transfer, and how to choose an option
* [Option 1: DID Forward](/docs/voice/use-cases/transfer-to-human-agent/did-forward/) — Transfer to a phone number
* [Option 3: Multiparty Call](/docs/voice/use-cases/transfer-to-human-agent/multiparty-call/) — Cold or warm transfer in a Multiparty Call
* [Troubleshoot Transfer to Human Agent](/docs/voice/use-cases/transfer-to-human-agent/troubleshooting/) — Test a transfer and fix failed ones
* [SIP Authentication](/docs/voice/concepts/sip-authentication/) — How outbound SIP auth works
* [Firewall and Network Configuration](/docs/voice/concepts/firewall-network-configuration/) — Plivo IPs to whitelist
