This page is the OpenAI-specific integration guide. For the general
speech-to-speech model — how a
REALTIME agent is shaped, the other duplex
providers, and how to pick duplex vs. a cascade — see
BYO Speech-to-Speech Models.What you get
- Duplex audio. TeleQuick Voice opens the Realtime WebSocket on the first inbound audio frame, forwards each PCM chunk, and streams the model’s spoken reply back onto the call. Sample-rate conversion to and from the model’s expected rate is handled for you, so the same agent works on a G.711 phone leg and an Opus web leg without changes.
- Server-side VAD. OpenAI does its own endpointing and emits
speech-started / speech-stopped signals. A
REALTIMEagent uses these directly — you do not add a local turn detector. - Instant barge-in via truncate. When the caller talks over the agent, the in-flight assistant turn is truncated at the model and the buffered audio already on its way to the caller is dropped. Details below.
- Function calling and a spoken greeting, both on by default.
Configure the agent
Set a REALTIME entry node with provider openai
A duplex agent has a single node. Set
entry_node: REALTIME, name openai
as the provider, and pick a voice. The model id is passed on the dial URL
rather than in the session bootstrap, so leave it unset to take the current
generally-available model.- agent-config.yml
- control-plane API (TS)
Supply the OpenAI API key
Each workspace supplies its own OpenAI key. It is stored per tenant, sealed
at rest, and never shared across workspaces. Set it in the agent console at
agent.telequick.dev, or via the control-plane API.Point a number at the agent and call it
Route a phone number or trunk at the agent and place a call. On the first
inbound audio frame the runtime dials OpenAI; if the connection is refused
(bad key, retired model), it logs the failure and the call degrades to a
silent passthrough rather than dropping.
How the session is bootstrapped
The moment the Realtime WebSocket connects, TeleQuick Voice sends a singlesession.update in OpenAI’s GA shape and only then begins streaming audio, so
your voice and instructions are always in force before the model speaks:
session.typeisrealtime.- Turn detection is set under
audio.input.turn_detectionasserver_vad, with tunablethreshold,prefix_padding_ms, andsilence_duration_ms. - The voice is set under
audio.output.voice. instructionscarries your prompt.max_output_tokensis capped per assistant turn (OpenAI defaults this to “inf”; a voice turn is short, so the runtime bounds it to stop a runaway response from generating minutes of speech and burning tokens).
Barge-in via truncate
Because OpenAI owns endpointing, itsspeech_started signal is what fires
barge-in. When the caller interrupts, two things happen together:
- The runtime sends a
conversation.item.truncatefor the assistant item that is currently speaking. This tells OpenAI to stop generating the rest of that turn — without it, the model keeps producing audio you have already decided not to play, wasting tokens. - It emits a cancel downstream so the outbound audio buffer is flushed — without it, the caller would keep hearing the tail of the cancelled turn out of the jitter buffer even after the model stopped.
The truncate handshake, step by step
The truncate handshake, step by step
- OpenAI’s server-side VAD detects caller speech over the agent and emits
speech_started(a server-initiated truncate). - The runtime responds with
conversation.item.truncate, carrying the id of the in-flight assistant item and the number of milliseconds of its audio the caller actually heard, so the model’s conversation history matches what was played. - Simultaneously the runtime cancels the in-flight response locally and drops any pre-fetched audio bytes queued toward the caller.
- The caller now has the floor; their speech streams into the input buffer and the model responds to it.
On a phone call there is no acoustic echo cancellation in the media path, so a
loud agent can trip the model’s VAD. Turn-detection thresholds and the
mic-gating that protects against this are covered in
Turn Detection & Barge-In.
Greeting on inbound calls
Some carrier SBCs will not send you RTP until they hear yours. On an inbound call the runtime asks the model to speak first — it issues an empty-input response request so the model self-greets from yourinstructions (or an exact
opening line you pin), which opens the carrier’s media path. This is on by
default for inbound direct-media calls; no extra config.
Tools mid-conversation
Your tools are advertised in the session bootstrap, so the model can call HTTP and MCP tools during a spoken turn: it emits a function call, the runtime runs the tool, returns the result as afunction_call_output, and requests the next
response so the model speaks the answer. Configure tools exactly as you would
for any agent — see Tool Calling.
Session budgets
Every Realtime session is bounded so a stuck provider can’t run forever:- Connect timeout — the handshake gets a few seconds before the runtime gives up and falls back to a silent passthrough.
- Per-turn token cap — bounded in the session bootstrap as above.
- Max session — sessions are closed at a 15-minute ceiling even if OpenAI hasn’t. Tune lifetime, idle re-engage, and hangup budgets on Session Lifecycle.
Next steps
Speech-to-speech overview
The general duplex model, other providers, and duplex vs. cascade.
Turn detection
Tune barge-in, endpointing, and backchannel handling.
Tool calling
Let the model call HTTP and MCP tools during a spoken turn.
Gemini Live
Wire Google’s duplex model as an alternative realtime provider.