Skip to main content

Call Transfers

Call transfers enable your AI agents to route calls to human agents, external phone numbers, or other systems when needed. This critical capability allows you to build hybrid workflows where AI handles routine interactions and humans address complex or sensitive issues.

What Are Call Transfers?

Call transfers hand off an active conversation from your AI agent to another destination—typically a human agent, a different phone number, or an external system. The transfer process can be immediate (cold transfer), consultative (warm transfer), or programmatically determined (HTTP transfer). Common Use Cases:
  • Escalating complex technical issues from AI to human support
  • Routing sales inquiries to qualified sales representatives
  • Transferring billing questions to payment specialists
  • After-hours routing to on-call emergency services
  • Multi-level support workflows (tier 1 AI, tier 2 human)
  • Geographic routing to regional offices
  • VIP customer routing to dedicated account managers
Best Practice: Use AI agents to handle 70-80% of routine inquiries, then transfer the remaining 20-30% that require human expertise, empathy, or decision-making authority.

Transfer Types Comparison

Dasha BlackBox supports three distinct transfer methods, each optimized for different scenarios:
FeatureCold TransferWarm TransferHTTP Transfer
SpeedFastestSlower (consultation required)Variable (webhook latency)
Context SharingNoneFull conversation contextConfigurable
AI Agent RoleDisconnects immediatelyBriefs human, then disconnectsRoutes based on logic
DestinationFixed phone/SIPFixed phone/SIPDynamic (determined by webhook)
Best ForSimple routing, IVR-styleComplex issues, VIP customersBusiness rule routing, load balancing
User ExperienceFast but impersonalPersonal, smooth handoffDepends on implementation
Configuration ComplexityLowMediumHigh
Fallback SupportNoNoYes (via fallback transfer)
Caller ID ModeN/AConfigurable (user or agent phone)Configurable via warm fallback

Transfer Type Decision Tree

Do you need dynamic routing based on business logic?
├─ Yes → Use HTTP Transfer
└─ No → Does the human agent need context before talking to caller?
    ├─ Yes → Use Warm Transfer
    └─ No → Use Cold Transfer

Cold Transfer (Blind Transfer)

Cold transfer immediately routes the call to a destination phone number or SIP endpoint. The AI agent disconnects as soon as the transfer begins, and the caller connects directly to the new destination without any introduction or context sharing.

How Cold Transfer Works

When to Use Cold Transfer

Ideal Scenarios:
  • IVR-Style Routing: “Press 1 for sales, 2 for support” equivalents
  • Department Routing: Simple redirection to known departments
  • After-Hours Forwarding: Route to voicemail or answering service
  • Emergency Escalation: Immediate connection to emergency contacts
  • High-Volume Routing: Minimize latency for simple redirects
Not Recommended For:
  • Complex issues requiring context transfer
  • VIP customers expecting personalized service
  • Situations where availability confirmation is needed
  • Cases where the caller’s issue needs explanation

Configuring Cold Transfer

Step-by-Step Configuration:
  1. Navigate to your agent’s Features tab
  2. Locate the Call Transfer section
  3. Toggle Enable Call Transfer to ON
  4. Select Cold Transfer from the transfer type dropdown
  5. Enter the destination endpoint:
    • Phone number in E.164 format: +1-555-123-4567
    • SIP URI: sip:support@example.com
  6. (Optional) Add transfer routes for multiple destinations
  7. Click Save Agent
Cold transfer configurationConfigure cold transfer with destination endpoint

Phone Number Format Requirements

All phone numbers must use E.164 format for transfers to work correctly: E.164 Format Rules:
  • Start with + (plus sign)
  • Include country code (1-3 digits)
  • Include area code and local number
  • No spaces, dashes, or parentheses
  • Maximum 15 digits total
Valid Examples:
+1-555-123-4567    ✓ (US number with hyphens allowed)
+14155551234       ✓ (US number, compact)
+44-20-7123-4567   ✓ (UK number)
+86-10-1234-5678   ✓ (China number)
Invalid Examples:
555-123-4567       ✗ (Missing country code and +)
1-555-123-4567     ✗ (Missing + prefix)
(555) 123-4567     ✗ (Invalid formatting)
+1 555 123 4567    ✗ (Spaces not allowed in some systems)
Invalid Phone Numbers: Using incorrect phone number formats will cause transfer failures. Always validate phone numbers against E.164 format before deployment.

SIP URI Format

For SIP endpoints, use standard SIP URI format:
sip:username@domain
sip:support@company.com
sip:+15551234567@sip.provider.com

Warm Transfer (Attended Transfer)

Warm transfer allows the AI agent to consult with the destination (typically a human agent) before completing the transfer. The AI can brief the human on the caller’s situation, confirm availability, and ensure a smooth handoff.

