Realtime voice is available on request. Contact your AI Reserve representative to have
realtimeVoiceEnabled
turned on for your organization — until then, session mints return 403. In environments where the voice relay is not
deployed they return 503.How it works
Because a WebSocket cannot ride the normal request/response gateway, the flow has two steps:- Mint a session credential — one API call that authenticates you, reserves funds, selects
the voice, and returns a short-lived
ephemeral_keyandwss_url. - Connect your WebSocket directly to
wss_urlusingephemeral_key. Drive the session with audio I/O events only.
Step 1: Mint a session
POST /v1/realtime/sessions authenticates the caller, checks the org gate, resolves voice
ownership, reserves worst-case session funds from your wallet, and returns the credentials.
The voice parameter selects which voice the relay will use for this session. Pass:
- Any built-in voice ID from
GET /v1/voices(e.g."ara","atlas","luna") — no extra org gate required. - One of your organization’s custom voice IDs from
GET /v1/custom-voices— requires thecustomVoicesEnabledorg gate in addition torealtimeVoiceEnabled.
voice defaults to "ara" when omitted.
201:
ephemeral_key is an HMAC-SHA-256 signed, opaque, one-use relay ticket — not an API
key. The token itself encodes only an expiry timestamp and a random nonce; it does not
carry a voice ID. Voice authorization lives in the session record: the relay stores the
authorized voice and ticket state in a DB row keyed by the ticket’s SHA-256 hash at mint time.
The ticket is valid for 5 minutes and consumed on first use — a replay is rejected even within
the TTL. Mint a new session for each conversation; do not log or share the key.
Step 2: Connect the WebSocket
From a server — pass the key as a bearer token header:browser_subprotocols
array from the mint response verbatim:
session.update event with the authorized voice before forwarding any client audio. The voice
is bound in the session record — the client cannot change it mid-session.
Supported WebSocket events
The relay enforces an audio-only event allowlist. Only the following client→relay events are accepted; anything else closes the connection with code1008:
session.update is additionally sanitized: only instructions, turn_detection, and audio
fields are forwarded. voice is always forced to the value selected at mint regardless of what
the client sends.
Relay→client messages are forwarded as-is from the xAI engine.
Text output, transcription, tool calling, and session resumption are not supported in this release. Attempting to
enable transcription or tools via
session.update will not work — those fields are stripped. See Deferred
features.Available voices
Pass a supported built-in voice ID or one of your organization’s custom voice IDs (requirescustomVoicesEnabled). The default when voice is omitted is ara. Use GET /v1/voices to
retrieve the current catalog with names, languages, and genders; catalog additions are enabled on
the synthesis surfaces after AI Reserve verifies and deploys them.
To create custom voice clones for your organization, see Text-to-speech.
Billing and limits
Usage appears on your ledger and dashboards like any other model call (unit: audio seconds) and
counts toward the same wallet and budget caps.
Audio persistence
AI Reserve does not persist audio from realtime sessions. Session metadata (duration, cost, voice ID, session ID) is stored for billing and usage reporting; no audio content is retained.Enable realtime voice
- Contact your AI Reserve representative (or the Help page in the portal) to enable
realtimeVoiceEnabledfor your organization. - Optionally enable
customVoicesEnabledif you want to use custom voice clones in sessions. - Mint a session and connect — the two-step flow above is the full integration.
- Watch your usage dashboard: each session appears as one audio usage row with duration and cost.
Deferred features
The following are not available in this release:- Standalone speech-to-text: transcription calls without voice synthesis. See
POST /v1/audio/transcriptionsfor the existing OpenAI-compatible transcription endpoint. - Streaming TTS: text-in, audio-out streaming without a microphone. See
POST /v1/audio/speechfor synchronous (non-streaming) TTS withgrok-tts. - SIP / telephony integration: direct PSTN or SIP dial-in/dial-out.
- Tool calling in realtime sessions: function calling over the realtime session is not available in this release.
- Session resumption: each
POST /v1/realtime/sessionsmint starts a fresh session; reconnecting to a prior session is not supported.