Transfer
The transfer Function packages the common transfer choreographies into a single declarative
Function, so you don't have to orchestrate dial/refer, hold music, briefing, confirmation
gates and fallback routing by hand. It covers two broad modes:
- blind — hand the call off immediately, without waiting for the destination to accept. Implemented either as a SIP REFER (
blindMethod: 'refer') or as a bridged outbound call (blindMethod: 'dial'). - warm — let the application brief the destination before the caller is connected. The caller is either parked (on hold,
callerPresent: false) or joined into a three-way conference (callerPresent: true).
When the transfer does not complete normally (no answer, busy, declined, error), a configurable disposition decides what happens to the caller — return them to the application, send them to voicemail, or hang up.
{
"verb": "transfer",
"mode": "blind",
"target": [
{ "type": "phone", "number": "+815099990011" }
]
}
A warm, parked transfer with a spoken brief, hold music, and a fallback when nobody answers:
{
"verb": "transfer",
"mode": "warm",
"callerPresent": false,
"target": [
{ "type": "phone", "number": "+815099990010" }
],
"brief": {
"text": "I have a customer on the line who needs help with their account."
},
"onHoldHook": "/hold-music",
"disposition": {
"onNoAnswer": "return",
"onBusy": "return"
},
"actionHook": "/transfer-complete"
}
Parameters
modestringblind or warm. blind hands the call off immediately without waiting for the
destination to accept; warm lets the application brief the destination before the
caller is connected.
targetarrayOne or more call destinations (same structure as the dial
Function's target). All targets are attempted simultaneously and the first to answer wins.
blindMethodstringblind only. refer sends a SIP REFER to the remote end; dial places a bridged
outbound call. This is not auto-detected — set it explicitly to dial when REFER is
not appropriate (e.g. transferring to a PSTN number that the upstream carrier won't REFER).
callerPresentbooleanwarm only. When true, the caller is added to a three-way conference and can hear the
brief; when false, the caller is parked (on hold) and does not hear the conversation
between the application and the destination.
callerIdstringCaller ID presented to the transfer destination.
onHoldHookstringwarm + parked only (callerPresent: false). A webhook returning Functions to run for the
parked caller while the destination is briefed — e.g. play hold music. Ignored when
callerPresent is true.
timeoutnumberSeconds to wait for the destination to answer before applying the onNoAnswer
disposition.
briefobjectwarm only. The literal spoken summary delivered to the destination (human) before the
caller is connected.
brief.textstringThe briefing text spoken to the destination.
brief.synthesizerobjectOptional voice/vendor for the brief (a synthesizer object). Defaults to the session synthesizer.
confirmobjectOptional human-side acceptance gate. The destination hears a prompt and must press the
specified digit to accept. A wrong digit, a timeout, or a hangup is treated as a
decline.
confirm.promptstringText or URL of the prompt played to the destination.
confirm.digitstringSingle DTMF digit the destination must press to accept the transfer.
amdobjectwarm only. Optional answering-machine detection run on the
destination leg (same amd structure as the dial Function). Off by default; a machine
result is treated as a decline.
dispositionobjectPer-outcome fallback actions when the transfer does not complete normally. Each key
accepts return, voicemail, or hangup and defaults to return.
disposition.onNoAnswerstringAction when the destination does not answer within timeout.
disposition.onBusystringAction when the destination returns busy.
disposition.onDeclinestringAction when the destination declines — the confirm gate failed, AMD detected a
machine, or the destination explicitly rejected the call.
disposition.onFailurestringAction when a protocol-level error occurs on the destination leg.
disposition.voicemailUrlstringSIP URI or HTTP URL to route the caller to voicemail. Required whenever any
disposition value is voicemail.
actionHookstringFires when the transfer resolves — whether the call was bridged, returned to the caller, sent to voicemail, or failed. See actionHook properties.
eventHookstringOptional hook for in-progress transfer lifecycle events. See eventHook events.
idstringAn optional unique identifier for this Function instance.
actionHook properties
When the transfer resolves, the actionHook is called with these additional parameters (alongside the standard call attributes):
transfer_result— one of:bridged— the caller and destination were connected and the transfer completed.returned— the transfer did not connect and the caller was returned to the application (control falls through to subsequent Functions, or to the Functions returned by the actionHook).failed— the transfer ended on ahangupdisposition or a fatal error.transfer_reason— the underlying cause:completed— destination answered and the call bridged.no-answer— destination did not answer withintimeout.busy— destination returned busy.declined—confirmgate failed, AMD detected a machine, or the destination rejected.caller-abandoned— the caller hung up before the transfer completed.error— a protocol-level error on the destination leg.
eventHook events
If eventHook is set, Wipple CPaaS posts the following lifecycle events. Each payload carries
the standard call attributes plus an event_type and event-specific fields:
transfer.initiated— fired at the start; includesmodeandcallerPresent.transfer.bridged— caller and destination connected.transfer.returned— transfer did not connect; includestransfer_reason.transfer.failed— transfer ended on failure; includestransfer_reason.
eventHook failures never interrupt the transfer.
Transfer-to-human from a conversational agent
If you want a voice agent to hand off to a human as a tool call, you do not use the
transfer Function directly — instead add a declarative handoff block to the
agent or llm
Function. The runtime injects a transfer_to_human tool and runs this same transfer
choreography when the model calls it.
Live Call Control
You can also inject a transfer into an in-progress call via the REST API by issuing an
updateCall request with a transfer body — useful for parking a caller and then
transferring them from an external trigger. See the
REST Call Control reference.