Skip to main content

How Dynamic Context Works

Expert Mode Dynamic Context lets you fetch customer data from your external APIs once, before each conversation starts. Instead of relying only on contact records, your agents can access account status, order history, support tickets, and business context from your customer relationship management (CRM) system, databases, and backend systems. You can also use custom API tools to fetch data during conversations.
Configure Dynamic Context in Call Flow under Before Call in your agent editor. The returned JSON data is available directly as variables (e.g., {{ field_name }}) in your agent’s greeting and prompt.
The platform calls the context API once before the conversation begins. The data is available for rendering the greeting and throughout the conversation. It does not refresh during the conversation. The hard request timeout is 30 seconds, but you should design the endpoint to return in under 1 second.
Quick Requirements:
  • HTTPS endpoint
  • Valid JSON object, or an array of objects that can be merged
  • Small response payload with only data needed for the conversation
  • Fast response time; aim for under 1 second
  • Authentication via Bearer token, Basic auth, custom header, or no auth

How It Works

Request Flow:
1

Call initiated

Call initiated (inbound) or about to start (outbound)
2

Context API called

BEFORE conversation begins: System sends POST request to your endpoint
3

Query your systems

Your API queries CRM/database for customer data
4

Return JSON

Your API returns JSON with context data
5

Context available

The platform makes context data available as template variables
6

Greeting rendered

The platform renders the greeting (using context variables if referenced)
7

Conversation begins

Conversation begins (context variables available if referenced in prompt)Context remains static throughout conversation (no refresh)

Inbound calls

direction: "inbound" with caller’s contact_number. Look up customer data in your CRM.

Outbound calls

direction: "outbound" with contact_number you’re calling. Fetch campaign context.

Web widget

medium: "web" with optional external_id. Identify user in your system via the web widget.

Configuration

1

Navigate to Dynamic Context

  1. Open your agent in the editor
  2. Click Call Flow
  3. In Before Call, open Dynamic Context
2

Configure Endpoint

This step is usually completed by a technical teammate.Endpoint URL: https://api.company.com/contextAuthentication: Choose Bearer Token, Basic Auth, Custom Header, or NoneThe request will include: agent_uuid, direction, agent_number, contact_number (and external_id for web widget)
3

Test

Save the Dynamic Context settings, then use Test to verify the saved endpoint and authentication respond correctly.
4

Save

Enable and save. The platform fetches context before each conversation.

Request & Response Format

Request Payload (POST Request)

POST https://api.company.com/context
Authorization: Bearer your_api_token
Content-Type: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...
X-Agent-UUID: 550e8400-e29b-41d4-a716-446655440000
X-Agent-Number: +15551234000
X-Contact-Number: +15551234567
X-Direction: inbound
X-Medium: phone
X-Room-SID: RM_abc123

{
  "agent_uuid": "550e8400-e29b-41d4-a716-446655440000",
  "direction": "inbound",
  "agent_number": "+15551234000",
  "contact_number": "+15551234567"
}
Body parameters:
  • agent_uuid (string, always included) - The UUID of the agent handling the call
  • direction (string, always included) - “inbound” or “outbound”
  • agent_number (string, optional) - The phone number the agent is using
  • contact_number (string, optional) - The customer’s phone number
  • external_id (string/int, optional) - Only for web widget calls, if provided by your integration
Additional headers:
  • X-Agent-UUID, X-Agent-Number, X-Contact-Number, X-Direction, X-Medium (phone/web)
  • X-Room-SID - Unique identifier for this conversation session
  • X-External-ID - For web widget calls only
Typical usage: Your endpoint uses contact_number or external_id to look up the customer in your CRM/database, then returns relevant account data, order history, tickets, etc. The agent_uuid can be used to customize responses per agent if needed.

What You Return (JSON Response)

{
  "account": {
    "customer_id": "12345",
    "tier": "VIP",
    "status": "active",
    "created_date": "2022-03-15"
  },
  "recent_orders": [
    {
      "order_id": "ORD-789",
      "status": "shipped",
      "tracking": "1Z999AA1234567890"
    }
  ],
  "support_tickets": [
    {
      "ticket_id": "TKT-456",
      "status": "open",
      "subject": "Billing question"
    }
  ]
}
Requirements:
  • Valid JSON object, or an array of objects that can be merged
  • Keep the response small and focused on fields the agent needs
  • Return only necessary fields (keeps response fast)
  • Handle missing data gracefully (return null or omit fields)
How variables are accessed: All top-level keys in your JSON response become template variables. If you return {"account": {"tier": "VIP"}}, you access it as {{ account.tier }}, not {{ context.account.tier }}.

Using Context Variables

All returned data from your API is available directly as top-level variables in your agent’s greeting and prompt. Accessing fields:
Account Tier: {{ account.tier }}
→ "VIP"

