Skip to navigation

Transfer Tools

Transfer tools hand the live call off to a human, a queue, another system, or another Phonic Agent. Both transfer types cannot have parameters and always run in sync mode.

See Tool Definition for the shared fields and Tool Behavior Configuration for the behavior toggles.

Transfer to Phone Number

The built_in_transfer_to_phone_number tool transfers the call to a phone number or a SIP URI: a human, a queue, or even another system. In the dashboard choose Transfer to phone number.

The smallest possible tool sets only the destination number. Everything else has a default, so start here and add fields one at a time as you need them.

import { PhonicClient } from "phonic";
const apiKey = process.env.PHONIC_API_KEY;
const client = new PhonicClient({ apiKey });
async function createTool() {
await client.tools.create({
name: "transfer_to_support",
description: "Transfers the call to the support team",
type: "built_in_transfer_to_phone_number",
execution_mode: "sync",
phone_number: "+15551234567", // E.164 format
});
}
createTool()

Two choices that shape every transfer

Most of the fields below are easier to reason about once you separate two independent decisions:

  1. Does Phonic stay on the line? (keep_listening, on by default.) On means a bridged transfer, off means a hand-off. See Bridged vs hand-off below.
  2. Whose number does the transfer present? (use_agent_phone_number, on by default.) The agent’s own number, or the original caller’s number (inbound calls only).

These are separate knobs. The most common confusion is expecting the caller-ID choice to also control whether Phonic stays on the line: it does not. Set them independently, subject to the compatibility rules below.

Bridged vs hand-off

Bridged (keep_listening: true)Hand-off (keep_listening: false)
How the call is connectedPhonic dials the destination and joins it to the caller’s call.Phonic asks the caller’s carrier to redirect the call to the destination (a SIP REFER). With DTMF, Phonic instead bridges just long enough to key the digits, then detaches.
Phonic after the transfer connectsStays on the call and keeps listening.Off the call. Nothing comes back to the agent.
Caller ID shown to the destinationAgent’s number or the caller’s (use_agent_phone_number)Can’t be the agent’s number
Post-transfer message, voicemail detection, retryingAvailableNot available
SIP headersAvailableOnly with DTMF

Use a bridged transfer unless you specifically want Phonic out of the call as soon as the transfer starts.

Configuration reference

Dashboard labelAPI fieldDefaultWhat it controls
Phone numberphone_numberrequiredThe E.164 destination number.
(Agent chooses number)phone_number: nulloffLet the agent pick the number at runtime.
SIP URI, SIP headerssipnullTransfer to a SIP URI instead of a phone number.
DTMFdtmfnullDigits to send after connecting. See DTMF characters.
Agent chooses DTMFdynamic_dtmffalseLet the agent supply the digits at call time.
Keep listening during transferkeep_listeningsame as use_agent_phone_numberBridged vs hand-off.
Use agent phone number for transferuse_agent_phone_numbertruePresent the agent’s number vs the caller’s.
Post-transfer announcementpost_transfer_messagenullA fixed line spoken to the caller when the transfer connects.
Allow Phonic to detect and handle voicemaildetect_voicemailfalseReturn the caller to the agent if the target is a voicemail box.
If the transfer isn’t answeredon_transfer_no_answerreturn_to_assistantWhat to do when the transfer rings out.
UninterruptibleuninterruptibletrueStop caller speech from interrupting the transfer.
Require speech before tool callrequire_speech_before_tool_calltrueForce the agent to speak before transferring (see Tool Behavior Configuration).

Phone number (phone_number)

The E.164 number to transfer to, for example +15551234567. Toggle Agent chooses in the dashboard (send phone_number: null via the API) to let the agent determine the number at runtime. When you do, describe the routing logic in the tool description so the agent knows which number to dial.

SIP URI (sip)

