Speko Docs

Speech-to-speech

Run a vendor realtime voice model through the Router — provider price plus 5%, one key, one host.

The Router speaks the vendors' own realtime wire protocols, so an existing speech-to-speech client works by swapping only the host and the API key. The Router holds the vendor socket, meters the session, and bills the provider's published price + 5% against your Speko balance — no vendor key of your own, no per-vendor billing.

Endpoints

ProtocolRouteModels
OpenAI / xAI Realtimewss://router.speko.dev/v1/realtime?model=<id>gpt-realtime-2, gpt-realtime-2.1, gpt-realtime-2.1-mini, grok-voice-3.0, grok-voice-think-fast-2.0
Gemini Live (BidiGenerateContent)wss://router.speko.dev/v1/bidigemini-3.8-live, gemini-3.8-live-extended-thinking
GPT-Livewss://router.speko.dev/v1/livegpt-live-1

For /v1/realtime the model rides the model query parameter; for /v1/bidi and /v1/live it rides the first setup/session frame, exactly as each vendor defines it. The full, per-organization catalog is GET /v1/models (kind s2s).

Authentication

Every upgrade carries your Speko key as a bearer token:

Authorization: Bearer sk_speko_...

An Idempotency-Key header is currently required on the WebSocket upgrade (any non-blank string up to 256 bytes — a UUID per session is the right default). A future release makes it optional on the voice routes and mints one server-side when absent; until then, send one. Browsers cannot set custom headers on a WebSocket upgrade, so terminate Router voice sockets from your backend.

Pricing

The provider's published per-minute (or per-token) realtime price + 5%, settled per second against your Speko balance and shown on the usage and activity pages. There is no Speko flat minute on the Router — see billing.

OpenAI SDK

Point the Realtime client at the Router and send your Speko key:

import { OpenAIRealtimeWebSocket } from "openai/realtime/websocket";

const rt = new OpenAIRealtimeWebSocket({
  model: "gpt-realtime-2.1",
  baseURL: "wss://router.speko.dev/v1",
  apiKey: process.env.SPEKO_API_KEY,
  // Send on the upgrade until Idempotency-Key becomes optional on voice routes.
  headers: {
    "Idempotency-Key": crypto.randomUUID(),
  },
});

LiveKit Agents

Give the OpenAI/xAI realtime plugin the Router base URL, the Speko key, and the upgrade header:

from livekit.plugins.openai.realtime import RealtimeModel

model = RealtimeModel(
    model="gpt-realtime-2.1",
    api_key=os.environ["SPEKO_API_KEY"],
    base_url="wss://router.speko.dev/v1",
    # LiveKit forwards extra headers on the realtime upgrade.
    extra_headers={"Idempotency-Key": str(uuid.uuid4())},
)

For Gemini Live, use the google realtime plugin against /v1/bidi.

Pipecat

from pipecat.services.openai_realtime import OpenAIRealtimeBeta

llm = OpenAIRealtimeBeta(
    api_key=os.environ["SPEKO_API_KEY"],
    base_url="wss://router.speko.dev/v1",
    session_properties={"model": "gpt-realtime-2.1"},
    headers={"Idempotency-Key": str(uuid.uuid4())},
)

Errors

Upgrade-time failures (bad key, unknown model, missing idempotency key) return a JSON error envelope before the socket switches protocols; after the upgrade, errors arrive as the vendor's own error events. See errors.

On this page