Observability
Health probes, Prometheus metrics, and what telemetry the gateway exports.
Health probes
Both are unauthenticated:
GET /healthz→200 {"status":"ok"}GET /readyz→200 {"status":"ready"}, or503 {"status":"draining"}during shutdown
Prometheus metrics
GET /metrics (authenticated, unlike the probes) serves the standard text format:
| Metric | Type | Meaning |
|---|---|---|
speko_gateway_sessions_active | gauge | Currently open sessions |
speko_gateway_sessions_total | counter | Sessions ever created |
speko_gateway_draining | gauge | 1 while shutting down |
speko_gateway_auth_failures_total | counter | Local auth rejections |
speko_gateway_input_queue_messages / ..._bytes | gauge | Input backpressure |
speko_gateway_telemetry_dropped_total | counter | Telemetry events dropped under pressure |
speko_gateway_warm_plan_hits_total, ..._misses_total, ..._expired_total, ..._refill_failures_total | counter | Warm-pool effectiveness |
speko_gateway_warm_plan_depth, ..._routes | gauge | Warm-pool state |
Telemetry
The gateway exports content-free events to Speko — no audio, no transcripts, no prompts, no tool arguments, no credentials, ever:
| Event | Payload |
|---|---|
session.opened | provider connection latency ({"provider_open_ms": N}) |
agent.event | canonical event type and sequence number |
usage.observed | provider request correlation ID |
usage.reported | accepted usage quantity |
session.closed | no payload |
error | error class, source, retryability, provider HTTP status |
Delivery is asynchronous and bounded (queue 1024, batches of 64, 3 attempts); under pressure events are dropped and counted rather than blocking media.
SPEKO_TELEMETRY_DISABLED=true suppresses anonymous and optional events. On managed routes, usage.reported, usage.observed, and the terminal event still flow — they are the billing record. BYOK routes have no mandatory events.
Conversation profiler
The optional LiveKit ConversationProbe posts content-free markers to the gateway's local POST /v1/turn-events route. The gateway forwards managed markers to gateway.speko.dev/v1/turn-events with authentication, or BYOK markers to /v1/anonymous-turn-events without an authorization header.
Markers cover conversation and turn boundaries, speech timing, final-transcript timing, LLM first-token/completion, tool timing, TTS first audio, playback, interruptions, and attached route IDs. They never contain transcripts, prompts, model output, tool names or arguments, synthesized text, or audio. Conversation and turn IDs are random and opaque. Delivery is optional, bounded, and disabled by SPEKO_TELEMETRY_DISABLED=true.
Heartbeats and the dashboard
When a Speko API key is configured, the gateway heartbeats its instance identity, capacity, and session counters to the control plane every SPEKO_INSTANCE_HEARTBEAT_INTERVAL (default 20 s). Set SPEKO_WORKLOAD_ID (and optionally SPEKO_WORKLOAD_TYPE) to group instances into a named workload in the dashboard.