WS /v1/realtime speaks the OpenAI Realtime protocol — session.update,
input_audio_buffer.append, response.create,
response.output_audio.delta — so existing realtime clients work against it.
In the console this is Studio → Nur Live.
Connect
The model rides the query string; the credential rides whichever channel your runtime can use.token:
timezone (an IANA zone, so the model knows what
“tomorrow” means), source (which surface opened the session, recorded on the
row), paired_session_id and pair_id for Duet, and
resume with resume_token for reconnecting.
The socket opens with three gateway declarations —
eesi.synthetic_audio, eesi.recording_disclosure, eesi.session — before
session.created arrives from the model. See
Realtime events for what each one carries.
Configure the session
Send onesession.update after session.created. The gateway composes your
instructions against the platform prompt and resolves the voice to its stored
reference clip before the frame reaches the model.
Updates merge recursively, so a later frame that names only a voice keeps your
instructions. An explicit
null clears a field.
Sample rates, and the two ways to break a session without noticing
Both defaults are 16 kHz mono PCM16, and neither the gateway nor the server checks what you actually put on the wire.response.created and response.done report the encoder’s effective format in
response.audio.output.format, so a client that reads it never has to guess.
G.711 is accepted too, always at 8 kHz — but mind the two spellings. A format
object takes { "type": "audio/pcmu" } or { "type": "audio/pcma" }.
capabilities.audio_formats lists the same two codecs under OpenAI’s legacy
names, g711_ulaw and g711_alaw, which are for reading, not for sending:
put one of them in format and the union matches nothing, so the whole
session.update is rejected exactly as rate: 16000 is.
Send audio
16 kHz mono PCM16, base64-encoded, in about 20 ms per message (640 bytes), paced at the rate it was recorded. Server-side VAD reads arrival timing to find the end of a turn, so pushing a file in at once produces bad endpointing rather than a faster answer. A single event may not carry more than two seconds of audio.Text has no voice activity detection behind it, so adding an item does not start
a turn. Follow it with
{"type": "response.create"}. Audio needs no such nudge —
turn detection fires the response when you stop speaking. That is the one
asymmetry between the two paths.Play the reply
input_audio_buffer.speech_started is not optional. The
server cancels generation in milliseconds; if your buffer keeps talking for
another two seconds, the agent feels slow no matter what the server numbers say.
Turn-taking and barge-in covers the whole contract.
Two events read the opposite way to how they look, and both fail silently:
conversation.item.input_audio_transcription.delta is cumulative, and
response.output_audio_transcript.done fires per segment. Read
Realtime events before
you write transcript handling.
Language
The model is multilingual and code-switches mid-sentence without configuration. Pin it to one language ininstructions if you need that.
To interpret rather than converse — the same words in another language and
nothing else — use Live translation. Instructions alone
will not do it: a conversational session carries a persona that tells the model
to introduce itself and to translate only when asked, and that persona arrives
first.
What this costs and where it stops
- Metered per minute of wall clock from the moment the upstream pipeline connects, at the same rate as synthesis and transcription.
- Three hours of wall clock per session, and five minutes with no frame from your client. See Connections.
- Inbound is bounded at 256 KB/s sustained with a 2 MiB burst, and one frame may not exceed 1 MiB. A client that exceeds the sustained rate is closed 1008.
- The balance and the free-tier day are re-checked once a minute, so a limit can end an established call — with a frame that tells you why, before the close.
Next
Realtime events
Every event in both directions, and the capability handshake.
Turn-taking and barge-in
How the server decides you stopped, and what to do when someone interrupts.
Connections that survive
Tickets, keepalives, close codes, resume.
Build a voice agent in a browser
Working end-to-end code, reconnect included.