- How to configure webhook tools to run asynchronously
- How to use the Add Messages API to inject context mid-conversation
- How to combine both features for powerful async workflows
- How to get the same behavior from tools served by an MCP server
Overview
Traditional webhook tools block the conversation until they complete. This works fine for fast operations, but creates awkward pauses for slow backend queries. Async tools solve this by letting the assistant continue the conversation while operations run in the background. If your backend responds within a few seconds and you’d prefer to keep using sync webhooks, filler messages offer a simpler alternative — scripted phrases that play at timed intervals to fill silence while the webhook executes.The two building blocks
These features are orthogonal—each is useful on its own, but they become especially powerful when combined.Combined workflow
When used together, these features enable a new pattern:- Assistant triggers an async webhook (e.g., order lookup)
- Assistant continues chatting with the customer
- Backend processes the request (5, 10, 30 seconds later)
- Backend calls Add Messages API to inject the results
- Assistant naturally incorporates the new information
Async webhooks
Theasync flag on webhook tools tells the assistant not to wait for the response. The webhook fires, and the assistant immediately continues the conversation.
Configuring an async webhook
Setasync: true in your webhook tool configuration:

Key configuration options
For the complete webhook tool schema, see the Create Assistant API reference.
What your backend receives
When the assistant triggers an async webhook, your endpoint receives:- The configured body parameters (e.g.,
order_id) - The
x-telnyx-call-control-idheader identifying the active call
The
x-telnyx-call-control-id header is critical—you’ll need it to inject results back into the conversation using the Add Messages API.Add Messages API
The Add Messages API lets you inject new messages into an active conversation from outside the call flow. This is useful for delivering async results, supervisor interventions, or external triggers.API endpoint
Request format
Message roles
Pick the role by how the result should land in the conversation:
- The caller is still talking, or the result can wait for the next turn: use
system(ortool). The assistant works the result into its next reply without interrupting anyone. If the caller goes quiet after asking, the platform’s own silence handling prompts the assistant, so the result is still delivered. - The result must be spoken immediately, even unprompted: use
user. This is the only role that starts a turn on its own. The trade-off is that the injected text appears in the transcript as caller speech and can interrupt a caller mid-sentence, so keep it short and label it, for example[SYSTEM: Order ORD-12345 is SHIPPED. Tell the caller now.].
Using role: tool and tool_call_id
A tool message must carry the tool_call_id of the call it answers. The id is required but not matched against the conversation’s outstanding calls: the API accepts a tool message whose id refers to a call that was already answered, and it does not reject an unknown id. Treat it as a label that helps the model relate the result to its earlier request, not as a correlation that the platform enforces.
Where to get the id:
- Mid-call: list the conversation’s messages with
GET /v2/ai/conversations/{conversation_id}/messages. Assistant messages carrytool_calls[].idfor every call the assistant made. MCP tools receive theconversation_iddirectly (_meta.telnyx_conversation_id); webhook tools receive thex-telnyx-call-control-idheader instead and can look the conversation up withGET /v2/ai/conversations?metadata->call_control_id=eq.{call_control_id}. - After the call: with
telephony_settings.conversation_ended_full_history: true, thecall.conversation.endedwebhook includes the full message history with the same ids.
tool buys you nothing over system for timing. Use it when you want the transcript to show a proper tool result, and system otherwise.
Standalone use cases
The Add Messages API is valuable even without async webhooks:- Supervisor intervention: A human supervisor injects guidance during a difficult call
- Scheduled reminders: External system reminds the assistant about time-sensitive information
- Cross-system triggers: CRM or ticketing system pushes updates to an active call
- Escalation prompts: Monitoring system detects frustration and injects de-escalation guidance
Combining async webhooks with Add Messages
The real power comes from combining these features. Here’s a complete example of an async order lookup system.Architecture
Step 1: Configure the assistant
Create an assistant with async webhook tools. Notice how the instructions tell the assistant to continue engaging while waiting:Step 2: Build the backend service
Your backend receives the webhook, processes the request, and calls the Add Messages API when done:Step 3: Test the flow
- Call your assistant and ask about an order
- The assistant triggers the async lookup and continues chatting
- After 15 seconds, your backend injects the results
- The assistant seamlessly shares the order details

