> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.vapi.ai/llms.txt.
> For full documentation content, see https://docs.vapi.ai/llms-full.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.vapi.ai/_mcp/server.

# Call Forwarding

Vapi's call forwarding functionality allows you to redirect calls to different phone numbers based on specific conditions using tools. This guide explains how to set up and use the `transferCall` function for call forwarding.

## Key Concepts

### Call Forwarding Tools

* **`transferCall` Tool**: This tool enables call forwarding to predefined phone numbers with specific messages based on the destination.

Looking for dynamic routing decided at runtime? Use a `transferCall` tool with an empty `destinations` array and either:

* Have the assistant supply a destination parameter (e.g., `phoneNumber`) directly; no webhook is sent.
* Or respond from your server to the `transfer-destination-request` webhook with a destination.
  See: <a href="/calls/call-dynamic-transfers">Dynamic call transfers</a>.

### Parameters and Messages

* **Destinations**: A list of phone numbers where the call can be forwarded.
* **Messages**: Custom messages that inform the caller about the call being forwarded.

## Setting Up Call Forwarding

### 1. Create a Transfer Call Tool in the Dashboard

The recommended approach is to create your transfer call tool in the Vapi dashboard:

1. Navigate to **Tools** in your Vapi dashboard
2. Click **Create Tool**
3. Select **Transfer Call** as the tool type
4. Configure your destinations:
   * **Department A**: `+1234567890` with message "I am forwarding your call to Department A. Please stay on the line."
   * **Department B**: `+0987654321` with message "I am forwarding your call to Department B. Please stay on the line."
   * **Department C**: `+1122334455` with message "I am forwarding your call to Department C. Please stay on the line."

### 2. Alternative: API Configuration

You can also define the tool via API with destinations and corresponding messages:

```json
{
  "tools": [
    {
      "type": "transferCall",
      "destinations": [
        {
          "type": "number",
          "number": "+1234567890",
          "message": "I am forwarding your call to Department A. Please stay on the line."
        },
        {
          "type": "number",
          "number": "+0987654321",
          "message": "I am forwarding your call to Department B. Please stay on the line."
        },
        {
          "type": "number",
          "number": "+1122334455",
          "message": "I am forwarding your call to Department C. Please stay on the line."
        }
      ],
      "function": {
        "name": "transferCall",
        "description": "Use this function to transfer the call. Only use it when following instructions that explicitly ask you to use the transferCall function. DO NOT call this function unless you are instructed to do so.",
        "parameters": {
          "type": "object",
          "properties": {
            "destination": {
              "type": "string",
              "enum": ["+1234567890", "+0987654321", "+1122334455"],
              "description": "The destination to transfer the call to."
            }
          },
          "required": ["destination"]
        }
      },
      "messages": [
        {
          "type": "request-start",
          "content": "I am forwarding your call to Department A. Please stay on the line.",
          "conditions": [
            {
              "param": "destination",
              "operator": "eq",
              "value": "+1234567890"
            }
          ]
        },
        {
          "type": "request-start",
          "content": "I am forwarding your call to Department B. Please stay on the line.",
          "conditions": [
            {
              "param": "destination",
              "operator": "eq",
              "value": "+0987654321"
            }
          ]
        },
        {
          "type": "request-start",
          "content": "I am forwarding your call to Department C. Please stay on the line.",
          "conditions": [
            {
              "param": "destination",
              "operator": "eq",
              "value": "+1122334455"
            }
          ]
        }
      ]
    }
  ]
}
```

You can also specify the `extension` parameter to forward the call to an extension.

```json
    "destinations": [
        {
            "type": "number",
            "number": "+1234567890",
            "extension": "4603",
            "message": "I am forwarding your call to Department A. Please stay on the line."
        }
    ]
```

### 3. Using the `transferCall` Function

When the assistant needs to forward a call, it uses the `transferCall` function with the appropriate destination:

```json
{
  "function": {
    "name": "transferCall",
    "parameters": {
      "destination": "+1234567890"
    }
  }
}
```

### 4. Customizing Messages

Customize the messages for each destination to provide clear information to the caller:

```json
{
  "messages": [
    {
      "type": "request-start",
      "content": "I am forwarding your call to Department A. Please stay on the line.",
      "conditions": [
        {
          "param": "destination",
          "operator": "eq",
          "value": "+1234567890"
        }
      ]
    }
  ]
}
```

## Instructing the Assistant

Use the system prompt to guide the assistant on when to utilize each forwarding number. For example:

* "If the user asks for sales, call the `transferCall` function with `+1234567890`."
* "If the user requests technical support, use the `transferCall` function with `+0987654321`."

## Troubleshooting

* If calls are not being transferred, check the logs for errors.
* Ensure that the correct destination numbers are used.
* Ensure you have written the function description properly to indicate where you want to forward the call
* Test the call forwarding setup thoroughly to confirm its functionality.