Transfer to a SIP endpoint, such as a PBX extension or contact-center queue, instead of a phone number. In the dashboard set Transfer to to SIP URI. Via the API, send sip with phone_number: null; the two can’t both be set.

  • uri: sip:user@host[:port][;transport=udp|tcp|tls] or sips:user@host[:port], for example sip:frontdesk@pbx.example.com:5061;transport=tls. transport is the only URI parameter allowed.
  • headers (optional): custom SIP headers to send with the transfer, for example {"X-Case-Id": "1234"}. Names must start with X-, and values can’t contain line breaks. Headers need a bridged transfer, or a hand-off with DTMF, because a plain SIP REFER can’t carry them.

On update, setting sip clears phone_number and setting phone_number clears sip.

DTMF (dtmf)

Optional digits Phonic keys after the transfer connects, for stepping through an IVR or entering an extension. Toggle Agent chooses DTMF (dynamic_dtmf: true) to let the agent decide the digits at call time instead of hard-coding them. See DTMF characters for the full set, including w to insert a pause. Pass null, not an empty string, when no digits should be sent.

Keep listening during transfer (keep_listening)

On (bridged) by default in the dashboard. Turn it off for a hand-off. See Bridged vs hand-off for what each allows. Via the API, an omitted keep_listening takes the value of use_agent_phone_number.

Use agent phone number for transfer (use_agent_phone_number)

On by default: the transfer presents the agent’s own phone number. Turn it off to present the original caller’s number instead, so the person receiving the transfer sees who is really calling. This only works on inbound calls (it relies on carrier call-forwarding metadata). An outbound leg always falls back to the agent’s number regardless of this setting.

On a custom SIP trunk, a bridged transfer or a hand-off with DTMF needs carrier setup to show the caller’s number. Without it, the transfer still connects but shows the agent’s number. See Showing the caller’s number on a transfer.

Via the API, turning this off also makes the transfer a hand-off unless you send keep_listening: true, because an omitted keep_listening takes this field’s value.

Post-transfer announcement (post_transfer_message)

A fixed line the agent speaks into the call the moment the transfer connects, so both the caller and the person receiving them hear it. Use it to introduce the two parties and bow out, for example “Hi, I have a caller on the line asking about a billing charge, and I’ve connected you both. Feel free to talk it through. Goodbye!” Leave it null for no message. It requires a bridged transfer (there is no agent left to speak it on a hand-off), and it cannot be combined with voicemail detection.

Allow Phonic to detect and handle voicemail (detect_voicemail)

Off by default. When on, Phonic listens after the transfer connects to tell whether a person or a voicemail system answered. If a person answers, Phonic completes the transfer and drops off, leaving the caller connected. If it reaches voicemail, Phonic ends the transfer and resumes the conversation with the caller instead of stranding them on a machine. Requires a bridged transfer.

If the transfer isn’t answered (on_transfer_no_answer)

What happens when the transfer rings out with no answer:

  • return_to_assistant (default): resume the conversation with the caller, so the agent can apologize or offer an alternative.
  • keep_retrying: keep re-dialing the number, with the caller still on the line, until someone answers, then fall back to return_to_assistant if no one ever does. Requires a bridged transfer.

Uninterruptible (uninterruptible)

On by default, including for existing transfer tools created before this setting existed. While the transfer tool runs, caller speech doesn’t interrupt it. This includes what the agent says just before transferring, once protection is active. Set it to false to let the caller cut the transfer off by speaking.

Compatibility rules

Some combinations are rejected at create time because they cannot physically work. If a request is rejected, it is one of these:

RuleWhy
use_agent_phone_number must be false when keep_listening is falseA hand-off can’t present the agent’s number.
detect_voicemail must be false when keep_listening is falseOnce Phonic hands off, there is no audio left to listen to.
post_transfer_message must be null when keep_listening is falseThere is no bridged call for the agent to speak the message on.
on_transfer_no_answer can’t be keep_retrying when keep_listening is falseA hand-off has no bridged dial to retry.
post_transfer_message must be null when detect_voicemail is trueThe message is not spoken while Phonic is still deciding person vs voicemail.
Only one of phone_number and sip can be setA transfer has a single destination.
sip.headers must be empty on a hand-off without DTMFA plain SIP REFER can’t carry custom headers.
In short: a hand-off (keep_listening: false) forces use_agent_phone_number: false and rules out the post-transfer message, voicemail detection, retrying, and (without DTMF) SIP headers. Everything else is available on a bridged transfer. Remember that an omitted keep_listening follows use_agent_phone_number, and these rules apply to that resulting value.