Async tools served by an MCP server
Theasync flag belongs to webhook tools only. An MCP server attached with mcp_servers exposes id and allowed_tools and nothing else: there is no per-tool async, timeout, or filler setting, and the assistant waits for the MCP tools/call to return before it can take new caller input. Filler messages do apply to MCP tool calls, but they narrate the wait rather than end it.
To get deferred behavior from an MCP tool, build it into the tool itself:
-
Return fast. As soon as the tool knows the work will be slow, return a short “started” result (for example
Lookup started for order ORD-12345; result will follow.) and keep the real work running in the background. The assistant can carry on talking while it runs. -
Correlate. Each
tools/callrequest from Telnyx carries the live conversation id in the JSON-RPCparams._metaobject (not in an HTTP header):Keep it with the background job. To call Add Messages you also need thecall_control_id: fetch it from the conversation’s metadata withGET /v2/ai/conversations/{conversation_id}(metadata.call_control_id), or record the mapping when the call starts from the dynamic variables webhook, whoseassistant.initializationpayload carriescall_control_id. - Inject the result with the Add Messages API exactly as you would for an async webhook, choosing the role as described in Message roles. Include the identifier from step 1 so the assistant can tie the result back to the request.
Multiple parallel lookups
You can trigger multiple async webhooks simultaneously. Each completes independently and injects results as they become available.Example: Staggered results
Configure multiple tools with different backend processing times:
The assistant triggers both at once. Results drip into the conversation naturally:
Instructing the assistant
For parallel lookups to work well, your assistant instructions should emphasize calling tools together:Best practices
Crafting system messages
When injecting results via the Add Messages API, format them clearly:Handling edge cases
Call ended before results arrive:- Include identifiers in messages so the assistant knows which query the results belong to
- Use timestamps or request IDs if needed
Backend considerations
- Your backend should return a 200 response quickly to acknowledge receipt
- Process the actual work asynchronously (use background workers, Celery, AWS Lambda, etc.)
- There’s no timeout constraint on async webhooks—your backend can take as long as needed before calling the Add Messages API
Testing tips
- Use tools like ngrok to expose local backends during development
- Webhook tools: log all headers to verify
x-telnyx-call-control-idis received. MCP tools: it is not a header; log the parsedtools/callrequest and checkparams._meta.telnyx_conversation_id - Test with various delay lengths to ensure natural conversation flow
- Monitor the conversation transcript in the Portal to see messages being injected
Use cases
Customer service
- Order lookups: Query multiple systems (warehouse, shipping, payments) in parallel
- Account reviews: Pull account history, loyalty status, and recent tickets simultaneously
- Product availability: Check inventory across multiple warehouses
Healthcare
- Patient record retrieval: Fetch records from multiple systems while confirming appointment details
- Insurance verification: Run eligibility checks while gathering patient information
- Lab results: Query lab systems and deliver results when ready
Financial services
- Loan pre-qualification: Run credit checks and affordability calculations in background
- Account aggregation: Pull balances from multiple accounts simultaneously
- Fraud alerts: Inject real-time fraud warnings from monitoring systems
Scheduling
- Multi-calendar availability: Check availability across multiple calendars/resources
- Booking confirmations: Process reservations and inject confirmation details
- Waitlist updates: Notify assistant when spots become available
Related resources
- Add Messages API Reference - Complete API specification for injecting messages
- Create Assistant API Reference - Full webhook tool configuration options
- Filler Messages - Scripted phrases that fill silence during sync webhook calls
- Webhooks & Workflows - Learn more about configuring webhook tools
- Dynamic Variables - Pass context into conversations at start time
- Memory - Persist information across conversations