Speko Docs

Streaming

The canonical session WebSocket — subprotocol, frames, and the event schema.

Attaching

GET /v1/sessions/{session_id}/stream upgrades to a WebSocket. Requirements:

  • Authorization: Bearer <SPEKO_LOCAL_AUTH_TOKEN>
  • The subprotocol speko.voice.v0.r3, sent as Sec-WebSocket-Protocol (missing → 400 unsupported_protocol)
  • One consumer per session — a second attach returns 409 stream_already_attached
  • Attach within 30 seconds of session creation

Client → gateway frames

FrameMeaning
binaryRaw audio in the session's media format
{"type":"audio.commit"}End of the current audio input
{"type":"text.append","data":{"text":"Hello"}}Append text input (TTS/LLM)
{"type":"text.commit"}Flush appended text
{"type":"response.cancel"}Cancel the in-flight response
{"type":"session.close"}Close the session cleanly

Anything else is a connection error. Input is bounded per session: 64 queued messages / 1 MiB queued bytes — producers that outrun the provider see backpressure errors rather than unbounded memory growth.

Gateway → client frames

Binary frames carry synthesized audio. Text frames are JSON events:

{
  "type": "transcript.final",
  "event_id": "evt_...",
  "session_id": "session_...",
  "attempt_id": "attempt_...",
  "sequence": 12,
  "created_at_ms": 1754000000000,
  "data": { "text": "Hello there." }
}

Event types:

CategoryEvents
Lifecyclesession.ready, session.recovering, session.recovered, session.closed
Speechspeech.started, speech.ended
Transcriptiontranscript.delta, transcript.final
Generationresponse.started, text.delta, text.done, tool.call, response.done, response.cancelled
Audioaudio.started, audio.done (audio itself arrives as binary frames)
Metadataalignment, route.selected, usage.observed, usage.reported, warning, error

The error event

{
  "type": "error",
  "data": {
    "code": "provider_unavailable",
    "message": "...",
    "retryable": true,
    "terminal": true,
    "source": "provider",
    "provider_status": 503
  }
}

source is runtime or provider. Provider-sourced codes: provider_unavailable, provider_rate_limited, provider_quota_exceeded, authentication_failed, invalid_request, input_too_large. Runtime codes include internal and session_lease_expired. The latter means the fixed deadline in the verified plan elapsed; provider-direct sessions do not renew it mid-call.

Liveness

Frames the gateway writes time out after 15 seconds if the consumer stalls; slow consumers see the session terminated rather than blocking other sessions.

On this page