> ## 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 DID Forward

> Transfer an AI-handled call to a human agent's phone number with Dial XML and the Number element.

> [!NOTE]
>
> * **What:** Transfer a call from your AI agent to a human agent's phone number with `<Dial>` and `<Number>`.
> * **Watch out:** On a `<Stream>` with `keepCallAlive="true"`, [close your WebSocket](#if-your-call-is-on-a-live-audio-stream) when you transfer.

The simplest transfer. When your AI agent decides to transfer, return this XML. Plivo dials the phone number in `<Number>`:

```xml theme={null}
<Response>
    <Speak>Connecting you to a human agent now.</Speak>
    <Dial>
        <Number>+14155551234</Number>
    </Dial>
</Response>
```

## How a DID Forward Works

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

* 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
* **No warm transfer** - your AI agent can't brief the human agent before the caller is connected. For that, use [Option 3: Multiparty Call](/docs/voice/use-cases/transfer-to-human-agent/multiparty-call/)

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

***

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

***

## Related

* [Transfer to Human Agent](/docs/voice/use-cases/transfer-to-human-agent/) — When to transfer, and how to choose an option
* [Option 2: SIP Auth Forward](/docs/voice/use-cases/transfer-to-human-agent/sip-auth-forward/) — Transfer to a SIP endpoint with credentials
* [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
* [Dial XML](/docs/voice/xml/routing/) — Complete reference for `<Dial>` and `<Number>`
