Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.blackbox.dasha.ai/llms.txt

Use this file to discover all available pages before exploring further.

Route calls dynamically using your business logic. HTTP transfers call your webhook with conversation context — your system decides the destination based on CRM data, availability, or skill requirements. What you’ll learn: Webhook configuration, request/response schemas, fallback handling, and dynamic routing patterns.

How HTTP Transfer Works

  1. Agent determines the caller needs transfer
  2. Agent calls your webhook endpoint with conversation context
  3. Your webhook returns routing decision: destination, type (warm/cold), and configuration
  4. Agent executes the transfer as specified by webhook response
  5. If webhook fails, the agent uses the fallback transfer

When to Use HTTP Transfer

Best for:
  • Dynamic routing based on agent availability
  • Skill-based routing (route to agents with specific expertise)
  • CRM-integrated routing (based on customer tier, history)
  • Workload balancing across teams
  • Complex business rules that change dynamically
  • Geographic or language-based routing
Choose simpler transfers when:
  • Static routing to fixed numbers
  • Simple department routing
  • No integration needs

Configuring HTTP Transfer

Step 1: Enable HTTP Transfer

  1. Open your agent’s configuration
  2. Navigate to the Features tab
  3. Scroll to Call Transfers section
  4. Select HTTP Transfer type

Step 2: Configure Transfer Description

Transfer Description
  • Guides the language model on when to use this transfer
  • Example: “Transfer to the best available agent based on customer priority and issue type”
  • Be specific about when this dynamic routing should be triggered
Webhook Endpoint
  • Your API URL: https://api.yourcompany.com/routing-decision
  • Will be called when transfer is initiated
Webhook Method
  • GET or POST (POST recommended for complex data)
Custom Headers
  • Authentication: Authorization: Bearer your-api-token
  • API keys, custom metadata
  • Example:
    Authorization: Bearer sk_live_abc123xyz789
    Content-Type: application/json
    
Query Parameters (optional)
  • Static parameters passed with every request
  • Example: api_version=v1&source=voice_agent
Your webhook receives a TransferWebHookPayload with conversation context:
{
  "type": "TransferWebHookPayload",
  "status": "running",
  "callId": "call_abc123",
  "agentId": "agent_xyz789",
  "orgId": "org_123",
  "endpoint": "+1234567890",
  "transferReason": "Customer requested to speak with a billing specialist",
  "transcription": [
    {
      "speaker": "ai",
      "name": "Agent",
      "text": "Hello, how can I help you today?",
      "startTime": "2026-04-10T10:00:00Z",
      "endTime": "2026-04-10T10:00:03Z"
    },
    {
      "speaker": "human",
      "name": "Customer",
      "text": "I have a question about my bill. Can I speak with someone from billing?",
      "startTime": "2026-04-10T10:00:04Z",
      "endTime": "2026-04-10T10:00:08Z"
    }
  ],
  "callAdditionalData": {
    "customerId": "cust_456",
    "priority": "high"
  },
  "agentAdditionalData": {},
  "sip": {
    "from": "+1234567890",
    "to": "+1987654321"
  }
}
Request Fields:
  • type: Always "TransferWebHookPayload" for transfer webhooks
  • status: Always "running" (call is active)
  • callId: Unique identifier for this call
  • agentId: Your voice agent’s ID
  • orgId: Your organization ID
  • endpoint: Phone number or SIP address of the caller
  • transferReason: AI-generated explanation of why transfer is needed
  • transcription: Full conversation history with speaker, text, and timestamps
  • callAdditionalData: Custom data passed when the call was created
  • agentAdditionalData: Custom data configured on the agent
  • sip: SIP headers for inbound calls (from, to, domain, diversion)
Your webhook returns a TransferWebhookResponse with routing instructions:
{
  "isSuccess": true,
  "message": "Routing to billing department",
  "transfer": {
    "type": "warm",
    "description": "Transfer to billing specialist",
    "endpointDestination": "+15550150",
    "sayToCustomer": "Connecting you with our billing specialist",
    "operatorInteraction": {
      "type": "static",
      "staticPhrase": "High priority customer with billing question"
    },
    "continueAfterOperatorDisconnect": true
  }
}
For a cold transfer response:
{
  "isSuccess": true,
  "transfer": {
    "type": "cold",
    "description": "Transfer to support queue",
    "endpointDestination": "+15550200"
  }
}
To cancel the transfer and continue the conversation:
{
  "isSuccess": false,
  "message": "No agents available, continue with AI"
}
Response Fields: Required:
  • isSuccess: Boolean - whether to proceed with transfer
  • transfer: Transfer configuration object (required when isSuccess is true)
Transfer Object (required when isSuccess is true):
  • type: "warm" or "cold"
  • description: Description for logging/debugging
  • endpointDestination: Phone number or SIP URI to transfer to
Optional (warm transfer only):
  • sayToCustomer: What agent tells customer before transfer
  • operatorInteraction: How agent briefs the operator (static phrase or smart mode)
  • continueAfterOperatorDisconnect: Boolean - can agent resume if operator hangs up?
Optional:
  • message: Context message for logging/debugging

Step 6: Configure Fallback Transfer

If webhook fails (timeout, error, unreachable), use fallback: Fallback Transfer Type
  • Warm or Cold
Fallback Destination
  • Backup phone number: +1-555-0100
Fallback Configuration
  • For warm: Operator message, customer message
  • For cold: Customer message
Failover Behavior (if fallback also fails)
  • Continue Conversation: Agent resumes
  • End Call: Call terminates gracefully
Failover Messages:
  • System message for agent context
  • Static phrase for caller

Configuration Example