Common scenarios

Pick the row that matches what you want, then set the listed fields (all other fields keep their defaults).

If you want to…Set
Warm-transfer to a human and announce the caller firstpost_transfer_message: "..." (bridged transfer, the default)
Hand the caller straight to a queue and drop Phonic off the callkeep_listening: false, use_agent_phone_number: false
Show the person you transfer to the caller’s real number (inbound only)use_agent_phone_number: false, keep_listening: true
Transfer to a PBX or contact center over SIPphone_number: null, sip: { uri: "sip:..." }
Let the caller interrupt the transfer by speakinguninterruptible: false
Step through an IVR or enter an extension after connectingdtmf: "1w2w1234" (w is a pause), or dynamic_dtmf: true
Avoid leaving the caller on a voicemail boxdetect_voicemail: true
Keep re-dialing until someone picks upon_transfer_no_answer: "keep_retrying"
Let the agent decide the destination numberphone_number: null, and describe the routing in the tool description

For example, a cold hand-off to a support queue that presents the caller’s number and never comes back to the agent:

await client.tools.create({
name: "transfer_to_queue",
description: "Hands the caller off to the support queue",
type: "built_in_transfer_to_phone_number",
execution_mode: "sync",
phone_number: "+15551234567",
keep_listening: false,
use_agent_phone_number: false,
});

DTMF characters

The dtmf string accepts digits 0–9, *, #, the lowercase letters a–d, and w for a pause. Phonic removes any character outside that set before sending.

CharacterSupportedEffect
0–9YesKeypad digit tone.
*YesStar tone.
#YesPound (hash) tone.
a b c dYesA/B/C/D tones, a fourth DTMF column that ordinary phones don’t have. Most IVRs ignore them.
wYesA pause of 0.5 seconds. Repeat to lengthen it, so www waits 1.5 seconds.
A B C DNoRemoved before sending. Use lowercase for A/B/C/D tones.
WNoRemoved before sending, and not a pause. Use lowercase w.
,NoRemoved before sending, and not a pause despite the convention elsewhere. Use w.
Anything elseNoRemoved before sending.

Each digit takes about half a second to play: a 250 ms tone followed by a 250 ms gap. A w pause is 0.5 seconds with no trailing gap. Neither is configurable.

An unsupported character is removed before the string is sent, so it doesn’t play and the rest of the sequence is unaffected. Uppercase A–D and W are the common case, since w and a–d are recognized in lowercase only.

There’s no maximum length for dtmf. Pass null, not an empty string, when no digits should be sent.

dtmf works with a hand-off (keep_listening: false) too: Phonic briefly bridges the call to key the digits, then detaches. With no dtmf, a hand-off is a plain SIP REFER.

Because a hand-off with DTMF is bridged, showing the caller’s number on a custom SIP trunk needs the same carrier setup as a bridged transfer.

Transfer to Agent

The built_in_transfer_to_agent tool hands the conversation off to another Phonic Agent. In the dashboard choose Transfer to agent and select one or more agents in Agents to transfer to (agents_to_transfer_to). Use the tool’s description to tell the agent which target to pick (e.g. route Enterprise vs Starter callers to different agents).

await client.tools.create({
name: "transfer_to_finance",
description:
"For finance queries, transfer to 'finance-enterprise-agent' for Enterprise plans, else 'finance-starter-agent'.",
type: "built_in_transfer_to_agent",
execution_mode: "sync",
agents_to_transfer_to: ["finance-enterprise-agent", "finance-starter-agent"],
});