type field, base64 PCM16 audio in input_audio_buffer.append, assistant speech in response.output_audio.delta, and familiar event names throughout. Most migrations are a matter of changing the URL, moving session configuration onto the assistant, and deleting client code that Telnyx makes unnecessary.
The one architectural shift to internalize before touching code:
With OpenAI, the socket is the product: you configure the session, manage the conversation, and request every response. With Telnyx, the AI Assistant is the product: instructions, model, voice, and tools live on the assistant, and the assistant owns turn-taking. The socket only carries the conversation.This makes the Telnyx client simpler than the OpenAI client it replaces — most of the migration is deleting code.
Before you start
Create and configure an AI Assistant in the Portal (or via the Assistants API — see Assistants API in the sidebar). Everything you used to send insession.update becomes assistant configuration:
Connection and authentication
g711_ulaw/g711_alaw are not available over this WebSocket). Input sample rate is one of 8000, 16000, 24000, 44100, 48000 Hz (default 16000). The output rate is determined by the assistant’s voice — read it from session.created instead of assuming 24 kHz:
Event mapping
Client → server frames
Server → client frames
Turn-taking: delete your response orchestration
On OpenAI, a manual-VAD or push-to-talk client drives the conversation:append → commit → response.create. On Telnyx the server drives it — you stream audio continuously and turns happen:
- Turn detection is always
server_vad. You cannot disable it (turn_detection: null) or use semantic VAD. Push-to-talk UIs still work — only send audio while the button is held — but the turn boundary is still decided by server VAD, tuned via Interruption Settings. - Automatic responses cannot be turned off. There is no
create_response: falsemode where you inspect the transcript before allowing a reply. - Text turns need no trigger.
conversation.item.createwithinput_textgets an automatic spoken response — do not follow it withresponse.create.
Interruption handling
Barge-in is automatic: when the user speaks over the assistant, Telnyx cancels the response (finalresponse.done has status: "cancelled") and starts a new turn. Your OpenAI truncation bookkeeping — tracking item_id, measuring played milliseconds, sending conversation.item.truncate — has no Telnyx equivalent and should be deleted. Keep exactly one client-side behavior: flush locally queued audio when speech starts.
Function calling
Tool definitions move fromsession.update payloads to the assistant’s tool configuration. At runtime, two OpenAI patterns collapse into one Telnyx pattern:
- Tools your backend served (the common OpenAI pattern) usually become webhook or MCP tools: Telnyx calls your endpoint directly and the socket only shows informational
response.tool_call.started/.completedframes. Your client-side function-calling code is deleted entirely. - Tools that must run in your client process become client-side tools. The round-trip resembles OpenAI’s, with two changes: the request arrives as a single
conversation.item.createdframe with complete arguments (nofunction_call_arguments.deltastreaming, no digging throughresponse.doneoutput), and you don’t sendresponse.createafter the output.
OpenAI features without a Telnyx equivalent
Audit your application for these before migrating — they are not available over the Assistant Conversation WebSocket today:- Session reconfiguration — no
session.update; configuration is fixed for the life of the connection. - Manual turn control — no
turn_detection: null,create_response: false,input_audio_buffer.commit/.clear, or semantic VAD. - Out-of-band responses and custom context — no
response.create, so noconversation: "none", per-responseinputarrays, responsemetadata, or per-response overrides (voice, modality,max_output_tokens). - Text-only output — responses are always spoken; use the transcript deltas for text. (For a pure text channel, use the Assistants chat API instead — see Assistants API in the sidebar.)
- Conversation item manipulation — no
conversation.item.truncate,.retrieve, or.delete, and no assistant-message injection into history. - Image input —
input_imagecontent is not supported;conversation.item.createacceptsinput_textandfunction_call_outputitems only (anything else is rejected withinvalid_item). - G.711 audio — PCM16 only, in both directions.
- Rate-limit telemetry — no
rate_limits.updatedframes.
Migration checklist
- Create an assistant and move
session.updatecontents into its configuration (instructions, model, voice, tools, transcription, interruption). - Swap the URL and API key; pick
input_sample_ratevia query parameter. - Read the output sample rate from
session.createdinstead of assuming 24 kHz. - Delete:
session.update,response.create,input_audio_buffer.commit/.clear,conversation.item.truncate, and truncation bookkeeping. - Rewire function calling: backend tools → webhook/MCP tools (delete client code); in-client tools → handle
conversation.item.createdfunction_callitems. - Keep: audio append loop, playback-flush on
speech_started,response.cancelfor programmatic interrupts, transcript rendering from.deltaframes. - Update error handling to the Telnyx error codes, and treat a reconnect as a new conversation.
- Test barge-in, tool calls, and long-silence behavior (
session_idle_timeout) end to end.
Learn more
- Realtime voice conversations over WebSocket — The full guide to this API
- Conversation WebSocket reference — The complete frame-by-frame reference, under Assistants API → Conversation WebSocket in the sidebar
- Client-Side Tools — Tool handlers that run in your application
- Custom LLM — Bring your own model to a Telnyx assistant