> ## Documentation Index
> Fetch the complete documentation index at: https://blackbox.dasha.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Route Calls Dynamically with Webhooks

> Configure HTTP transfers for dynamic, webhook-based call routing. Your agent calls your endpoint with conversation context, your system checks CRM data, availability, and skill levels, then returns the routing decision. Route premium customers to senior agents, balance workload across teams, and apply complex business logic in real-time.

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

<Accordion title="Step 3: Configure Webhook">
  **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
    ```
</Accordion>

**Query Parameters** (optional)

* Static parameters passed with every request
* Example: `api_version=v1&source=voice_agent`

<Accordion title="Step 4: Webhook Request Format">
  Your webhook receives a `TransferWebHookPayload` with conversation context:

  ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
  {
    "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"
    }
  }
  ```
</Accordion>

**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)

<Accordion title="Step 5: Webhook Response Format">
  Your webhook returns a `TransferWebhookResponse` with routing instructions:

  ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
  {
    "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:

  ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
  {
    "isSuccess": true,
    "transfer": {
      "type": "cold",
      "description": "Transfer to support queue",
      "endpointDestination": "+15550200"
    }
  }
  ```

  To cancel the transfer and continue the conversation:

  ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
  {
    "isSuccess": false,
    "message": "No agents available, continue with AI"
  }
  ```
</Accordion>

**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

<Accordion title="Example: Complete HTTP Transfer Configuration">
  This shows the `config.features.transfer` object structure for HTTP transfer:

  ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
  {
    "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."
    }
  }
  ```
</Accordion>

## Webhook Implementation Examples

<Accordion title="Skill-Based Routing">
  Route to agents with specific expertise:

  ```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  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}`
        }
      }
    });
  });
  ```
</Accordion>

<Accordion title="Priority-Based Routing">
  VIP customers get routed to senior agents:

  ```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  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
      }
    });
  });
  ```
</Accordion>

<Accordion title="Workload Balancing">
  Route to least busy agent:

  ```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  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"
        }
      }
    });
  });
  ```
</Accordion>

<Accordion title="Geographic Routing">
  Route to agents in customer's region:

  ```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  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}`
        }
      }
    });
  });
  ```
</Accordion>

## 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

<CardGroup cols={2}>
  <Card title="Warm Transfer" icon="handshake" href="/docs/advanced-features/call-transfers/warm-transfer">
    What HTTP transfer returns for warm routing
  </Card>

  <Card title="Cold Transfer" icon="phone-arrow-right" href="/docs/advanced-features/call-transfers/cold-transfer">
    What HTTP transfer returns for cold routing
  </Card>

  <Card title="Call Transfers Overview" icon="phone" href="/docs/advanced-features/call-transfers">
    Compare all transfer types
  </Card>

  <Card title="Webhooks" icon="webhook" href="/docs/webhooks-and-events/webhooks-overview">
    Receive call events
  </Card>
</CardGroup>