How Warm Transfer Works

When to Use Warm Transfer

Ideal Scenarios:
  • Complex Issues: Technical problems requiring detailed context
  • VIP Customers: High-value customers deserving personalized service
  • Sensitive Situations: Billing disputes, complaints, legal matters
  • Availability Confirmation: Ensure human agent is available before transfer
  • Quality Assurance: Human can decline transfer if not qualified
  • Context Preservation: Caller doesn’t need to repeat information
Not Recommended For:
  • High-volume, simple routing (use cold transfer)
  • After-hours scenarios (no human available)
  • Time-sensitive emergencies (cold transfer is faster)
  • Situations where consultation adds no value

Configuring Warm Transfer

Step-by-Step Configuration:
  1. Navigate to your agent’s Features tab
  2. Toggle Enable Call Transfer to ON
  3. Select Warm Transfer from the transfer type dropdown
  4. Enter the destination endpoint (phone or SIP)
  5. Configure warm transfer behavior:
    • Caller ID Mode: Select which phone number the human agent sees (Agent Phone Number or User Phone Number)
    • Consultation Script: What AI says to human during consultation
    • Customer Hold Message: What caller hears during consultation
    • Continue After Operator Disconnected: Resume AI if human declines
    • Continue Recording: Record the transferred conversation
  6. Click Save Agent
Warm transfer configurationConfigure warm transfer with consultation settings

Warm Transfer Behavior Options

Interaction with Operator:
OptionDescriptionUse Case
smart_v1AI dynamically briefs human based on conversation contextComplex, variable issues
staticAI uses pre-defined script every timeConsistent, simple briefings
Additional Settings:
  • sayPhraseToCustomer: What the caller hears while AI consults with human
    • Example: "Please hold while I connect you with a specialist"
  • continueAfterOperatorDisconnected: If true, AI resumes if human declines or disconnects
    • Example: Human says “I can’t take this call” → AI continues with caller
  • continueRecordingInTransfer: If true, continues recording after transfer
    • Required for compliance in some industries

Advanced Warm Transfer Parameters

This section documents additional warm transfer parameters for advanced configurations.

Continue Recognition In Transfer

The continueRecognitionInTransfer parameter controls whether speech recognition continues during the warm transfer phase. This is useful when the AI agent needs to listen to the conversation between the caller and the human operator during the transfer.
ParameterTypeDefaultDescription
continueRecognitionInTransferbooleanfalseContinue speech recognition during the transfer
When to Enable:
  • Supervisor Monitoring: When AI needs to hear the transfer conversation for quality assurance
  • Context Extraction: When you want to capture additional information from the human-to-human handoff
  • Training Data: When collecting conversation data for AI model improvement
  • Compliance: When regulations require full conversation capture
API Example:
{
  config: {
    features: {
      transfer: {
        type: "warm",
        isEnabled: true,
        endpointDestination: "+1-555-0200",
        continueRecognitionInTransfer: true, // AI continues listening during transfer
        continueRecordingInTransfer: true,
        interactionWithOperator: {
          type: "smartV1"
        }
      }
    }
  }
}
Enabling continueRecognitionInTransfer may have privacy and compliance implications. Ensure you have appropriate consent and disclosures in place before enabling this feature.

Caller ID Mode

The Caller ID Mode setting determines which phone number is displayed to the transfer destination (human agent) when the AI initiates a warm transfer call. This setting is crucial for helping human agents identify and prepare for incoming transferred calls. Available Modes:
ModeValueDescription
Agent Phone NumberagentPhoneNumberUses the AI agent’s configured outbound SIP fromUser as the caller ID. The human agent sees the company’s number. This is the default.
User Phone NumberuserPhoneNumberUses the original caller’s phone number as the caller ID. The human agent sees the customer’s number on their phone.
When callerIdMode is not specified or set to null, the system defaults to agentPhoneNumber behavior.

When to Use Each Mode

Use agentPhoneNumber (default) when:
  • You want a consistent, recognizable internal number for all transfers
  • Human agents work in a call center that routes by internal extension
  • Privacy requirements prevent sharing customer phone numbers with agents
  • You need to distinguish AI-transferred calls from direct customer calls
  • Your phone system filters or routes calls based on caller ID
Use userPhoneNumber when:
  • Human agents need to identify the caller before answering
  • Agents use CRM screen pops that match on caller ID
  • You want agents to see the customer’s callback number
  • Agents use caller ID to pull up customer records
  • Internal routing systems rely on caller ID for prioritization

Configuring Caller ID Mode

