Developer Guide / Transfer Call Options

Transfer Call Options

Route callers to human agents or other numbers — blind or attended, sequential or simultaneous, with dynamic resolution and failure handling.

Overview

VoiceElements supports transferring a caller to a human agent or another number, controlled by the AI. Transfers can be blind (caller is immediately bridged) or attended (the AI announces the caller to the recipient first). Numbers can be dialed sequentially (one at a time, move to next on no answer) or simultaneously (all at once, first to answer wins).

Transfers are initiated when the AI calls the vns_transfer_call built-in tool. You configure transfer behavior through transferServices in VoiceElements_Instructions in your CallStart response.

Blind Transfer

Caller is bridged immediately. The AI disconnects once the recipient answers.

Attended Transfer

The AI announces the caller to the recipient and gets confirmation before bridging.

Dynamic Resolution

Your API can return a transfer service at call time based on time of day, queue availability, or any business logic.

The vns_transfer_call Tool

You must define vns_transfer_call in your session configuration so the AI knows it can request a transfer. Two forms are supported.

Simple — uses the "default" transfer service

No parameters needed when you have a single default transfer destination:

{
  "name": "vns_transfer_call",
  "description": "Transfers the current call to another number.",
  "type": "function",
  "parameters": null
}

With parameters — AI selects a named transfer service

Use this when you have multiple transfer services (e.g. afterhours, support) and want the AI to choose:

{
  "name": "vns_transfer_call",
  "description": "Transfers the current call.",
  "type": "function",
  "parameters": {
    "type": "object",
    "properties": {
      "transferService": {
        "type": "string",
        "description": "Name of the transfer service to use (e.g. 'afterhours', 'support')."
      }
    }
  }
}

Transfer Service Resolution Order

When vns_transfer_call is received, VoiceElements resolves the transfer service using this chain in order:

1

Named service

If transferService is provided and matches a name in transferServices, use it.

2

onTransferToolName API call

If the named service wasn't found (or no name was given), and onTransferToolName is configured, your API is called to dynamically return a transfer service.

3

"default" service

If no transferService was supplied and no API is configured, the entry named "default" in transferServices is used.

4

Legacy direct number

If the AI passed a transferNumber directly (legacy mode), that number is dialed.

!

Fail

If none of the above resolve, the AI receives an error response.

Configuring Transfer Services

Transfer services are defined in the transferServices array inside VoiceElements_Instructions of your CallStart response. You can define as many named services as you need.

"transferServices": [
  {
    "name": "default",
    "callerId": "+18005551234",
    "callerIdName": "Acme Support",
    "attended": false,
    "useVnsNumberAsCallerId": false,
    "dialMode": "sequential",
    "transferNumbers": [
      { "number": "+13035551000", "dialTime": 20 },
      { "number": "+13035551001", "dialTime": 30 },
      "+13035559999"
    ]
  },
  {
    "name": "afterhours",
    "callerId": "+18005551234",
    "callerIdName": "Acme Support",
    "attended": false,
    "useVnsNumberAsCallerId": false,
    "dialMode": "simultaneous",
    "transferNumbers": [
      "+13035552000",
      "+13035552001"
    ]
  }
]

Transfer Service Fields

Field Type Description
name string Identifier. "default" is used when the AI calls vns_transfer_call with no service name.
callerId string E.164 caller ID shown to the recipient.
callerIdName string Caller ID name shown to the recipient.
attended boolean false = blind transfer. true = attended transfer (AI announces caller to recipient).
useVnsNumberAsCallerId boolean If true, uses the called DID as the caller ID instead of callerId.
dialMode string "sequential" — try numbers one at a time. "simultaneous" — ring all at once, first to answer wins.
transferNumbers array Numbers to dial. Each entry can be a plain string or an object with number and dialTime.
attendedTransferSessionUpdate object Custom session.update sent to the AI when an attended transfer connects. Overrides the built-in defaults entirely when present.
failedTransferSessionUpdate object Custom session.update sent to the AI when all transfer attempts fail.

Per-Number Dial Time

Each entry in transferNumbers can be a plain string (uses the default 30-second dial time) or an object with a custom dialTime in seconds. The last number can have a longer dialTime if you want the call to reach voicemail.

"transferNumbers": [
  { "number": "+13035551000", "dialTime": 12 },
  { "number": "+13035551001", "dialTime": 18 },
  "+13035559999"
]

Blind Transfer

Set "attended": false — the caller is immediately bridged to the first available recipient. The AI is disconnected once the transfer connects.

Sequential

Numbers are tried one at a time. If the first doesn't answer within its dialTime, the next is tried, and so on. If all fail, the failure handler runs.

