Docs
Speko Router API quickstart
Call Speko Router's native model discovery, speech-to-text, LLM, and text-to-speech operations with typed responses.
Set the credential
export SPEKO_API_KEY=sk_live_...
export SPEKO_ROUTER=https://router.speko.devDiscover models
curl --fail --silent "$SPEKO_ROUTER/v1/models" \
-H "Authorization: Bearer $SPEKO_API_KEY"Transcribe audio
curl --fail --silent "$SPEKO_ROUTER/v1/stt/transcriptions" \
-H "Authorization: Bearer $SPEKO_API_KEY" \
-H "Idempotency-Key: stt-$(uuidgen)" \
-F 'request={"routing":{"mode":"auto","objective":"latency"},"language":"en"};type=application/json' \
-F 'audio=@sample.wav;type=application/octet-stream'Response
{
"text": "What time do you close on Saturday?",
"route": {"provider": "deepgram", "model": "nova-3", "region": "us-west-2", "attempt_id": "att_..."},
"usage": {"duration_ms": 1840}
}Generate an LLM response
curl --fail --silent "$SPEKO_ROUTER/v1/llm/responses" \
-H "Authorization: Bearer $SPEKO_API_KEY" \
-H "Idempotency-Key: llm-$(uuidgen)" \
-H "Content-Type: application/json" \
--data '{
"routing": {"mode": "auto", "objective": "quality"},
"input": [{"type": "message", "role": "user", "content": [{"type": "text", "text": "What time do you close on Saturday?"}]}],
"max_output_tokens": 128
}'Response
{
"id": "resp_req_...",
"route": {"provider": "openai", "model": "gpt-5.2", "region": "us-west-2", "attempt_id": "att_..."},
"output": [{"type": "message", "role": "assistant", "content": [{"type": "text", "text": "We close at six on Saturday."}]}],
"stop_reason": "stop",
"usage": {"input_tokens": 18, "output_tokens": 11}
}Synthesize speech
curl --fail --silent "$SPEKO_ROUTER/v1/tts/speech" \
-H "Authorization: Bearer $SPEKO_API_KEY" \
-H "Idempotency-Key: tts-$(uuidgen)" \
-H "Content-Type: application/json" \
--data '{
"routing": {"mode": "auto", "objective": "balanced"},
"input": "We close at six on Saturday.",
"language": "en",
"audio": {"encoding": "pcm_s16le", "sample_rate_hz": 24000, "channels": 1}
}' \
--output reply.pcmRoutes
| GET /openapi.json | Download the canonical OpenAPI 3.1 contract without authentication |
|---|---|
| GET /v1/models | List currently routable models and capabilities |
| POST /v1/stt/transcriptions | Transcribe one uploaded audio file |
| GET /v1/stt/stream | Open a realtime transcription WebSocket |
| POST /v1/tts/speech | Synthesize one utterance to a raw audio stream |
| GET /v1/tts/stream | Open a streaming synthesis WebSocket |
| POST /v1/llm/responses | Generate a typed JSON or SSE LLM response |
Request headers
| Authorization | Bearer Speko API key. Required on every /v1 operation. |
|---|---|
| Idempotency-Key | Required on every POST and WebSocket upgrade. Reuse only for a byte-identical retry. |
| Content-Type | application/json, multipart/form-data, or the media type declared by the operation. |
Response headers
| Speko-Request-ID | Router correlation id; also appears in error envelopes when available. |
|---|---|
| Speko-Attempt-ID | The attempt that produced the response after any pre-output fallback. |
| Speko-Provider | The concrete provider selected for this response. |
| Speko-Model | The concrete provider model selected for this response. |
| Speko-Region | The Speko Router region that served the request. |
| RateLimit-Policy | Default edge policy: "relay-ip";q=2000;w=300. Lower concurrency controls may also apply. |
| Retry-After | Minimum delay on an application-generated 429; continue with exponential backoff. |
Errors
| 400 | invalid_request | Correct the fields named by message and hint. |
|---|---|---|
| 401 | authentication_failed | Replace or reactivate the bearer key. |
| 404 | route_not_found | Read /openapi.json and use a declared route. |
| 405 | method_not_allowed | Use the method in the Allow header. |
| 409 | idempotency_conflict | Use a new Idempotency-Key when content changes. |
| 429 | rate_limited | Honor Retry-After and use exponential backoff. |
| 429 | concurrency_exhausted | Wait for active work to finish, then retry. |
| 502 | provider_error | Retry or allow Router to select another provider. |
| 503 | provider_unavailable | Retry after a delay or use auto routing. |
| 504 | request_timeout | Retry; the selected provider stopped making progress. |
Give the contract to an agent
Read https://speko.ai/openapi.json. Integrate the native Speko Router contract into this repository. Do not treat Router as an OpenAI-compatible hostname. Use Idempotency-Key on every POST and preserve the typed error envelope.