Step-by-Step Configuration:
  1. Navigate to your agent’s Features tab
  2. Enable Call Transfer and select Warm Transfer
  3. Find the Caller ID Mode dropdown
  4. Select your preferred mode:
    • Agent Phone Number (default): AI agent’s configured phone number appears as caller ID
    • User Phone Number: Customer’s phone number appears as caller ID
  5. Click Save Agent
Caller ID mode configurationConfigure which phone number the human agent sees during warm transfer

Caller ID Mode API Reference

FieldTypeRequiredValuesDescription
callerIdModestringNo"userPhoneNumber", "agentPhoneNumber"Determines the caller ID shown to the transfer destination
SIP Configuration Required: When using agentPhoneNumber mode, ensure your agent has a properly configured outbound SIP fromUser. Without this configuration, the transfer may fail or show an unexpected caller ID.

Operator Name

The operatorName parameter allows you to provide a name reference for the human operator in the conversation. This name is used by the AI when generating contextual phrases, particularly when using threeway messaging with smartV1 behavior.
ParameterTypeDefaultDescription
operatorNamestringnullName reference for the operator in generated phrases
Use Cases:
  • Personalized Handoffs: GPT can include the operator’s name or role in generated handoff phrases
  • Context for Threeway Messaging: When using smartV1 threeway messaging, the operator name provides context for generating appropriate introduction phrases
  • Conversation Context: The AI can reference the operator by name during the transfer process
API Example:
{
  config: {
    features: {
      transfer: {
        type: "warm",
        isEnabled: true,
        endpointDestination: "+1-555-0200",
        operatorName: "Technical Support Specialist",
        threewayMessaging: {
          type: "smartV1"
        }
      }
    }
  }
}

Threeway Messaging

Threeway messaging enables a unified phrase to be spoken to BOTH the customer and the human operator simultaneously right before the bridge channel is executed. This feature creates a cohesive handoff experience where both parties hear the same announcement.
How It Works: The threeway messaging phrase is delivered via TTS to both the parent conversation (customer) and the warm transfer child block (operator) for simultaneous delivery. This occurs right before the call is bridged.
Threeway Messaging vs. Other Messaging:
FeatureWho HearsWhenPurpose
sayPhraseToCustomerCustomer onlyBefore consultationSet customer expectations
sayPhraseToOperator (in interactionWithOperator.static)Operator onlyDuring consultationBrief operator privately
threewayMessagingBoth simultaneouslyBefore bridgeUnified handoff announcement
ThreewaySmartV1Behavior
Smart V1 behavior uses GPT to generate a contextual handoff phrase based on the conversation history and optional additional instructions. The AI crafts an appropriate announcement that makes sense for both parties.
FieldTypeRequiredDescription
type"smartV1"YesType discriminator
additionalInstructionsstringNoOptional instructions to guide GPT in generating the phrase
When to Use:
  • Variable Contexts: When handoff situations vary and need contextual messaging
  • Dynamic Conversations: When the phrase should reflect the specific conversation
  • Personalized Experience: When you want GPT to craft relevant, natural-sounding announcements
API Example:
{
  config: {
    features: {
      transfer: {
        type: "warm",
        isEnabled: true,
        endpointDestination: "+1-555-0200",
        operatorName: "Billing Specialist",
        threewayMessaging: {
          type: "smartV1",
          additionalInstructions: "Keep it professional and brief. Include a summary of the customer's billing issue."
        },
        interactionWithOperator: {
          type: "smartV1"
        }
      }
    }
  }
}
Example Generated Phrases: Based on conversation context, GPT might generate phrases like:
  • “I’m now connecting you with our billing specialist to help resolve your invoice discrepancy.”
  • “You’ll be speaking with a technical support representative who can assist with your network configuration issue.”
  • “Connecting you both now. Sarah needs help with her premium account upgrade.”
ThreewayStaticBehavior
Static behavior uses a predefined phrase that is spoken unchanged to both parties. This provides consistent, predictable messaging for standardized handoffs.
FieldTypeRequiredDescription
type"static"YesType discriminator
phrasestringNoThe exact phrase to speak to both parties
When to Use:
  • Consistent Messaging: When you need the same phrase every time
  • Compliance Requirements: When exact wording is mandated
  • Simple Handoffs: When context-specific phrases aren’t needed
  • Predictable Workflows: When standardization is preferred
API Example:
{
  config: {
    features: {
      transfer: {
        type: "warm",
        isEnabled: true,
        endpointDestination: "+1-555-0200",
        threewayMessaging: {
          type: "static",
          phrase: "Connecting you now. Please hold while the line is bridged."
        },
        interactionWithOperator: {
          type: "smartV1"
        }
      }
    }
  }
}
Example Static Phrases:
  • “Connecting you now”
  • “Please hold while I connect you”
  • “You are now being connected to a representative”
  • “I’m bridging this call now. One moment please.”
