text-only mode runs the conversation over WebSocket: no microphone permission prompt, no audio, no WebRTC session, and no voice minutes — visitors type, the assistant replies in text. For a fully custom chat interface, the Assistant Chat API sends a message to an assistant from your backend and returns the reply.
assistant created in Mission Control
Why text-only
Because no call is placed, atext-only chat session never bills voice minutes or speech: there is no per-minute Voice AI session charge for the chat. The assistant’s replies still run LLM inference, billed as AI inference usage. Use this mode when visitors should type rather than talk.
Embed the chat widget
The<telnyx-ai-agent> web component ships on npm as @telnyx/ai-agent-widget. In text-only mode the only required attribute is the assistant id:
npm install @telnyx/ai-agent-widget and import the component where the app registers custom elements.
The widget opens directly into the transcript panel: there is no “Start Call” button and no collapsed pill state. Typed turns go to the assistant over a WebSocket; the reply streams back as text and renders in the transcript UI. The browser never holds a Telnyx API key — the connection is brokered server-side, the same anonymous trust the voice widget uses, so the only thing the page carries is the assistant id.
Enable the assistant for web visitors
The assistant must allow anonymous web visitors:- In Mission Control, open the assistant and, under Telephony settings, enable Supports unauthenticated web calls (
telephony_settings.supports_unauthenticated_web_calls). This is the same opt-in the voice widget requires, and it is what marks an assistant as reachable from a public web page. - No phone number is needed. The chat works for an assistant that has never been attached to a number.
What fires and what bills
- DOM events work the same as on the voice widget:
agent.connected(its detail carries theconversationId),agent.disconnected,agent.error, and the transcript events. Listen for transcript updates withtranscript.updated, whosedetailis the complete current transcript — replace the displayed transcript with it rather than appending. - A session lives as a
web_chatconversation keyed byconversation_id, alongside — never inside — any phone conversation for the same assistant. See conversation keying.
Resuming a conversation
Pass the server-issued conversation id to keep one visitor in one conversation across page loads:Build a custom chat UI
Embedding a prebuilt widget is optional. The Assistant Chat API drives any chat frontend through your own backend, which keeps the Telnyx API key server-side:
Assistant Chat records each turn against the
conversation_id, so the history persists itself — there is no separate persist step. Create Message is only for inserting messages that did not go through the chat endpoint, such as importing an existing transcript.
Send a message with content and the conversation id:
conversation_id maintains context across requests; the response’s content field is the assistant’s reply. Set stream: true to receive the reply as Server-Sent Events — delta events carry content fragments while generated, and a final done event carries the full text.
A minimal backend flow: create a conversation once per visitor, then relay each typed turn.
content to your frontend, store the conversation_id in the visitor’s session, and pass it back on every subsequent turn. Because your server brokers every request, the API key never reaches the browser.
Assistant behavior in chat
Instructions, model, knowledge bases, and insights configured on the assistant apply to chat the same as to calls. Server-side tools run as usual. Three things differ:- The conversation runs as its own
web_chatchannel; instructions referencing{{telnyx_conversation_channel}}seeweb_chat. - Voice-specific telephony settings — phone number, voice, transcription — are simply unused; there is no audio path in a text-only chat.
- Client-side tools are unavailable in a text-only widget: the chat path is request/response, so a browser tool announced on this path could never run. An assistant that relies on client-side tools is not a fit for
text-only— server-side tools are the ones that run in chat.