Skip to main content

Introduction

Establish low-latency real-time voice sessions over WebSocket, compatible with the OpenAI Realtime API. After connecting, exchange audio and text via the event protocol—suitable for voice assistants, live translation, and similar use cases. Base URL: wss://api.gravitex.ai/v1/realtime
You must use the WebSocket protocol, not a standard HTTP POST. model must be passed as a query parameter; otherwise the gateway returns 400.

Authentication

Include the following headers when establishing the WebSocket connection:
string
required
Bearer token, e.g. Bearer sk-xxxxxxxxxx
string
required
Must be realtime=v1
Browsers cannot set custom WebSocket headers. Use OpenAI subprotocols to pass the key (equivalent to headers; parsed by the gateway):

Connection

string
required
Realtime model ID, e.g. gpt-realtime-1.5, gpt-realtime-2. Must match a model available to your API key.
On success, the server returns 101 Switching Protocols. You will then receive session.created; send session.update to complete session configuration.

Session configuration

After connecting, send session.update to set instructions, output modalities, and audio format:
Available voices (when output_modalities includes audio): alloy · ash · ballad · coral · echo · sage · shimmer · verse · marin Wait for session.updated before starting the conversation.

Sending messages

Each turn has two steps:
  1. conversation.item.create — write the user message
  2. response.create — trigger model generation

Text input

Audio input

Recordings must be PCM16 raw bytes (no WAV header), Base64-encoded:
You can combine multiple input types in one turn, e.g. image + text or image + audio:
Image input limitation: Some upstream providers (e.g. Azure OpenAI Realtime) do not support images—only input_text and input_audio. Sending images may trigger a server 500 error. Vision is only available on non-Realtime Chat Completions / Responses endpoints. See Microsoft’s official note. Keep Base64 image length under 1,048,576 characters (~750 KB original).
After writing the message, trigger the response:

Receiving responses

Common server events: Audio delta fields may be audio or delta; clients should handle both.

Usage

Each response.done returns usage for that Response only, not session cumulative totals. Official docs: “The tokens used for a Response can be read from the response.done event”. For multi-turn sessions, track both per-turn and cumulative usage. Example usage structure:

Field reference

  1. output.text_tokens: Even with audio output, automatic transcript generates text tokens—this is normal billing. See OpenAI Realtime costs.
  2. input.cached_tokens: A subset of input_tokens, not additive. OpenAI returns cached_tokens_details (text/audio split); when upstream (e.g. Azure GA) does not, the gateway estimates by text/audio input ratio.
  3. Multi-turn cost: Each Response sends the full conversation history, so input_tokens grow over time; earlier turns often hit prompt cache with high discounts (e.g. gpt-realtime-2 audio cache 0.40/1Mvsaudioinput0.40/1M vs audio input 32/1M = 98.75% off). Official docs: “turns later in the session will be more expensive”.

Full Python example

Dependencies: pip install websockets pyaudio
For a full interactive script (microphone recording, speaker playback, image input, per-turn and cumulative usage), see test_realtime.py.

FAQ

  • 400 on connect: Check that the URL includes the ?model=... query parameter.
  • 401 on connect: Invalid or unauthorized API key; call GET /v1/models to verify key and model availability.
  • No response after send: Confirm you received session.updated and sent response.create.
  • Disconnect after 500: Upstream errors close the WebSocket—reconnect.
  • No audio: Confirm 24 kHz PCM16 mono and correct Base64 decoding before playback.
For more event types and fields, see the OpenAI Realtime API docs.