Threeway Messaging API Reference
FieldTypeRequiredDefaultDescription
threewayMessagingobjectNonullThreeway messaging configuration
threewayMessaging.type"smartV1" | "static"Yes-Behavior type discriminator
threewayMessaging.additionalInstructionsstringNonullAdditional GPT instructions (smartV1 only)
threewayMessaging.phrasestringNonullStatic phrase to speak (static only)

Say Phrase To Operator (Static Behavior)

When using interactionWithOperator with type: "static", you can configure a phrase to say to the human operator before bridging the call. This is part of the static interaction behavior and is separate from threeway messaging—it’s heard by the operator only.
FieldTypeRequiredDescription
sayPhraseToOperatorobjectNoPhrase configuration for operator-only messaging
sayPhraseToOperator.phrasestringYesThe phrase to say to the operator
sayPhraseToOperator.beforeOperatorbooleanNoIf true, says phrase before waiting for operator to answer. Default: false
API Example:
{
  config: {
    features: {
      transfer: {
        type: "warm",
        isEnabled: true,
        endpointDestination: "+1-555-0200",
        sayPhraseToCustomer: "Please hold while I connect you with a specialist.",
        interactionWithOperator: {
          type: "static",
          waitFirstAnswerFromOperator: true,
          waitChecksTimeoutInS: 4,
          sayPhraseToOperator: {
            phrase: "Hello, this is the AI assistant. I have a customer with a billing dispute who needs your help.",
            beforeOperator: false
          }
        }
      }
    }
  }
}
Combining Messaging Features: You can use sayPhraseToCustomer (customer only), sayPhraseToOperator in static behavior (operator only), and threewayMessaging (both parties) together for complete control over what each party hears at each stage of the transfer.

Complete Warm Transfer Parameter Reference

ParameterTypeDefaultDescription
type"warm"-Transfer type discriminator
endpointDestinationstring-Phone number or SIP URI to transfer to
descriptionstring-Human-readable description of the transfer
isEnabledbooleantrueWhether this transfer is enabled
sayPhraseToCustomerstringnullPhrase spoken to customer before consultation
continueAfterOperatorDisconnectedbooleanfalseResume AI if operator disconnects/declines
continueRecordingInTransferbooleantrueContinue recording during transfer
continueRecognitionInTransferbooleanfalseContinue speech recognition during transfer
callerIdMode"userPhoneNumber" | "agentPhoneNumber""agentPhoneNumber"Caller ID shown to operator
operatorNamestringnullName reference for operator in generated phrases
threewayMessagingobjectnullUnified messaging to both parties before bridge
interactionWithOperatorobjectnullOperator consultation behavior (smartV1 or static)
transferRoutesarraynullNamed routes for LLM-driven destination selection
failoverBehaviorobjectnullBehavior when transfer fails
sipobjectnullOptional SIP configuration override for the transfer

Transfer Success and Failure Handling

Successful Transfer Flow:
1. AI initiates warm transfer
2. AI calls human agent
3. Human agent answers
4. AI briefs human on situation
5. Human confirms ability to help
6. AI completes transfer
7. Caller and human are connected
8. AI disconnects
Failure Scenarios: Human Doesn’t Answer:
// If continueAfterOperatorDisconnected: true
AI: "I apologize, but I couldn't reach a specialist right now. Let me see
what else I can do to help you."
[AI continues conversation]

// If continueAfterOperatorDisconnected: false
AI: "I'm sorry, but no specialist is available at the moment. Would you
like me to take a message or schedule a callback?"
[Call continues with AI for message/callback scheduling]
Human Declines Transfer:
// Human says "I can't take this call"
AI (to customer): "I apologize, but our specialist isn't available to help
with this specific issue right now. Let me see if I can connect you with
someone else, or we can schedule a callback."

HTTP Transfer (Programmatic Routing)

HTTP transfer uses a webhook to determine the transfer destination dynamically based on business logic, caller data, CRM integrations, or real-time availability checks. This enables sophisticated routing strategies beyond simple fixed endpoints.

How HTTP Transfer Works

When to Use HTTP Transfer

Ideal Scenarios:
  • CRM Integration: Route to assigned account manager or sales rep
  • Load Balancing: Distribute calls across available agents
  • Business Hours Routing: Route to on-call vs regular support based on time
  • Geographic Routing: Route based on caller’s location or area code
  • Priority Routing: VIP customers to dedicated agents
  • Skill-Based Routing: Route to agent with specific expertise
  • Availability Checking: Verify agent availability before transfer
  • Multi-Tenant Systems: Route to customer-specific support teams
