Logo
Search
API Docs

Call Forwarding & Transfer Modes

Inbound Call Handling

Call Forwarding & Transfer Modes

Overview

This guide covers the technical layer underneath call transfers — the transferCall tool's full configuration surface, every warm transfer mode, SIP-level transfer signaling, and dynamic (runtime-resolved) transfer destinations. If you just need to route calls to a person or department using the portal UI, see How to Route or Transfer a Call to a Person first; this page is for teams that need finer control over exactly how a handoff behaves.


Blind vs. Warm Transfer

Every transfer destination has a transferPlan that controls how the handoff feels to the person receiving it:

  • Blind transfer (the default) connects the caller to the destination immediately, the same way a standard call forward works. No warning, no context, fastest possible handoff.
  • Warm transfer gives the receiving party context before the caller is connected — a spoken summary, a custom message, or in the most advanced mode, a live back-and-forth with an assistant that decides whether to complete or cancel the handoff.

Warm transfer functionality is currently only available on phone numbers provisioned through the core system.


The transferCall Tool and Destinations

A transferCall tool can hold multiple named destinations in its destinations array, each with its own number, message, and transfer mode:

{
  "type": "transferCall",
  "destinations": [
    {
      "type": "number",
      "number": "+15551234567",
      "message": "Transferring you to sales now.",
      "transferPlan": { "mode": "blind-transfer" }
    }
  ]
}

The model chooses which destination to use based on the description you give each one, and your system prompt should still tell the assistant when to reach for the tool at all — the tool's presence doesn't imply when it should fire.


Warm Transfer Plan Modes

The transferPlan.mode field selects which warm transfer behavior to use:

ModeBehavior
warm-transfer-with-summaryAn AI-generated summary of the call is spoken to the recipient before connecting. Requires a summaryPlan.messages array; use {{transcript}} to include the transcript.
warm-transfer-with-messageA static custom message (set in message) is spoken to the recipient before connecting. {{transcript}} is not available here.
warm-transfer-wait-for-operator-to-speak-first-and-then-say-messageWaits for the recipient to speak first, then delivers the static message.
warm-transfer-wait-for-operator-to-speak-first-and-then-say-summaryWaits for the recipient to speak first, then delivers the AI-generated summary.
warm-transfer-with-twimlExecutes TwiML on the destination leg before connecting. Supports only Play, Say, Gather, and Pause verbs; must be a single-line, valid-XML string under 4096 characters.
warm-transfer-experimentalDials the destination, holds the caller, and connects once the recipient answers. Detects voicemail and falls back to a message if the transfer can't complete.

Example for the experimental mode, which has the most configuration surface:

"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" }
    ]
  }
}

voicemailDetectionType is either "audio" (default, widest machine-detection coverage including beep detection) or "transcript" (lowest latency). Voicemail detection for transfer plans is only supported when the assistant uses a Google or OpenAI provider, even if the call itself is on a different provider.


Assistant-Based Warm Transfer

For the most control, a warm transfer can hand the call to a dedicated transfer assistant that talks to the operator directly and decides the outcome itself, using two built-in tools that are always present and cannot be removed:

  • transferSuccessful – merges the customer and operator calls, removes the transfer assistant, and connects the two parties. Called when the operator agrees to accept the call.
  • transferCancel – disconnects from the operator and returns the customer to the original assistant, optionally playing a fallback message. Called when the operator declines, voicemail is detected, or the transfer otherwise can't complete.

Your system prompt for the transfer assistant should spell out exactly when to call each tool, for example:

- Use transferSuccessful when the operator agrees to accept the call
- Use transferCancel when the transfer cannot be completed
- Only call the tool once you've addressed the operator's questions

The transfer is also cancelled automatically if maxDurationSeconds is reached or the operator never answers, regardless of what the assistant decides.


SIP REFER Signaling and Supported Scenarios

When a transfer is initiated on a SIP call, a SIP REFER packet is sent to your SIP provider, which then takes over managing the actual transfer. Not every combination of call type and destination supports this:

FromToSupported
Phone call (PSTN)Phone numberYes
Web callPhone numberNo – the call will always drop
Phone call (PSTN)SIP numberNo
SIP callSIP numberYes
SIP callPhone numberYes

For SIP transfers to work correctly, phoneCallProviderBypassEnabled must be false and "phone-call-control" must not be present in serverMessages (either would override the platform's own call control). Some SIP trunk providers do not accept REFER-based transfers at all — confirm support with your provider before relying on this path.


Dynamic Transfers via the transfer-destination-request Webhook

If the transfer destination isn't known ahead of time and needs to be resolved at runtime (for example, looking up the right department in a CRM), configure the transferCall tool without a destination. When the assistant invokes it, a transfer-destination-request event is sent to your server:

{
  "message": {
    "type": "transfer-destination-request",
    "call": { }
  }
}

Your server must respond with a destination and, optionally, a spoken message:

{
  "destination": { "type": "number", "number": "+11234567890" },
  "message": { "type": "request-start", "message": "Transferring you now" }
}

A SIP URI can be returned the same way by setting "type": "sip" and a sipUri field instead. This is one of the few server events that requires a response — if the assistant already includes a destination directly in the tool call, this webhook is never sent and the transfer happens immediately.