Skip to content

Call Transfer

The Call Transfer tool lets your AI agent transfer an active telephony call to a phone number or SIP endpoint. You can configure a fixed destination, use a template from call context, or resolve the destination at transfer time by calling your HTTP endpoint.

Use this tool when the caller should speak to a human operator, department, escalation queue, support queue, or another phone system.

Supported providers

Call transfer is available for telephony calls using Twilio, Telnyx, or Asterisk ARI providers.

How call transfer works

When the LLM decides a transfer is needed, it calls the Call Transfer tool. Decibyl resolves the destination, validates the transfer setup, and then starts the provider transfer.

For a successful transfer:

  1. The agent calls the Call Transfer tool.
  2. Decibyl resolves the destination from either static configuration or a dynamic HTTP resolver.
  3. Decibyl optionally plays a pre-transfer message.
  4. Decibyl starts dialing the destination through the telephony provider.
  5. The caller hears hold music while the destination leg is connecting.
  6. When the destination answers, Decibyl connects the caller and ends the AI agent’s involvement.

The transfer is a blind transfer. Decibyl does not currently pass conversation context to the receiving human as part of the transfer.

Destination source

You must choose one destination source for each Call Transfer tool.

Static / Template

Use this when the transfer destination is already known before the transfer happens.

Static destinations can be:

  • A fixed E.164 phone number, such as +1234567890
  • A SIP endpoint, such as PJSIP/sales-queue
  • A template value from context, such as {{initial_context.transfer_destination}}

This is the simplest option for fixed support lines, fixed departments, or cases where the destination is provided before the call starts.

Dynamic HTTP Resolver

Use this when the destination must be decided during the conversation.

Decibyl sends a POST request to your resolver endpoint before starting the transfer. Your endpoint returns the destination and may return a custom message to play before dialing.

Common use cases:

  • Route by region, timezone, or language
  • Look up the right account team in your customer system
  • Route by customer tier or account status
  • Route by issue type, language, or department
  • Use business logic from your backend instead of hardcoding numbers in Decibyl

Dynamic resolver request

The resolver request body is a flat JSON object.

Decibyl builds it from:

  • LLM parameters: values the agent extracts from the conversation when it calls the transfer tool
  • Preset parameters: values Decibyl injects from fixed values or templates such as {{initial_context.account_id}} or {{gathered_context.billing_issue_type}}

If both define the same key, preset parameters take precedence.

Example request body:

{
"account_id": "acct_123",
"plan": "enterprise",
"billing_issue_type": "invoice_dispute"
}

Dynamic resolver response

Your resolver must return a JSON object with transfer_context.destination.

transfer_context.custom_message is optional.

{
"transfer_context": {
"destination": "+1234567890",
"custom_message": "Please wait while I connect you with our enterprise billing team."
}
}

Field behavior:

  • destination: Required. E.164 phone number or SIP endpoint.
  • custom_message: Optional. Played to the caller before the transfer starts.
  • briefing: Optional. Played to the destination when they answer, before the caller is bridged in. See Briefing the person who answers.

If the resolver fails, times out, returns invalid JSON, or omits transfer_context.destination, the transfer fails gracefully and the agent can continue handling the caller.

Dynamic resolver configuration

When using a dynamic resolver, configure:

  • Resolver URL: HTTPS or HTTP endpoint Decibyl calls with POST
  • Resolver Timeout: How long Decibyl waits for the resolver response
  • Resolver Wait Message: Optional message spoken while Decibyl waits, such as “One moment while I find the right team.”
  • LLM Parameters: Values the agent should extract from the conversation, such as billing_issue_type or requested_department
  • Preset Parameters: Values injected by Decibyl from context or fixed values
  • Custom Headers: Static headers sent to your resolver endpoint
  • Credential: Optional saved credential used to authenticate the resolver request

Pre-transfer messages

Call Transfer supports a common pre-transfer message setting for both static and dynamic destinations.

For static transfers:

  1. Decibyl resolves the static or template destination.
  2. Decibyl plays the configured pre-transfer message, if any.
  3. Decibyl starts the provider transfer.

For dynamic transfers:

  1. Decibyl may play the resolver wait message while calling your resolver.
  2. If the resolver returns custom_message, Decibyl plays that message.
  3. If the resolver does not return custom_message, Decibyl uses the configured pre-transfer message.
  4. Decibyl starts the provider transfer.

Resolver custom_message overrides the configured pre-transfer message for that transfer attempt.

Briefing the person who answers

A pre-transfer message is played to the caller. A briefing is played to the destination, on their leg alone, in the moment between them answering and the caller being bridged in. The caller never hears it.

Without one, the person who picks up knows nothing — not who is on the line, not what they have already explained, not what they want. So they ask again, and a caller who has just spent three minutes explaining repeats the whole thing to a second party. That is the moment people decide a voice agent made things worse.