Not Recommended For:
  • Simple, fixed routing (use cold transfer)
  • When webhook latency is unacceptable
  • When fallback complexity isn’t justified

Configuring HTTP Transfer

Step-by-Step Configuration:
  1. Navigate to your agent’s Features tab
  2. Toggle Enable Call Transfer to ON
  3. Select HTTP Transfer from the transfer type dropdown
  4. Enter webhook configuration:
    • Webhook URL: Your routing endpoint
    • Headers: Authentication tokens, API keys
    • Timeout: Max wait time for webhook response (default: 5s)
  5. Configure fallback transfer (optional):
    • Select fallback type (cold or warm)
    • Enter fallback destination
  6. Click Save Agent
HTTP transfer configurationConfigure HTTP transfer with webhook endpoint

HTTP Transfer Webhook Request Format

When a transfer is triggered, Dasha BlackBox sends a POST request to your webhook URL: Request Headers:
POST /webhooks/transfer-routing HTTP/1.1
Host: api.yourcompany.com
Content-Type: application/json
Authorization: Bearer YOUR_WEBHOOK_API_KEY
X-Dasha BlackBox-Event: transfer.requested
X-Dasha BlackBox-Call-Id: 660e8400-e29b-41d4-a716-446655440001
X-Dasha BlackBox-Agent-Id: 550e8400-e29b-41d4-a716-446655440000
Request Body:
{
  "callId": "660e8400-e29b-41d4-a716-446655440001",
  "agentId": "550e8400-e29b-41d4-a716-446655440000",
  "agentName": "Smart Routing Agent",
  "callerNumber": "+1-555-987-6543",
  "callDirection": "inbound",
  "timestamp": "2025-10-20T15:30:00Z",
  "conversationContext": {
    "customerName": "John Doe",
    "accountEmail": "john@example.com",
    "inquiryType": "upgrade",
    "urgency": "medium"
  },
  "additionalData": {
    "customerId": "cust_789",
    "accountTier": "premium"
  }
}
Field Descriptions:
  • callId: Unique identifier for the call
  • agentId: ID of the AI agent handling the call
  • agentName: Name of the AI agent
  • callerNumber: Phone number of the caller (E.164 format)
  • callDirection: "inbound" or "outbound"
  • timestamp: ISO 8601 timestamp when transfer was requested
  • conversationContext: Information extracted from conversation
  • additionalData: Custom metadata from call creation

HTTP Transfer Webhook Response Format

Your webhook must return a JSON response within the timeout period (default: 5 seconds): Successful Response (200 OK):
{
  "transferTo": "+1-555-0201",
  "transferType": "warm",
  "context": {
    "assignedRep": "Jane Smith",
    "repId": "rep_456",
    "customerTier": "premium",
    "accountValue": "$50,000"
  },
  "briefing": "Customer John Doe wants to upgrade premium account. Account value: $50k. Assigned rep: Jane Smith."
}
Response Fields:
FieldTypeRequiredDescription
transferTostringYesDestination phone number (E.164) or SIP URI
transferTypestringNo"cold" or "warm" (default: "cold")
contextobjectNoAdditional data to log with transfer
briefingstringNoFor warm transfers, what AI says to human during consultation
Error Response (4xx or 5xx): If your webhook returns an error or times out, the fallback transfer (if configured) will be used:
{
  "error": "No available agents for this account",
  "errorCode": "NO_AGENTS_AVAILABLE",
  "useFallback": true
}
Webhook Timeouts: Ensure your webhook responds within the timeout period (default: 5 seconds). Slow responses will trigger fallback transfers and degrade user experience.

Webhook Implementation Examples

const express = require('express');
const app = express();
app.use(express.json());

app.post('/webhooks/transfer-routing', async (req, res) => {
  try {
    const {
      callId,
      callerNumber,
      conversationContext,
      additionalData
    } = req.body;

    // Example: Route based on account tier
    const accountTier = additionalData?.accountTier || 'standard';
    const inquiryType = conversationContext?.inquiryType;

    let transferDestination;
    let transferType = 'cold';

    // Routing logic
    if (accountTier === 'premium') {
      // Premium customers get warm transfer to dedicated rep
      const assignedRep = await getAssignedRep(additionalData.customerId);
      transferDestination = assignedRep.phoneNumber;
      transferType = 'warm';
    } else if (inquiryType === 'billing') {
      // Billing goes to billing department
      transferDestination = '+1-555-0100';
    } else if (inquiryType === 'technical') {
      // Technical to support queue
      transferDestination = await getNextAvailableAgent('technical');
    } else {
      // Default to general support
      transferDestination = '+1-555-0200';
    }

    // Return routing decision
    res.json({
      transferTo: transferDestination,
      transferType: transferType,
      context: {
        routingReason: `${accountTier} tier - ${inquiryType} inquiry`,
        assignedAt: new Date().toISOString()
      },
      briefing: `Customer ${conversationContext.customerName} from ${accountTier} tier needs help with ${inquiryType}.`
    });

  } catch (error) {
    console.error('Routing error:', error);
    // Return error to trigger fallback
    res.status(500).json({
      error: 'Routing failed',
      errorCode: 'INTERNAL_ERROR',
      useFallback: true
    });
  }
});

