diff --git a/docs/voice-agent/tools/call-transfer.mdx b/docs/voice-agent/tools/call-transfer.mdx
index 2e3ed6b7..f14e9c2d 100644
--- a/docs/voice-agent/tools/call-transfer.mdx
+++ b/docs/voice-agent/tools/call-transfer.mdx
@@ -1,62 +1,291 @@
---
title: "Call Transfer"
-description: "Enable your AI agent to transfer calls to phone numbers or SIP endpoints with built-in call transfer functionality."
+description: "Transfer live telephony calls to static destinations or resolve the destination dynamically during the call."
---
-The Call Transfer tool enables your AI agent to transfer active calls to phone numbers or SIP endpoints. When configured, your agent can seamlessly transfer callers to human operators, departments, or other systems while maintaining a professional experience.
+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.
-## Supported Providers
+Use this tool when the caller should speak to a human operator, department, escalation queue, support queue, or another phone system.
-Call transfer is available for telephony calls using Twilio, Telnyx, or Asterisk ARI providers. Web calls do not support transfer functionality.
+## Supported providers
-## How It Works
-
-The Call Transfer tool performs **blind transfers** where no call context is shared with the destination. Here's what happens:
-
-1. **Agent Decision**: Your AI agent determines a transfer is needed and calls the transfer function
-2. **Pre-transfer Message**: (Optional) Agent plays a custom message like "Let me transfer you to our sales team"
-3. **Hold Experience**: Caller hears hold music while the transfer is processed
-4. **Connection**: Once the destination answers, the caller is connected directly
-5. **Agent Handoff**: The AI agent ends its involvement in the call
-
-## Configuration
-
-### Basic Settings
-
-- **Destination**: Phone number or SIP endpoint (see formats below)
-- **Timeout**: How long to wait for destination to answer (default 30 seconds)
-- **Pre-transfer Message**: Optional custom message played before transfer
-
-### Destination Formats
-
-**For Twilio:**
-- **Phone numbers**: [E.164](https://en.wikipedia.org/wiki/E.164) format (`+` then country code then number, no spaces or dashes): `+1234567890`
-- Must be a valid reachable phone number
-
-**For Telnyx:**
-- **Phone numbers**: E.164 format: `+1234567890`
-- Must be a valid reachable phone number
-
-**For Asterisk ARI:**
-- **SIP endpoints only**: `PJSIP/extension` or `SIP/endpoint`
-- **Examples**: `PJSIP/sales-queue`, `SIP/1001`, `PJSIP/conference-room`
+Call transfer is available for telephony calls using Twilio, Telnyx, or Asterisk ARI providers.
-Asterisk ARI transfers only work with SIP endpoints configured on your Asterisk server. External phone numbers require additional PSTN trunk configuration.
+Web calls do not support call transfer.
-## Setup Requirements
+## How call transfer works
-1. **Organization Setup**: Ensure your organization has a supported telephony provider configured
-2. **Tool Enablement**: Add the Call Transfer tool to your agent's available tools
-3. **Destination Validation**:
- - **Twilio**: Verify phone numbers are reachable
- - **Telnyx**: Verify phone numbers are reachable
- - **ARI**: Verify SIP endpoints exist on your Asterisk server
-4. **Testing**: Test transfers in your specific provider environment
+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"
+}
+```
+
+
+Dograh does not send the full conversation transcript to the resolver. Add the specific values you need as LLM parameters or preset parameters.
+
+
+## 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."
+ }
+}
+```
+
+
+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.
+
+
+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
+
+
+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.
+
+
+## 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
+```
+
+
+Asterisk ARI transfers only work with SIP endpoints configured on your Asterisk server. External phone numbers require PSTN trunk configuration in your Asterisk setup.
+
+
+## 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
-- **Destination not reachable**: Verify destination number/endpoint is valid and reachable
-- **Tool not available**: Check that Call Transfer tool is added to the correct agent node
-- **Transfer failures**: Handle transfer failure scenarios within your agent prompts
\ No newline at end of file
+### 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.