Order Status: {{ recent_orders[0].status }}
→ "shipped"

Number of Tickets: {{ support_tickets|length }}
→ 1
Example greeting with context:
Thanks for calling! I see you're a {{ account.tier }} customer with us.
How can I help you today?
Example prompt with context:
You are helping a {{ account.tier }} customer since {{ account.created_date }}.

{% if support_tickets|length > 0 %}
IMPORTANT: Customer has {{ support_tickets|length }} open ticket(s):
{% for ticket in support_tickets %}
- Ticket #{{ ticket.ticket_id }}: {{ ticket.subject }} ({{ ticket.status }})
{% endfor %}

Ask if they're calling about ticket #{{ support_tickets[0].ticket_id }}.
{% endif %}

{% if recent_orders|length > 0 %}
Recent order #{{ recent_orders[0].order_id }} is {{ recent_orders[0].status }}.
{% if recent_orders[0].tracking %}
Tracking: {{ recent_orders[0].tracking }}
{% endif %}
{% endif %}

Account Status: {{ account.status | default("active") }}
Use the | default("value") filter to provide fallbacks when data is missing. See Greeting and Prompt for more templating syntax and usage examples.

Authentication

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Use for JSON Web Token (JWT), OAuth (Open Authorization) 2.0 access tokens, or modern API keys.

Custom Header

X-API-Key: sk-abc123def456...
Custom header name with a credential value, such as an API key.

Basic Auth

Authorization: Basic YXBpX3VzZXI6cGFzc3dvcmQ=
Username/password, base64 encoded.

None

No authentication (only for internal/private networks).
Always use HTTPS.

Example Use Case

Customer Support with Full Context Scenario: Support agent needs complete customer view before conversation starts. Your API returns:
{
  "customer": {
    "name": "John Smith",
    "tier": "Premium",
    "since": "2022-01-15"
  },
  "account": {
    "status": "active",
    "subscription": "Pro Plan",
    "renewal_date": "2025-12-01"
  },
  "support": {
    "open_tickets": [
      {
        "id": "TKT-789",
        "subject": "Can't export reports",
        "priority": "high"
      }
    ]
  }
}
Agent prompt:
You're helping {{ customer.name }}, a {{ customer.tier }} customer
since {{ customer.since }}.

{% if support.open_tickets|length > 0 %}
Customer has an open {{ support.open_tickets[0].priority }} priority ticket
about "{{ support.open_tickets[0].subject }}".

Start by asking: "I see you have a ticket open about
{{ support.open_tickets[0].subject }}. Is that what you're calling about today?"
{% endif %}

Account: {{ account.subscription }}, renews {{ account.renewal_date }}
Result: Agent knows about the open ticket before the conversation starts, allowing for a personalized greeting and informed conversation throughout.

Best Practices

  • Target under 1 second response time
  • Cache frequently accessed data (5-10 minute TTL)
  • Return only fields you’ll use in your prompt
  • Use database indexes on lookup fields (contact_number, external_id, or your internal customer IDs)
  • Use | default("value") filters in your prompt
  • Return null for missing fields (don’t error)
  • Test with contacts that have minimal data
{# Safe - provides fallback #}
Tier: {{ account.tier | default("Standard") }}

{# Safer - checks existence #}
{% if support_tickets and support_tickets|length > 0 %}
  Has open tickets
{% endif %}
  • Don’t return SSN, credit cards, passwords
  • Use HTTPS only
  • Implement authentication (Bearer token recommended)
  • Return only necessary fields (e.g., last 4 of account number, not full)
  • Log access for audit trails
  1. Use Test with real customer data
  2. Test edge cases (new customer, VIP, suspended account)
  3. Verify your prompt handles missing fields gracefully
  4. Pilot with small traffic percentage before full rollout

Troubleshooting

  • Verify credentials are correct
  • Check authentication type matches your API (Bearer Token, Basic Auth, or Custom Header)
  • Test with same credentials in Postman
  • Check if token has expired
  • Use Test to verify the endpoint is responding
  • Check JSON structure matches what you’re accessing
  • Verify Dynamic Context toggle is ON
  • Use | default("fallback") for missing fields
  • Add database indexes
  • Implement caching
  • Return only necessary fields
  • Optimize database queries
  • Check network latency to your API
  • Check parameters in Test
  • Verify template variables resolve correctly: {{ account.tier }}
  • Ensure cache keys include customer identifier
  • Test with known customer to confirm data matches

Next Steps

Greeting

Use context variables to personalize your agent’s greeting

Prompt

Use context variables in your prompt with Jinja templating

Template Syntax

Master templating syntax for dynamic prompts

Custom Action

Create tools that use context data during conversations