app.listen(3000, () => {
  console.log('Transfer routing webhook listening on port 3000');
});

Configuring Transfer Tools (Function Calling)

For more control over when transfers occur, you can define transfer as a tool that the LLM explicitly calls:

Transfer Tool Schema

{
  "name": "transfer_to_human",
  "description": "Transfer the call to a human agent when the AI cannot resolve the issue or when explicitly requested by the caller",
  "schema": {
    "type": "object",
    "properties": {
      "reason": {
        "type": "string",
        "description": "Reason for transfer (e.g., 'complex technical issue', 'billing dispute', 'customer request')"
      },
      "department": {
        "type": "string",
        "enum": ["billing", "technical", "sales", "general"],
        "description": "Department to transfer to"
      },
      "urgency": {
        "type": "string",
        "enum": ["low", "medium", "high", "critical"],
        "description": "Urgency level of the issue"
      },
      "context": {
        "type": "string",
        "description": "Brief summary of conversation for the receiving agent"
      }
    },
    "required": ["reason", "department"]
  },
  "webhook": {
    "url": "https://api.yourcompany.com/webhooks/transfer-handler"
  }
}

Transfer Tool Webhook Handler

app.post('/webhooks/transfer-handler', async (req, res) => {
  const { toolArguments, callId } = req.body;
  const { reason, department, urgency, context } = toolArguments;

  // Determine transfer destination based on department
  const destinations = {
    'billing': '+1-555-0100',
    'technical': '+1-555-0101',
    'sales': '+1-555-0102',
    'general': '+1-555-0103'
  };

  const transferTo = destinations[department] || destinations['general'];

  // Log transfer for analytics
  await logTransfer(callId, {
    reason,
    department,
    urgency,
    context,
    destination: transferTo
  });

  // Return transfer instruction
  res.json({
    success: true,
    message: `Transferring to ${department} department`,
    transferTo: transferTo,
    transferType: urgency === 'critical' ? 'cold' : 'warm',
    briefing: context || `Transfer reason: ${reason}`
  });
});

Monitoring Transfers in Call Inspector

The Call Inspector provides detailed visibility into transfer execution and outcomes:

Transfer Event Details

When you open a call with transfers in the Call Inspector, you’ll see: Transfer Initiation:
  • Timestamp when transfer was triggered
  • Transfer type (cold, warm, HTTP)
  • Destination endpoint (phone number or SIP URI)
  • Reason for transfer (from conversation context)
Webhook Execution (HTTP Transfers):
  • Request payload sent to webhook
  • Response received from webhook
  • Latency (time to receive response)
  • Routing decision made
Transfer Outcome:
  • Success or failure status
  • Connection time to destination
  • Duration of consultation (warm transfers)
  • Fallback usage (if primary transfer failed)
Transfer details in call inspector View complete transfer execution details and outcomes

Transfer Metrics to Track

Success Metrics:
  • Transfer completion rate (percentage of successful transfers)
  • Average transfer connection time
  • Warm transfer consultation duration
  • Webhook response latency (HTTP transfers)
Failure Metrics:
  • Transfer failure rate
  • Reasons for failure (no answer, busy, invalid number)
  • Fallback usage rate
  • Webhook timeout rate
Quality Metrics:
  • Post-transfer call duration (indicates if human resolved issue)
  • Customer satisfaction after transfer
  • Number of re-transfers (bouncing between departments)
  • Time to resolution after transfer

Use Cases and Examples

Sales Qualification to Human

Scenario: AI qualifies leads, then transfers hot leads to sales reps
// Agent configuration
{
  config: {
    llmConfig: {
      prompt: `You are a sales qualification assistant. Ask about:
- Company size
- Budget
- Timeline
- Decision maker status

If qualified (company size above 50 employees, budget above $10k, timeline under 3 months),
transfer to sales team. Otherwise, offer to send materials via email.`
    },
    transfer: {
      type: "http",
      webhook: {
        url: "https://api.yourcompany.com/webhooks/sales-routing"
      }
    }
  }
}

