dograh/docs/voice-agent/pre-call-data-fetch.mdx
Abhishek 00a1a22b74
feat: refactor node spec and add mcp tools (#244)
* refactor: carve out extraction panel

* refactor: create spec versions for node types

* refactor: create a GenericNode and remove custom nodes

* feat: add python and typescript sdk

* add dograh sdk

* fix: fetch draft workflow definition over published one

* fix: fix routes of SDKs to use code gen

* chore: remove doclink dependency to reduce image size

* chore: format files

* chore: bump pipecat

* feat: let mcp fetch archived workflows on demand

* chore: fix tests

* feat: add sdk documentation

* chore: change banner and add badge
2026-04-21 07:56:16 +05:30

164 lines
5.8 KiB
Text

---
title: "Pre-Call Data Fetch"
description: "Fetch customer data from your CRM or ERP before the call starts, so your voice agent can greet callers by name and reference their account details."
---
Pre-Call Data Fetch allows you to enrich the call context with external data before the voice agent starts speaking. When enabled on the **Start Call** node, Dograh sends an HTTP request to your API as soon as a call is initiated. While the response is loading, the caller hears a ring-back tone. Once the data arrives, it is merged into the call's [initial context](/core-concepts/context-and-variables#initial_context) and becomes available as template variables in your prompts and greetings.
## How It Works
1. A call arrives (inbound) or is initiated (outbound).
2. Dograh sends a **POST** request to your configured endpoint with a standardized payload.
3. The caller hears a ring-back tone while waiting for the response.
4. Your API responds with a JSON object containing `dynamic_variables`.
5. The variables are merged into the call's initial context.
6. The voice agent starts with full access to the fetched data via `{{variable_name}}` syntax.
## Configuration
Open the **Start Call** node editor and expand **Advanced Settings**. Toggle **Pre-Call Data Fetch** and configure:
| Field | Description |
| --- | --- |
| **Endpoint URL** | The URL Dograh will send the POST request to. |
| **Authentication** | Optional credential for authenticating the request. Supports API key, bearer token, basic auth, and custom header. |
## Request Format
Dograh sends a `POST` request with the following JSON payload:
```json
{
"event": "call_inbound",
"call_inbound": {
"agent_id": 123,
"from_number": "+12137771234",
"to_number": "+12137771235"
}
}
```
| Field | Description |
| --- | --- |
| `event` | Always `"call_inbound"`. |
| `call_inbound.agent_id` | The workflow (agent) ID. |
| `call_inbound.from_number` | The caller's phone number (`caller_number` from initial context). |
| `call_inbound.to_number` | The called phone number (`called_number` from initial context). |
The `Content-Type` header is set to `application/json`. If you configured a credential, the corresponding authentication header is included.
## Expected Response Format
Your API should return a **JSON object** with a `2xx` status code. The variables to inject into the call context should be placed inside the `dynamic_variables` key:
```json
{
"call_inbound": {
"dynamic_variables": {
"customer_name": "Jane Doe",
"account_status": "active",
"loyalty_tier": "gold",
"open_tickets": 2
}
}
}
```
You can also place `dynamic_variables` at the top level:
```json
{
"dynamic_variables": {
"customer_name": "Jane Doe",
"account_status": "active"
}
}
```
After the response is received, you can reference these values anywhere template variables are supported:
- **Greeting**: `Hello {{customer_name}}, thank you for calling!`
- **Prompt**: `The customer is a {{loyalty_tier}} member with {{open_tickets}} open support tickets.`
<Note>
If the response is not a valid JSON object, does not contain `dynamic_variables`, or the request fails or times out, the call proceeds normally without the additional context. The pre-call fetch never blocks or fails a call.
</Note>
## Nested Variables
If your `dynamic_variables` contain nested objects, you can access them using dot notation:
```json
{
"call_inbound": {
"dynamic_variables": {
"customer": {
"name": "Jane Doe",
"address": {
"city": "Los Angeles"
}
}
}
}
}
```
Access in prompts as `{{customer.name}}` and `{{customer.address.city}}`.
## Timeout
The request has a **10-second timeout**. If your API does not respond within this window, the call proceeds without the fetched data. Design your endpoint to respond as quickly as possible to minimize the ring-back tone duration.
## Testing with Test Calls
<iframe
src="https://www.tella.tv/video/vid_cmnrnu19v011z04l1hvwiezaz/embed?b=0&title=0&a=1&loop=0&autoPlay=false&t=0&wt=0"
allowFullScreen
allowTransparency
style={{ width: "100%", aspectRatio: "16/9", border: "none", borderRadius: "12px" }}
/>
When a real phone call comes in, the `caller_number` and `called_number` context variables are automatically set by the telephony provider and included in the pre-call data fetch request as `from_number` and `to_number`. However, when you make a test call — either a **web call** (WebRTC) or a **phone test call** from the workflow editor — these variables are not available by default.
To simulate telephony data during testing:
1. Open your workflow and go to **Settings**.
2. Under **Context Variables**, add the following variables:
- `caller_number` — set to a phone number you want to simulate as the caller (e.g., `+12137771234`).
- `called_number` — set to the number that would be dialed (e.g., `+12137771235`).
3. Save the settings.
Now when you make a test call (web or phone), these values will be sent in the pre-call data fetch request to your endpoint, allowing you to test the full flow as if a real inbound call were coming in.
<Note>
These context variables are only used during test calls from the workflow editor. On production inbound calls and campaign outbound calls, the actual telephony data is used and these values are ignored.
</Note>
## Example Integration
A simple Node.js endpoint that looks up a customer by phone number:
```javascript
app.post("/dograh/pre-call", async (req, res) => {
const { call_inbound } = req.body;
const customer = await db.customers.findOne({
phone: call_inbound.from_number,
});
if (!customer) {
return res.json({});
}
res.json({
call_inbound: {
dynamic_variables: {
customer_name: customer.name,
account_status: customer.status,
loyalty_tier: customer.tier,
},
},
});
});
```