## Call Transfers Mode

Vapi supports two types of call transfers:

1. **Blind Transfer** (default): Directly transfers the call to another agent without providing any prior information to the recipient.
2. **Warm Transfer**: Transfers the call to another agent after providing context about the call. The context can be either a full transcript or a summary, based on your configuration.

### Warm Transfer

To implement a warm transfer, add a `transferPlan` object to the `transferCall` tool syntax and specify the transfer mode.

Note: Warm transfer functionality is currently available only with Twilio-based telephony systems.

#### Modes of Warm Transfer

#### 1. Warm Transfer with Summary

In this mode, Vapi provides a summary of the call to the recipient before transferring.

* **Configuration:**

  * Set the `mode` to `"warm-transfer-with-summary"`.
  * Define a `summaryPlan` specifying how the summary should be generated.
  * Use the `{{transcript}}` variable to include the call transcript.

* **Example:**

```json
"transferPlan": {
  "mode": "warm-transfer-with-summary",
  "summaryPlan": {
    "enabled": true,
    "messages": [
      {
        "role": "system",
        "content": "Please provide a summary of the call."
      },
      {
        "role": "user",
        "content": "Here is the transcript:\n\n{{transcript}}\n\n"
      }
    ]
  }
}
```

#### 2. Warm Transfer with Message

In this mode, Vapi delivers a custom message to the recipient before transferring the call.

* **Configuration:**

  * Set the `mode` to `"warm-transfer-with-message"`.
  * Provide the custom message in the `message` property.
  * Note that the `{{transcript}}` variable is not available in this mode.

* **Example:**

```json
"transferPlan": {
  "mode": "warm-transfer-with-message",
  "message": "Hey, this call has been forwarded through Vapi."
}
```

#### Complete Example

Here is a full example of a `transferCall` payload using the warm transfer with summary mode:

```json
{
  "type": "transferCall",
  "messages": [
    {
      "type": "request-start",
      "content": "I'll transfer you to someone who can help."
    }
  ],
  "destinations": [
    {
      "type": "number",
      "number": "+918936850523",
      "description": "Transfer the call",
      "transferPlan": {
        "mode": "warm-transfer-with-summary",
        "summaryPlan": {
          "enabled": true,
          "messages": [
            {
              "role": "system",
              "content": "Please provide a summary of the call."
            },
            {
              "role": "user",
              "content": "Here is the transcript:\n\n{{transcript}}\n\n"
            }
          ]
        }
      }
    }
  ]
}
```

#### 3. Warm Transfer with Wait and Say Message

In this mode, Vapi waits for the recipient to speak first and then delivers a custom message to the recipient before transferring the call.

* **Configuration:**

  * Set the `mode` to `"warm-transfer-wait-for-operator-to-speak-first-and-then-say-message"`.
  * Provide the custom message in the `message` property.
  * Note that the `{{transcript}}` variable is not available in this mode.

* **Example:**

```json
"transferPlan": {
  "mode": "warm-transfer-wait-for-operator-to-speak-first-and-then-say-message",
  "message": "Hey, this call has been forwarded through Vapi."
}
```

#### 4. Warm Transfer with Wait and Say Summary

In this mode, Vapi waits for the recipient to speak first and then delivers a summary of the call to the recipient before transferring the call.

* **Configuration:**

  * Set the `mode` to `"warm-transfer-wait-for-operator-to-speak-first-and-then-say-summary"`.
  * Define a `summaryPlan` specifying how the summary should be generated.
  * Use the `{{transcript}}` variable to include the call transcript.

* **Example:**

```json
"transferPlan": {
  "mode": "warm-transfer-wait-for-operator-to-speak-first-and-then-say-summary",
  "summaryPlan": {
    "enabled": true,
    "messages": [
      {
        "role": "system",
        "content": "Please provide a summary of the call."
      },
      {
        "role": "user",
        "content": "Here is the transcript:\n\n{{transcript}}\n\n"
      }
    ]
  }
}
```

#### 5. Warm Transfer with TwiML

In this mode, Vapi executes TwiML instructions on the destination call leg before connecting the destination number.

* **Configuration:**

  * Set the `mode` to `"warm-transfer-with-twiml"`.
  * Provide the TwiML instructions in the `twiml` property.
  * Supports only `Play`, `Say`, `Gather`, and `Pause` verbs.
  * Maximum TwiML length is 4096 characters.
  * TwiML must be provided as a single-line string without line breaks or tabs, and must be a valid XML string. For example: `<Say>Hello</Say>` is valid, but `<Say>Hello\n</Say>` is not.

* **Example:**

```json
"transferPlan": {
  "mode": "warm-transfer-with-twiml",
  "twiml": "<Say>Hello, transferring a customer to you.</Say><Pause length=\"2\"/><Say>They called about billing questions.</Say>"
}
```