// Webhook determines best sales rep
app.post('/webhooks/sales-routing', async (req, res) => {
  const { conversationContext } = req.body;
  const { companySize, budget, industry } = conversationContext;

  // Route to specialized sales rep
  let salesRep;
  if (industry === 'healthcare') {
    salesRep = await getAvailableRep('healthcare');
  } else if (companySize above 500) {
    salesRep = await getAvailableRep('enterprise');
  } else {
    salesRep = await getAvailableRep('smb');
  }

  res.json({
    transferTo: salesRep.phone,
    transferType: 'warm',
    briefing: `Qualified lead: ${companySize} employees, $${budget} budget, ${industry} industry`
  });
});

Support Escalation Path

Scenario: Tier 1 AI support, escalate to human for complex issues
// Agent with escalation tool
{
  config: {
    llmConfig: {
      prompt: `You are tier 1 technical support. Try to resolve:
- Password resets
- Basic connectivity issues
- Account activation

Escalate to human if:
- Customer tried your suggestions without success
- Issue requires backend access
- Customer is frustrated or angry
- Issue is business-critical`
    },
    tools: [
      {
        name: "escalate_to_tier2",
        description: "Escalate to tier 2 human support for complex issues",
        schema: {
          type: "object",
          properties: {
            issue_summary: { type: "string" },
            steps_tried: {
              type: "array",
              items: { type: "string" }
            },
            customer_sentiment: {
              type: "string",
              enum: ["calm", "frustrated", "angry"]
            }
          },
          required: ["issue_summary", "steps_tried"]
        },
        webhook: {
          url: "https://api.yourcompany.com/webhooks/tier2-escalation"
        }
      }
    ]
  }
}

After-Hours Routing

Scenario: Different transfer destinations based on business hours
app.post('/webhooks/transfer-routing', async (req, res) => {
  const now = new Date();
  const hour = now.getHours();
  const dayOfWeek = now.getDay();

  // Business hours: Mon-Fri 9am-5pm
  const isBusinessHours = (
    dayOfWeek >= 1 && dayOfWeek <= 5 &&
    hour >= 9 && hour < 17
  );

  if (isBusinessHours) {
    // Transfer to regular support team
    res.json({
      transferTo: '+1-555-0100',
      transferType: 'warm'
    });
  } else {
    // Transfer to on-call emergency line
    res.json({
      transferTo: '+1-555-0911',
      transferType: 'cold',
      context: {
        afterHours: true,
        routedAt: now.toISOString()
      }
    });
  }
});

Geographic Routing

Scenario: Route to regional support based on area code
app.post('/webhooks/transfer-routing', async (req, res) => {
  const { callerNumber } = req.body;

  // Extract area code from caller number
  const areaCode = callerNumber.substring(2, 5); // Extract from +1-XXX-...

  // Map area codes to regions
  const regionMapping = {
    // East Coast (NYC, Boston, DC area codes)
    '212': '+1-555-0201', '646': '+1-555-0201', '617': '+1-555-0201',
    // West Coast (LA, SF, Seattle area codes)
    '213': '+1-555-0202', '415': '+1-555-0202', '206': '+1-555-0202',
    // Central (Chicago, Dallas area codes)
    '312': '+1-555-0203', '214': '+1-555-0203'
  };

  const destination = regionMapping[areaCode] || '+1-555-0200'; // Default

  res.json({
    transferTo: destination,
    transferType: 'cold',
    context: {
      region: getRegionName(destination),
      areaCode: areaCode
    }
  });
});

Best Practices

Clear Transfer Messaging

Do:
  • Explain why you’re transferring: "This requires specialist expertise, so I'm connecting you with our technical team"
  • Set expectations: "This should take just a moment" or "The specialist will pick up in about 30 seconds"
  • Confirm before transferring: "Would you like me to connect you with a specialist?"
Don’t:
  • Transfer without explanation: "Please hold" [transfer]
  • Make promises you can’t keep: "They'll definitely fix this right away"
  • Use negative language: "I can't help you, let me find someone who can"

Fallback Handling

Always configure fallback transfers for HTTP transfers:
{
  transfer: {
    type: "http",
    webhook: { url: "..." },
    fallback: {
      type: "cold",
      endpointDestination: "+1-555-0100" // Always-available general support
    }
  }
}
Fallback Triggers:
  • Webhook timeout (above 5 seconds)
  • Webhook returns error status (4xx, 5xx)
  • Webhook returns useFallback: true
  • Network errors preventing webhook call

Context Preservation

For warm transfers, ensure the AI provides adequate context: Good Briefing:
"Hi, this is the AI assistant. I have Sarah Johnson on the line. She's having
trouble accessing her account after a password reset. She's tried resetting
twice without success. This is a high-priority issue as she needs access for
a client meeting in 30 minutes. Are you able to assist?"
Poor Briefing:
"I have a customer with an account issue."

Phone Number Validation

