Quickstart
Call the relay with curl — transcribe, synthesize, and generate in five minutes.
1. Get an API key
Create a key in the dashboard's Gateway keys page and export it:
export SPEKO_API_KEY=sk_speko_...2. List routable models
curl -s https://relay.speko.dev/v1/models \
-H "Authorization: Bearer $SPEKO_API_KEY"{
"models": [
{
"id": "deepgram:flux-general-en",
"provider": "deepgram",
"kind": "stt",
"capabilities": { "tools": false, "structured_output": false, "cached_input": false, "reasoning": false },
"regions": ["us-east-1"]
}
],
"catalog_digest": "sha256:..."
}3. Transcribe an audio file
The request is multipart with exactly two parts, request then audio, in that order:
curl -s https://relay.speko.dev/v1/stt/transcriptions \
-H "Authorization: Bearer $SPEKO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-F 'request={"routing":{"mode":"auto","objective":"balanced"},"language":"en"};type=application/json' \
-F 'audio=@meeting.wav;type=audio/wav'{
"text": "Good morning everyone, let's get started.",
"segments": [{ "text": "Good morning everyone, let's get started.", "start_ms": 0, "end_ms": 2900 }],
"route": { "provider": "deepgram", "model": "flux-general-en", "region": "us-east-1", "attempt_id": "ratt_..." },
"usage": { "duration_ms": 3000 }
}4. Synthesize speech
The response body is raw audio; the character count you were metered for comes back in the Speko-Usage-Characters header.
curl -s https://relay.speko.dev/v1/tts/speech \
-H "Authorization: Bearer $SPEKO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"routing": { "mode": "auto", "objective": "latency" },
"input": "Your table is ready.",
"audio": { "encoding": "pcm_s16le", "sample_rate_hz": 24000, "channels": 1 }
}' \
--output speech.pcm5. Generate a model response
max_output_tokens is required — an unbounded generation cannot be priced up front.
curl -s https://relay.speko.dev/v1/llm/responses \
-H "Authorization: Bearer $SPEKO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"routing": { "mode": "explicit", "provider": "anthropic", "model": "claude-sonnet-5" },
"input": [
{ "type": "message", "role": "user", "content": [{ "type": "text", "text": "Say hello in French." }] }
],
"max_output_tokens": 100
}'{
"id": "resp_rreq_...",
"route": { "provider": "anthropic", "model": "claude-sonnet-5", "region": "us-east-1", "attempt_id": "ratt_..." },
"output": [
{ "type": "message", "role": "assistant", "content": [{ "type": "text", "text": "Bonjour !" }] }
],
"stop_reason": "stop",
"usage": { "input_tokens": 21, "output_tokens": 5 }
}Next
- Routing — objectives, allow/deny lists, and explicit provider pinning
- Bring your own provider keys — provider billing and credential-source-preserving failover
- Streaming STT and streaming TTS over WebSocket
- Errors — the closed error-code set and retry guidance