Simultaneous

All numbers are called at once. The first to answer wins; all other ringing calls are dropped.

{
  "name": "support",
  "attended": false,
  "dialMode": "sequential",
  "transferNumbers": [
    { "number": "+13035551000", "dialTime": 20 },
    { "number": "+13035551001", "dialTime": 20 }
  ]
}

Attended Transfer

Set "attended": true — the AI is routed to the outgoing call and announces the original caller to the recipient before bridging.

When the transfer channel connects, a session.update is sent to the AI with instructions for the attended transfer phase. The AI then has access to two built-in tools:

vns_attended_transfer_accepted

Call when the recipient agrees to take the call. The caller is bridged.

vns_attended_transfer_declined

Call when the recipient refuses or voicemail is detected. The failure handler runs.

Default Attended Transfer Instructions

By default, VNS uses the following session.update when the attended transfer connects. To override it, set attendedTransferSessionUpdate on the transfer service.

{
  "type": "session.update",
  "session": {
    "type": "realtime",
    "instructions": "The original caller has requested to be transferred to another number. You have been routed to the outgoing call. When the call is answered take a moment to determine if you reached a voicemail box. If so, then call vns_attended_transfer_declined. If you reach a human, then announce the call to the person that answered. Then ask them to accept the call.\n\n## Tool Call Rules\nYou may only call vns_attended_transfer_accepted or vns_attended_transfer_declined.\n\nvns_attended_transfer_accepted is called when the person answering the transferred call accepts.\n\nvns_attended_transfer_declined is called when the person answering the transferred call refuses the call.",
    "tools": [
      {
        "name": "vns_attended_transfer_accepted",
        "description": "Call this function to accept the transfer.",
        "type": "function",
        "parameters": null
      },
      {
        "name": "vns_attended_transfer_declined",
        "description": "Call this function to decline the transfer.",
        "type": "function",
        "parameters": null
      }
    ]
  }
}

Transfer Failure Handling

When all transfer attempts fail (all numbers busy/no-answer, or the recipient declines an attended transfer), VoiceElements runs the failure handler. The AI is routed back to the original caller with new session instructions.

Resolution Order

1

failedTransferSessionUpdate on the TransferService

Use a custom session.update for this specific service.

2

onTransferFailedToolName

Call your API to decide what to do. Your API returns a TransferFailedResponse JSON object with one of: a retry transferService, a useNamedTransferService name, or a custom sessionUpdate.

3

TransferFailedDefaults

The built-in fallback, used when nothing above is configured or all return null. The AI apologizes and ends the call.

Built-in Failure Defaults

When no failure handler is configured, VNS routes the AI back with these instructions:

{
  "type": "session.update",
  "session": {
    "type": "realtime",
    "instructions": "The call transfer was unsuccessful. Apologize to the caller and let them know the transfer could not be completed at this time. Suggest they try calling back later. Then call vns_end_conversation to end the call.\n\n## Tool Call Rules\nYou must call vns_end_conversation after delivering your message.",
    "tools": [
      {
        "name": "vns_end_conversation",
        "description": "Call this function to end the conversation after delivering the transfer failure message.",
        "type": "function",
        "parameters": {
          "type": "object",
          "properties": {
            "farewell": {
              "type": "string",
              "description": "The farewell you would like to say to the caller."
            }
          },
          "required": ["farewell"]
        }
      }
    ]
  }
}

Dynamic Transfer Service via API

If you want your server to decide which transfer service to use at call time — based on time of day, caller history, or queue availability — set onTransferToolName to a tool name in your toolkit. When the AI calls vns_transfer_call, VoiceElements will call your API endpoint and expect a complete TransferService JSON object back.

// In VoiceElements_Instructions:
"onTransferToolName": "transfer_request"

Your endpoint returns a complete TransferService object:

{
  "name": "live-agent",
  "callerId": "+18005551234",
  "callerIdName": "Acme Support",
  "attended": false,
  "useVnsNumberAsCallerId": false,
  "dialMode": "sequential",
  "transferNumbers": [
    { "number": "+13035551000", "dialTime": 20 }
  ]
}

Additional Configuration Fields

Field Description
addSecondsToMaxTimeOnTransfer Extends the maximum call duration by this many seconds once a transfer connects. Default: 7200 (2 hours).
onTransferToolName Tool name to call for dynamic transfer service resolution. Your endpoint returns a full TransferService object.
onTransferFailedToolName Tool name to call when all transfer attempts fail. Your endpoint returns a TransferFailedResponse specifying how to proceed.

Ready to Automate Your Phone Lines?

See Voice Nexus in action. Book a live demo with our team and we'll walk you through setup, integrations, and pricing.