LiveKit docs › Prebuilt components › Prebuilt tasks › WarmTransferTask

---

# WarmTransferTask

> Execute an agent-assisted warm transfer with SIP dialing, hold music, and context handoff.

Available in (BETA):
- [ ] Node.js
- [x] Python

## Overview

Use `WarmTransferTask` to execute an agent-assisted warm transfer. The task automatically manages the complexities of the transfer workflow, including dialing the human agent, providing context, and merging the calls.

`WarmTransferTask` handles the following:

- Creating a separate room for the human agent.
- Dialing the human agent using SIP.
- Playing hold music to the caller while connecting.
- Providing the human agent with conversation history and context.
- Disabling I/O for the caller during the transfer process.
- Providing tools for the human agent to:- `connect_to_caller`: Connect the human agent to the original caller.
- `decline_transfer`: Decline the transfer with a reason.
- `voicemail_detected`: Handle voicemail detection.

The task returns a `WarmTransferResult` data class with one field: `human_agent_identity`.

- **[Agent-assisted warm transfer](https://docs.livekit.io/telephony/features/transfers/warm.md)**: A comprehensive guide to transferring calls using an AI agent to provide context.

### Usage

For a basic example, see the following code snippet:

```python
import os

from livekit.agents.beta.workflows import WarmTransferTask
from livekit.protocol.sip import SIPOutboundConfig

result = await WarmTransferTask(
    sip_call_to=<human-agent-phone-number>,         # Human agent's phone number
    sip_connection=SIPOutboundConfig(               # Inline trunk configuration
        hostname=os.getenv("SIP_TRUNK_HOSTNAME"),
        auth_username=os.getenv("SIP_AUTH_USERNAME"),
        auth_password=os.getenv("SIP_AUTH_PASSWORD"),
    ),
    chat_ctx=self.chat_ctx,                         # Conversation history
)

```

> ℹ️ **Stored outbound trunk**
> 
> You can also use a stored outbound trunk by passing `sip_trunk_id` instead of `sip_connection`. For details, see [Outbound trunk](https://docs.livekit.io/telephony/making-calls/outbound-trunk.md). You can set the trunk ID with the `LIVEKIT_SIP_OUTBOUND_TRUNK` environment variable.

### Parameters

For a full list of parameters, see the [WarmTransferTask reference](https://docs.livekit.io/reference/python/livekit/agents/beta/workflows/warm_transfer.html.md#livekit.agents.beta.workflows.warm_transfer.WarmTransferTask).

You can customize the behavior of `WarmTransferTask` by passing additional parameters:

- **`sip_call_to`** _(string)_: The phone number or SIP URI to dial for the warm transfer.

- **`sip_trunk_id`** _(string)_ (optional) - Environment: `LIVEKIT_SIP_OUTBOUND_TRUNK`: The outbound SIP trunk ID to use for dialing. Either `sip_trunk_id` or `sip_connection` is required. You can also set this with the `LIVEKIT_SIP_OUTBOUND_TRUNK` environment variable.

- **`sip_connection`** _(api.SIPOutboundConfig)_ (optional): [Inline trunk configuration](https://docs.livekit.io/telephony/making-calls/outbound-calls.md#inline-trunk). Pass trunk settings directly instead of using a stored trunk. You can specify a custom hostname, transport protocol, or authentication credentials.

Either `sip_connection` or `sip_trunk_id` is required.

- **`sip_number`** _(string)_ (optional) - Environment: `LIVEKIT_SIP_NUMBER`: The SIP "From" number to use as the caller ID. If empty, the trunk number is used. You can also set this with the `LIVEKIT_SIP_NUMBER` environment variable.

- **`sip_headers`** _(dict[str, str])_ (optional): Custom SIP headers included as-is in the outbound INVITE request. Use this to pass metadata that identifies the call to the remote SIP endpoint.

- **`dtmf`** _(str | None)_ (optional): DTMF tones to send after the human agent answers the call. Use this to dial an extension or navigate an interactive voice response (IVR) menu. Insert `w` characters to pause ~0.5 seconds each before or between digits. For example, `"wwww1234#"` waits ~2 seconds then dials extension 1234.

- **`ringing_timeout`** _(float | None)_ (optional): Seconds to wait for the human agent to answer before giving up. When the timeout elapses, the task completes with a `ToolError` and the caller conversation resumes.

- **`hold_audio`** _(AudioSource | AudioConfig | list | None)_ (optional) - Default: `BuiltinAudioClip.HOLD_MUSIC`: Audio to play while the caller is on hold. By default, plays `BuiltinAudioClip.HOLD_MUSIC`.

**Audio comparison** (audio-only, not available in text):

- [Default hold music](https://github.com/livekit/agents/blob/main/livekit-agents/livekit/agents/resources/hold_music.ogg)

- **`extra_instructions`** _(string)_ (optional): Additional instructions for the transfer agent. These instructions are passed to the transfer agent along with the conversation history and the default instructions.

- **`tools`** _(list)_ (optional): Additional tools that can be used in the execution of the transfer task. These tools can be used in place of, or in addition to, the default tools.

---

This document was rendered at 2026-06-07T11:35:26.594Z.
For the latest version of this document, see [https://docs.livekit.io/agents/prebuilt/tasks/warm-transfer.md](https://docs.livekit.io/agents/prebuilt/tasks/warm-transfer.md).

To explore all LiveKit documentation, see [llms.txt](https://docs.livekit.io/llms.txt).