Validate all transfer destinations before deployment:
function isValidE164(phoneNumber) {
  const e164Regex = /^\+[1-9]\d{1,14}$/;
  return e164Regex.test(phoneNumber);
}

// Validate before configuring transfer
if (!isValidE164(transferDestination)) {
  throw new Error(`Invalid phone number: ${transferDestination}`);
}

Testing Strategy

Pre-Production Testing:
  1. Test all transfer routes with real phone numbers
  2. Verify fallback handling (disconnect webhook to test)
  3. Test transfers during different business hours
  4. Measure transfer connection times
  5. Review transfer conversation transcripts for quality
Production Monitoring:
  1. Track transfer success rate (target: above 95%)
  2. Monitor webhook response times (target: under 2 seconds)
  3. Alert on high transfer failure rates
  4. Review transferred call recordings periodically
  5. Collect feedback from receiving human agents

Troubleshooting Transfer Issues

Transfer Fails to Connect

Symptoms:
  • Call drops after transfer attempt
  • Caller hears busy signal or “number not reachable”
  • Transfer shows as “Failed” in call inspector
Debugging Steps:
  1. Verify phone number format (E.164)
    // Correct
    +1-555-123-4567
    
    // Incorrect
    555-123-4567 ✗ (missing country code and +)
    1-555-123-4567 ✗ (missing +)
    
  2. Test destination number externally
    • Can you call the number from your phone?
    • Is the number active and accepting calls?
    • Check for call forwarding or blocking
  3. Review SIP configuration (for SIP URIs)
    • Verify SIP server is reachable
    • Check SIP credentials
    • Test SIP endpoint with SIP testing tools
  4. Check transfer limits
    • Some carriers block transfers to certain number types
    • Verify no rate limiting on destination

Webhook Timeouts (HTTP Transfer)

Symptoms:
  • HTTP transfers fall back to default destination
  • Call inspector shows “Webhook timeout”
  • Transfers take longer than expected
Debugging Steps:
  1. Measure webhook response time
    app.post('/webhooks/transfer-routing', async (req, res) => {
      const startTime = Date.now();
    
      // Your routing logic
      const result = await determineDestination(req.body);
    
      const duration = Date.now() - startTime;
      console.log(`Webhook responded in ${duration}ms`);
    
      res.json(result);
    });
    
  2. Optimize slow queries
    • Cache CRM lookups
    • Use indexed database queries
    • Implement connection pooling
    • Consider async processing with immediate response
  3. Increase timeout (if justified)
    {
      transfer: {
        webhook: {
          url: "...",
          customSettings: {
            timeout: 8000 // Increase to 8 seconds
          }
        }
      }
    }
    

Warm Transfer Consultation Fails

Symptoms:
  • AI calls human, but human doesn’t answer
  • Transfer completes but without consultation
  • Caller complains they had to repeat information
Debugging Steps:
  1. Verify human agent availability
    • Is the phone number monitored during operating hours?
    • Are agents trained to answer transfers?
    • Check for call forwarding issues
  2. Adjust timeout for consultation phase
    • Some agents need more time to answer
    • Consider using ring group/queue instead of direct number
  3. Configure proper fallback behavior
    {
      transfer: {
        type: "warm",
        continueAfterOperatorDisconnected: true, // AI resumes if no answer
        sayPhraseToCustomer: "I'm connecting you now. If no one answers, I'll continue helping you."
      }
    }
    

Context Not Preserved

Symptoms:
  • Caller has to repeat information to human
  • Human agent unaware of conversation history
  • Poor user experience after transfer
Solutions:
  1. Use warm transfers instead of cold
  2. Configure detailed briefing in interactionWithOperator
  3. Send call metadata to human agent’s system
  4. Use CRM integration to display caller history

High Transfer Rates

Symptoms:
  • More than 40-50% of calls transfer to humans
  • AI transfers for issues it should handle
  • Transfer rate increasing over time
Debugging Steps:
  1. Review transfer reasons in call inspector
    • Are transfers justified?
    • Could AI handle these with better prompts?
    • Are customers explicitly requesting humans?
  2. Improve AI capabilities
    • Add tools for common transfer reasons
    • Enhance system prompt with more examples
    • Train on actual transferred conversations
  3. Adjust transfer triggers
    • Increase threshold for escalation
    • Add clarifying questions before transfer
    • Offer alternatives to transfer

Next Steps

  • Tools & Functions: Tools & Functions - Configure function calling for advanced workflows
  • Webhook Events: Webhook Events - Handle call lifecycle events
  • Call Inspector: Call Inspector - Debug and monitor transfers
  • Inbound Calls: Inbound Calls - Configure inbound call routing with transfers

API Cross-Refs