Overview
Useanswer with assistant.id when an AI assistant should handle an inbound call from pickup. Telnyx attempts to prepare the assistant before answering, reducing the work left to do after pickup. Use dial with assistant.id (or TeXML POST /v2/texml/ai_calls/{connection_id}) to place an outbound call that an assistant handles from pickup, warming up the assistant before the call is placed. Use ai_assistant_start to attach an assistant to a call that is already answered, such as after an IVR or human interaction.
This is different from Gather using AI, which is purpose-built for collecting structured data. ai_assistant_start is for open-ended, conversational AI experiences.
Prerequisites
- A Telnyx account and a Call Control application receiving calls. Follow the Voice API getting started guide if you haven’t set that up.
- An AI assistant. You can create one:
- No-code via the Portal: AI Assistants guide
- Via the API: Create an assistant
id (format: assistant-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
Answer an inbound call with an assistant
For an inbound call that is still unanswered, sendPOST /v2/calls/{call_control_id}/actions/answer with the assistant configuration in the request body:
assistant.id is required within the assistant object; the call uses the stored assistant’s configuration. To change settings for this call only, send per-call overrides alongside the ID — for example:
- Telnyx accepts the command and attempts to warm up the assistant configuration and dependencies while the call remains unanswered.
- Telnyx answers the call and emits
call.answered. The HTTP success response can arrive before this webhook. - The assistant starts automatically on the answered call. Do not send a second
ai_assistant_startcommand from thecall.answeredhandler.
assistant.id does not match an existing assistant — Telnyx sends call.conversation.start_failed instead of call.conversation.created. The call stays answered, so handle this webhook to continue the call, for example by transferring it or hanging up.
If the application first rings a business’s phones, send this combined answer request when the no-answer timeout expires and the assistant should take over. The caller’s inbound leg must still be unanswered. Answering that leg earlier and starting the assistant later cannot move preparation back before pickup.
Get the conversation ID
Theanswer HTTP response does not include conversation_id. Handle the call.conversation.created webhook and store data.payload.conversation_id alongside data.payload.call_control_id. Telnyx sends this event to the configured Call Control webhook URL during assistant startup; no send_message_history_updates setting is required.
Example payload fields:
Reuse one assistant with per-call settings
A single stored assistant can supply defaults for many businesses or call-by-call experiments. Send each call’s greeting, instructions, tools, voice, and transcription overrides insideassistant; a separate stored assistant per voice or business is not required.
When migrating from ai_assistant_start, use these locations in the answer request:
The two commands use different voice-settings schemas. Select the supported assistant voice options from the Answer call reference rather than copying the start command’s entire
voice_settings object unchanged.
Omitted assistant fields retain stored values. A supplied voice_settings or transcription object replaces that entire stored object: include all settings that the call needs, including provider credentials where applicable. dynamic_variables merge with stored variables, with request values taking precedence. The top-level answer.transcription boolean controls standalone call transcription; it does not configure assistant speech recognition.
Understand and measure the remaining delay
Warm-up moves preparation before answer; it does not guarantee a shorter total time from the incoming call to the greeting. It does not wait for greeting audio to be synthesized or guarantee zero silence after pickup. If warm-up fails, Telnyx answers and starts the assistant without the warmed configuration. Compare the same voice and assistant configuration using the time from actual answer to the first audible greeting. Also track the total time from the incoming call to the greeting so that a later answer is visible in the results. Usecall.answered for the answer event, rather than the HTTP response time, and verify the greeting onset from call audio. A playback-start event alone does not establish that speech was audible; the playback may contain silence.
Place an outbound call with an assistant
For an outbound call that an AI assistant should handle from the moment the called party picks up, sendPOST /v2/calls with the destination, your Call Control application’s connection_id, and the assistant configuration in the request body:
assistant.id is required within the assistant object; the call uses the stored assistant’s configuration. To change settings for this call only, send per-call overrides alongside the ID, with the same merge rules as the inbound answer request — for example a different greeting and voice:
- Telnyx accepts the command and attempts to warm up the assistant configuration and dependencies before placing the call.
- The called party answers and Telnyx emits
call.answered. - The assistant starts automatically on the answered call. Do not send
ai_assistant_startfrom thecall.answeredhandler — the call already has the assistant attached.
conversation_id from the call.conversation.created webhook, as with inbound calls; the dial response does not include it. If the assistant cannot be started after the called party answers, Telnyx sends call.conversation.start_failed instead, and the call stays connected.
If warm-up fails, the call is still placed and the assistant starts after answer without the warmed configuration.
Outbound with TeXML
ThePOST /v2/texml/ai_calls/{connection_id} endpoint places the same assistant-backed outbound call from a TeXML application, warming up the assistant before the call is placed:
AIAssistantDynamicVariables passes per-call variables and AIAssistantVersion pins a specific assistant version. If the assistant’s voicemail detection is configured, include the MachineDetection parameters as shown in the Initiate an outbound AI call reference.
The <AIAssistant> TeXML verb attaches an assistant to a call leg that is already on a TeXML call. When a still-ringing leg’s instructions begin with <Connect><AIAssistant/></Connect>, TeXML answers the leg and starts the assistant in one step, with the assistant warmed up while the leg is still ringing. See the <AIAssistant> verb documentation.
Reduce the silence before the greeting
Warm-up moves preparation before answer; the greeting still only starts once media is connected after answer. To keep the called party’s wait short:- Prefer
dialwithassistant.id(orPOST /v2/texml/ai_calls/{connection_id}) over dial-then-ai_assistant_start-on-call.answered: the two-step flow performs all startup after the called party answered, and the webhook handler’s round trip adds to the silence the called party hears. - Use a static
greetingrather than<assistant-speaks-first-with-model-generated-message>, which puts the LLM’s first token in the critical path before any audio. - Keep the stored assistant’s dynamic-variables webhook fast if one is configured: it runs during warm-up on every call, and a slow endpoint delays every greeting.
- Measure from
call.answered(or the TeXMLansweredstatus callback) to the first audible greeting in the call audio, not from your API request, and keep total time from request to greeting visible so a longer ringing phase is not hidden.
Start an AI Assistant on an answered call
Send aPOST request to ai_assistant_start with the call_control_id of the active call:
Webhooks
The assistant emits the following lifecycle webhooks:When the AI conversation ends — the assistant stops itself at its
time_limit_secs or user_idle_timeout_secs, or you call ai_assistant_stop — the call is not hung up by the assistant stop itself. What happens to the call depends on how the assistant is running on it:- Call Control (
ai_assistant_start): the call leg stays connected and continues to be billed until you hang it up with the Hangup command, the far end hangs up, or the call reaches the platform’s maximum call duration. Handlecall.conversation.endedand decide what happens next: hang up the leg, transfer the caller, or keep the call open for your own Call Control flow. - TeXML (
<Connect><AIAssistant>): the assistant is the TeXML instruction currently executing, and stopping it ends that instruction. In the default TeXML setup for assistants there is nothing after the assistant command — the served document is just<Connect><AIAssistant id="…"/></Connect>— so with no further instructions to execute, the call is hung up when the assistant stops. If you need the call to continue, either put TeXML instructions after</Connect>— the following instructions execute when the service stops — or set theactionattribute on<Connect>to a URL that returns the next TeXML instructions (for example a<Dial>to a human agent); the call is hung up only when neither continues the flow.
Stream Message History Updates
By default you only learn what was said once the conversation ends. Setsend_message_history_updates to true on ai_assistant_start to receive a call.ai_gather.message_history_updated webhook every time the conversation history changes — useful for live transcripts, agent-assist screens, or supervisor dashboards.
Control It From the Assistant Instead
The same setting exists on the assistant itself, astelephony_settings.send_message_history_updates. When it is set, it overrides whatever the start command asked for, so an assistant can turn the webhooks on for every call it takes — or opt out of them entirely:
Messages exchanged privately with a transfer destination during warm transfer acceptance are never included in these webhooks unless the transfer tool is configured with
end_user_target_context_mode: "shared".Include the Full History in call.conversation.ended
By default, the messages array of the call.conversation.ended webhook contains only the user and assistant text turns. Set telephony_settings.conversation_ended_full_history to true on the assistant to receive the full conversation history instead, in order — including the tools the assistant called and what they returned:
messages looks like this:
The assistant’s instructions are never included. If data retention is disabled for your account,
messages is redacted regardless of this setting.
Stop the Assistant
To stop the assistant and return control to your application. On Call Control the call remains active and can continue with other Call Control commands (in the default TeXML setup, stopping the assistant ends the call — configure the<Connect> action attribute to keep the call going; see the webhooks note above):
Add a Participant to an Existing Conversation
Once an AI assistant conversation is running, you can bring additional call legs into it usingai_assistant_join. For example, you can dial out to a new destination, wait for the person to answer, then add them to the ongoing conversation.
Prerequisites
- An active AI assistant conversation with a known
conversation_id. Theconversation_idis returned in the200response ofai_assistant_start. Foranswerwithassistant.id, obtain it from the call.conversation.created webhook as described above.
Example: Dial a new participant and add them to the conversation
Step 1 — Dial the new destination:call_control_id for the outbound leg.
Step 2 — Wait for the call.answered webhook:
When Telnyx sends a call.answered event for the new call leg, extract its call_control_id.
Step 3 — Add the participant to the conversation:
Join the Conversation
Once you have the newcall_control_id:
id must be the call_control_id of the call being added. The only supported role is "user".
Optional Participant Fields
Next Steps
- Explore the full AI Assistant API reference
- Configure your assistant in the Portal
- Collect structured data mid-call with Gather using AI