mirror of
https://github.com/dograh-hq/dograh.git
synced 2026-07-13 11:22:14 +02:00
291 lines
9.4 KiB
Text
291 lines
9.4 KiB
Text
---
|
|
title: "Call Transfer"
|
|
description: "Transfer live telephony calls to static destinations or resolve the destination dynamically during the call."
|
|
---
|
|
|
|
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.
|
|
|
|
<Warning>
|
|
Web calls do not support call transfer.
|
|
</Warning>
|
|
|
|
## How call transfer works
|
|
|
|
When the LLM decides a transfer is needed, it calls the Call Transfer tool. Dograh 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. Dograh resolves the destination from either static configuration or a dynamic HTTP resolver.
|
|
3. Dograh optionally plays a pre-transfer message.
|
|
4. Dograh 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, Dograh connects the caller and ends the AI agent's involvement.
|
|
|
|
The transfer is a blind transfer. Dograh 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.
|
|
|
|
Dograh 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 Dograh
|
|
|
|
## Dynamic resolver request
|
|
|
|
The resolver request body is a flat JSON object.
|
|
|
|
Dograh builds it from:
|
|
|
|
- **LLM parameters**: values the agent extracts from the conversation when it calls the transfer tool
|
|
- **Preset parameters**: values Dograh 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:
|
|
|
|
```json
|
|
{
|
|
"account_id": "acct_123",
|
|
"plan": "enterprise",
|
|
"billing_issue_type": "invoice_dispute"
|
|
}
|
|
```
|
|
|
|
<Note>
|
|
Dograh does not send the full conversation transcript to the resolver. Add the specific values you need as LLM parameters or preset parameters.
|
|
</Note>
|
|
|
|
## Dynamic resolver response
|
|
|
|
Your resolver must return a JSON object with `transfer_context.destination`.
|
|
|
|
`transfer_context.custom_message` is optional.
|
|
|
|
```json
|
|
{
|
|
"transfer_context": {
|
|
"destination": "+1234567890",
|
|
"custom_message": "Please wait while I connect you with our enterprise billing team."
|
|
}
|
|
}
|
|
```
|
|
|
|
<Warning>
|
|
Follow this response shape exactly. Dograh reads specific keys from the resolver response. For dynamic transfer resolution, an invalid response does not fall back silently: the transfer fails before dialing.
|
|
</Warning>
|
|
|
|
Field behavior:
|
|
|
|
- `destination`: Required. E.164 phone number or SIP endpoint.
|
|
- `custom_message`: Optional. If returned, this message is played before the provider transfer starts.
|
|
|
|
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 Dograh calls with `POST`
|
|
- **Resolver Timeout**: How long Dograh waits for the resolver response
|
|
- **Resolver Wait Message**: Optional message spoken while Dograh 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 Dograh from context or fixed values
|
|
- **Custom Headers**: Static headers sent to your resolver endpoint
|
|
- **Credential**: Optional saved credential used to authenticate the resolver request
|
|
|
|
<Note>
|
|
The dynamic resolver uses `POST` only. If you need custom backend behavior, implement it behind your resolver endpoint and return the expected `transfer_context` shape.
|
|
</Note>
|
|
|
|
## Pre-transfer messages
|
|
|
|
Call Transfer supports a common pre-transfer message setting for both static and dynamic destinations.
|
|
|
|
For static transfers:
|
|
|
|
1. Dograh resolves the static or template destination.
|
|
2. Dograh plays the configured pre-transfer message, if any.
|
|
3. Dograh starts the provider transfer.
|
|
|
|
For dynamic transfers:
|
|
|
|
1. Dograh may play the resolver wait message while calling your resolver.
|
|
2. If the resolver returns `custom_message`, Dograh plays that message.
|
|
3. If the resolver does not return `custom_message`, Dograh uses the configured pre-transfer message.
|
|
4. Dograh starts the provider transfer.
|
|
|
|
Resolver `custom_message` overrides the configured pre-transfer message for that transfer attempt.
|
|
|
|
## Transfer timeout
|
|
|
|
Transfer timeout is the maximum time Dograh 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 Dograh waits for your HTTP resolver before dialing starts.
|
|
|
|
## Destination formats
|
|
|
|
### Twilio and Telnyx
|
|
|
|
Use E.164 phone numbers:
|
|
|
|
```text
|
|
+1234567890
|
|
```
|
|
|
|
The number must be reachable from your telephony provider.
|
|
|
|
### Asterisk ARI
|
|
|
|
Use SIP endpoints:
|
|
|
|
```text
|
|
PJSIP/sales-queue
|
|
SIP/1001
|
|
```
|
|
|
|
<Warning>
|
|
Asterisk ARI transfers only work with SIP endpoints configured on your Asterisk server. External phone numbers require PSTN trunk configuration in your Asterisk setup.
|
|
</Warning>
|
|
|
|
## 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:
|
|
|
|
```json
|
|
[
|
|
{
|
|
"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:
|
|
|
|
```json
|
|
[
|
|
{
|
|
"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:
|
|
|
|
```json
|
|
{
|
|
"billing_issue_type": "invoice_dispute",
|
|
"requested_department": "billing",
|
|
"account_id": "acct_123",
|
|
"plan": "enterprise"
|
|
}
|
|
```
|
|
|
|
Your resolver returns:
|
|
|
|
```json
|
|
{
|
|
"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:
|
|
|
|
```json
|
|
{
|
|
"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 Dograh 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.
|