Set briefing on the tool. It renders {{variables}} the same way a webhook payload does:

{{gathered_context.caller_name}} on the line about {{gathered_context.issue}}.
Account {{initial_context.account_id}}. They have already verified their
identity.

A dynamic resolver can return its own briefing alongside destination, and it wins: a routing service that chose who takes the call is best placed to say why.

{
"transfer_context": {
"destination": "+1234567890",
"custom_message": "Connecting you to our billing team now.",
"briefing": "Enterprise billing escalation. Priya Menon, account 4471, disputing a duplicate charge."
}
}

Two limits worth knowing:

  • It is capped at 240 characters — about twelve seconds spoken. Past that the human has stopped listening and the caller, sitting in silence, starts saying “hello?”. Longer text is cut at the last sentence that fits.
  • It is spoken on Twilio and Cloudonix. Telnyx and Asterisk ARI dial the destination in a way that has no point to speak from, so a briefing set on those is ignored and the transfer proceeds as before.

If no briefing is set, the destination hears a short generic line rather than silence.

Voicemail is not a person

“Answered” and “answered by a person” are different things. An out-of-hours desk phone rolls to voicemail and reports as answered — and a caller who asked for a human, and was told one was coming, gets bridged into a recorded greeting and then silence.

On Twilio, Decibyl asks the carrier who picked up and does not bridge the caller into a machine. The transfer fails instead, which hands the conversation back to the agent — it can say the line was unavailable and offer a callback, which is a far better ending than a caller talking to an answering machine.

Detection costs a second or two before the briefing plays, spent on the destination’s leg where the caller is on hold either way. Carriers that do not report who answered — Telnyx, Cloudonix and Asterisk ARI on this leg — transfer exactly as they did before.

Transfer timeout

Transfer timeout is the maximum time Decibyl waits for the destination to answer after the provider transfer starts.

This timeout applies to both static and dynamic transfers.

The resolver timeout is separate. It controls only how long Decibyl waits for your HTTP resolver before dialing starts.

Destination formats

Twilio and Telnyx

Use E.164 phone numbers:

+1234567890

The number must be reachable from your telephony provider.

Asterisk ARI

Use SIP endpoints:

PJSIP/sales-queue
SIP/1001

Example: route enterprise billing calls

Use this setup when the agent identifies a billing issue and your backend decides whether to route the caller to standard billing, enterprise billing, or collections.

Configure LLM parameters:

[
{
"name": "billing_issue_type",
"type": "string",
"description": "The billing issue the caller needs help with, such as invoice_dispute, payment_failed, refund_request, or plan_change.",
"required": true
},
{
"name": "requested_department",
"type": "string",
"description": "The department the caller is asking for, if they explicitly mention one.",
"required": false
}
]

Configure preset parameters:

[
{
"name": "account_id",
"type": "string",
"value_template": "{{initial_context.account_id}}",
"required": true
},
{
"name": "plan",
"type": "string",
"value_template": "{{initial_context.plan}}",
"required": true
}
]

Your resolver receives:

{
"billing_issue_type": "invoice_dispute",
"requested_department": "billing",
"account_id": "acct_123",
"plan": "enterprise"
}

Your resolver returns:

{
"transfer_context": {
"destination": "+18005550199",
"custom_message": "Please wait while I connect you with our enterprise billing team."
}
}

Best practices

  • Keep resolver latency low. Aim for 2-3 seconds.
  • Use a resolver wait message if the resolver may take noticeable time.
  • Send only the parameters your resolver needs.
  • Prefer preset parameters for values already available in initial_context or gathered_context.
  • Make LLM parameter descriptions explicit so the agent knows what to extract.
  • Test both successful transfer and resolver failure paths before going live.
  • Keep destination validation and routing logic in your backend when routing depends on account data or business rules.

Troubleshooting

The transfer tool is not called

Check that the tool is attached to the correct node and that the node prompt clearly tells the agent when to transfer.

Static transfer fails with no destination

Static mode requires a configured destination. Use a fixed destination or a template that resolves to a non-empty value.

Dynamic transfer fails before dialing

Check the resolver response. It must include:

{
"transfer_context": {
"destination": "+1234567890"
}
}

Also verify the resolver URL, authentication headers, credential, and timeout.

Resolver receives missing parameters

Confirm the parameter is configured as either:

  • an LLM parameter, if the agent should extract it from the conversation
  • a preset parameter, if Decibyl should inject it from context

For known context values, prefer preset parameters like {{initial_context.account_id}} or {{gathered_context.billing_issue_type}}.

Destination does not connect

Verify that the phone number or SIP endpoint is valid and reachable from the configured telephony provider.