This shows the config.features.transfer object structure for HTTP transfer:
{
  "type": "http",
  "description": "Transfer to the most appropriate agent based on customer tier, issue type, and agent availability.",
  "webhook": {
    "url": "https://api.yourcompany.com/v1/routing",
    "headers": {
      "Authorization": "Bearer sk_live_abc123xyz789"
    },
    "customSettings": {
      "httpMethod": "POST"
    }
  },
  "fallback": {
    "type": "warm",
    "description": "Fallback transfer when webhook unavailable",
    "endpointDestination": "+15550100",
    "sayToCustomer": "Let me connect you with our team",
    "operatorInteraction": {
      "type": "static",
      "staticPhrase": "General transfer - webhook unavailable"
    }
  },
  "failoverBehavior": {
    "continueConversation": true,
    "staticPhrase": "I'm sorry, I'm having trouble connecting you right now. Let me try to help you directly."
  }
}

Webhook Implementation Examples

Route to agents with specific expertise:
app.post('/routing-decision', async (req, res) => {
  const { transferReason, transcription, callAdditionalData } = req.body;

  // Determine issue type from conversation
  const conversationText = transcription.map(t => t.text).join(' ');
  const issueType = categorizeIssue(conversationText);

  // Find available agent with matching skill
  const agent = await findAvailableAgent({
    skill: issueType,
    available: true
  });

  res.json({
    isSuccess: true,
    message: `Routing to ${issueType} specialist`,
    transfer: {
      type: "warm",
      description: `${issueType} transfer`,
      endpointDestination: agent.phoneNumber,
      sayToCustomer: "Connecting you with a specialist",
      operatorInteraction: {
        type: "static",
        staticPhrase: `${issueType} issue - ${transferReason}`
      }
    }
  });
});
VIP customers get routed to senior agents:
app.post('/routing-decision', async (req, res) => {
  const { callAdditionalData, endpoint, transferReason } = req.body;

  // Check customer tier using endpoint (caller's phone number)
  const customer = await crm.getCustomer(endpoint);

  if (customer.tier === 'VIP') {
    // Route to senior agent
    const seniorAgent = await getAvailableSeniorAgent();
    return res.json({
      isSuccess: true,
      transfer: {
        type: "warm",
        description: "VIP customer transfer",
        endpointDestination: seniorAgent.phone,
        sayToCustomer: "Connecting you with our senior specialist",
        operatorInteraction: {
          type: "static",
          staticPhrase: `VIP customer ${customer.name} - priority handling`
        }
      }
    });
  }

  // Standard routing
  const agent = await getNextAvailableAgent();
  res.json({
    isSuccess: true,
    transfer: {
      type: "cold",
      description: "Standard support transfer",
      endpointDestination: agent.phone
    }
  });
});
Route to least busy agent:
app.post('/routing-decision', async (req, res) => {
  const { transferReason } = req.body;

  // Query all agents and their current call loads
  const agents = await getAgentWorkloads();

  // Find agent with lowest current workload
  const bestAgent = agents.reduce((min, agent) =>
    agent.activeCalls < min.activeCalls ? agent : min
  );

  res.json({
    isSuccess: true,
    transfer: {
      type: "warm",
      description: "Load-balanced transfer",
      endpointDestination: bestAgent.phone,
      sayToCustomer: "Connecting you with the next available agent",
      operatorInteraction: {
        type: "static",
        staticPhrase: "New customer inquiry"
      }
    }
  });
});
Route to agents in customer’s region:
app.post('/routing-decision', async (req, res) => {
  const { endpoint } = req.body;

  // Determine caller's region from phone number
  const region = getRegionFromNumber(endpoint);

  // Find available agent in same region
  const localAgent = await findAgentByRegion(region);

  res.json({
    isSuccess: true,
    transfer: {
      type: "warm",
      description: "Geographic routing transfer",
      endpointDestination: localAgent.phone,
      sayToCustomer: "Connecting you with a local specialist",
      operatorInteraction: {
        type: "static",
        staticPhrase: `Customer from ${region}`
      }
    }
  });
});

Use Cases

Skill-Based Routing

Route to agents with specific expertise (billing, technical, sales) based on conversation content. Your webhook analyzes the issue and matches with qualified available agents.

Priority Routing

VIP customers get immediate routing to senior agents. Standard customers follow normal queues. Your webhook checks customer tier in CRM and routes accordingly.

Geographic Routing

Route to agents in customer’s timezone or region. Your webhook uses caller location data to find local agents.

Workload Balancing

Route to least busy available agent. Your webhook queries real-time agent workload and routes to maintain balance.

Language Matching

Route to agents who speak customer’s language. Your webhook detects language from conversation and matches with agent skills.

Business Hours Routing

Different routing during business hours vs. after hours. Your webhook checks time and routes to appropriate team or service.

Troubleshooting

Problem: Webhook Times Out

Solution: Optimize webhook response time (target under 2 seconds). Add caching for common queries. Configure appropriate timeout and fallback transfer. Consider pre-computing routing decisions.

Problem: Webhook Returns Errors

Solution: Check webhook logs for error details. Verify webhook signature/authentication. Ensure response format matches specification. Test webhook with sample payloads.

Problem: Fallback Transfer Used Often

Solution: Investigate webhook reliability. Check webhook uptime and error rates. Verify network connectivity between Dasha BlackBox and webhook. Add monitoring and alerts.

Problem: Wrong Agent Receives Transfer

Solution: Review webhook routing logic. Test with various conversation scenarios. Verify conversation_summary provides enough context. Add logging to debug routing decisions.

Next steps

Warm Transfer

What HTTP transfer returns for warm routing

Cold Transfer

What HTTP transfer returns for cold routing

Call Transfers Overview

Compare all transfer types

Webhooks

Receive call events