Skip to main content
Realtime audio is a WebSocket gateway at wss://api.meshapi.ai/v1/realtime. Most issues are connection, auth, or event-shape problems. See Realtime Audio for the full reference.

Can’t connect over HTTP

This endpoint exists only as a WebSocket upgrade. A plain HTTP request to /v1/realtime is not served. Connect with a WebSocket client. Also, TLS is mandatory: ws:// is rejected, use wss://.

Auth fails, especially in the browser

Two methods: the Sec-WebSocket-Protocol: openai-realtime, Bearer <rsk_...> subprotocol (preferred), or ?api_key=<rsk_...> on the URL.
  • Browsers can’t set request headers on a WebSocket and can’t reliably send the space-separated Bearer subprotocol — use the ?api_key= query fallback.
  • If both are present, the subprotocol wins.
  • An Authorization header is not read on this endpoint. A client that only sets one (e.g. websocat -H "Authorization: ...") gets invalid_api_key.

session.update is rejected

Realtime uses OpenAI’s GA event protocol. Use the GA shape ({"type":"realtime","output_modalities":[...],"audio":{...}}). The older beta shape (modalities / voice / input_audio_format) is rejected.

Audio isn’t received

Audio frames are base64 inside text events (input_audio_buffer.append up, response.output_audio.delta down), as OpenAI’s protocol defines. Mesh forwards binary WebSocket frames unchanged, but the protocol doesn’t read raw PCM sent that way. Send audio as input_audio_buffer.append events.

Session drops after a while

  • 30-minute cap. Mesh closes the session with session_duration_exceeded. Reconnect and resume app-level state for long agents.
  • 60s idle timeout. Mesh closes a socket with no client→server frame for 60s, with idle_timeout. Keep the audio buffer flowing or send a session.update ping.
  • service_draining / connection_timeout. The server restarted or the heartbeat was lost. Reconnect.

Reading errors — use error.code, not the close code

Errors arrive as a JSON frame ({ "type": "error", "error": { "code", "message" }, "request_id" }) just before the socket closes. Branch on error.code — the close code is incidental. More codes, including the lifecycle ones, are in the error code reference. Close codes seen: 1000 (normal closure, including auth, quota and limit errors) and 1011 (server/upstream conditions).

Session won’t open / billing surprises

  • Opening a session holds up to $10 of your balance until it closes; if your balance can’t cover the hold, you get insufficient_quota.
  • Sessions cut short (network drop, tab close) still bill for tokens already processed.
  • There’s no in-stream cost message. Usage is settled every 60 seconds and at close. Query GET /v1/usage for canonical numbers.

Still stuck?

See the Mesh API error reference or email contact@meshapi.ai.