Here is a full example of a `transferCall` payload using the warm transfer with TwiML mode:

```json
{
  "type": "transferCall",
  "messages": [
    {
      "type": "request-start",
      "content": "I'll transfer you to someone who can help."
    }
  ],
  "destinations": [
    {
      "type": "number",
      "number": "+14155551234",
      "description": "Transfer to customer support",
      "transferPlan": {
        "mode": "warm-transfer-with-twiml",
        "twiml": "<Say>Hello, this is an incoming call from a customer.</Say><Pause length=\"1\"/><Say>They have questions about their recent order.</Say><Pause length=\"1\"/><Say>Connecting you now.</Say>",
        "sipVerb": "refer"
      }
    }
  ]
}
```

#### 6. Experimental Warm Transfer

In this mode, Vapi dials the destination number and places the caller on hold (with a default ringtone). If the destination answers, Vapi connects the calls. If voicemail is detected or the call isn't answered, Vapi plays a fallback message to the caller.

* **Configuration:**

  * Set the `mode` to `"warm-transfer-experimental"`.
  * Provide a `message` to be spoken to the operator when they answer.
  * Optionally define a `summaryPlan` that will take precedence over the message if enabled.
  * Configure a `fallbackPlan` with a message and whether to end the call if transfer fails.
  * Optionally provide a `holdAudioUrl` to play custom hold music to the customer during the transfer.
  * Configure `voicemailDetectionType` to customize how human voice detection is performed (only applies when the provider is Google or OpenAI):
    * `"audio"` (default): Supports a wide range of machine detection including beep detection and other audio cues
    * `"transcript"`: Uses transcript-based detection with the lowest latency and faster transfer processing times
  * Note that only Google or OpenAI providers are supported for voicemail detection with transfer plans, even if the assistant configuration supports other providers like Twilio or Vapi.

* **Example:**

```json
"transferPlan": {
  "mode": "warm-transfer-experimental",
  "message": "Transferring a customer to you.",
  "holdAudioUrl": "https://api.twilio.com/cowbell.mp3",
  "voicemailDetectionType": "transcript",
  "fallbackPlan": {
    "message": "Could not transfer your call, goodbye.",
    "endCallEnabled": true
  },
  "summaryPlan": {
    "enabled": true,
    "messages": [
      {
        "role": "system",
        "content": "Please provide a summary of the call."
      },
      {
        "role": "user",
        "content": "Here is the transcript:\n\n{{transcript}}\n\n"
      }
    ]
  }
}
```

This example uses `"transcript"` for the fastest transfer processing. For wider machine detection capabilities, use `"audio"` instead.

Here is a full example of a `transferCall` payload using the experimental warm transfer mode:

```json
{
  "type": "transferCall",
  "function": {
    "name": "myTransferCall"
  },
  "destinations": [
    {
      "type": "number",
      "number": "+1123456789",
      "message": "Transferring the call now...",
      "transferPlan": {
        "mode": "warm-transfer-experimental",
        "message": "Transferring a customer to you.",
        "holdAudioUrl": "https://assets.example.com/music.mp3",
        "voicemailDetectionType": "audio",
        "fallbackPlan": {
          "message": "Could not transfer your call, goodbye.",
          "endCallEnabled": true
        },
        "summaryPlan": {
          "enabled": true,
          "messages": [
            {
              "role": "system",
              "content": "Please provide a summary of the call."
            },
            {
              "role": "user",
              "content": "Here is the transcript:\n\n{{transcript}}\n\n"
            }
          ]
        }
      }
    }
  ]
}
```

This example uses `"audio"` for comprehensive machine detection including beep detection. This is the default option if not specified.

#### 7. Assistant-Based Warm Transfer (Experimental)

For use cases requiring AI-managed transfers, Vapi supports using assistants to handle the transfer process. This allows the assistant to converse with operators and make transfer decisions based on your configuration.

Configure AI assistants to handle call transfers with operator conversations

**Notes:**

* In all warm transfer modes, the `{{transcript}}` variable contains the full transcript of the call and can be used within the `summaryPlan`.
* The `holdAudioUrl` property (available only in `warm-transfer-experimental` mode) allows you to specify a custom MP3 file URL that will be played to the customer while they are on hold during the transfer. If not provided, the default hold audio will be used.
* The `voicemailDetectionType` parameter allows you to optimize the detection method based on your needs:
  * Use `"transcript"` for the fastest transfer processing with lowest latency
  * Use `"audio"` (default) for comprehensive machine detection including beep detection and other audio cues
* For more details about transfer plans and configuration options, please refer to the [transferCall API documentation](/api-reference/tools/create#request.body.transferCall.destinations.number.transferPlan)