> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stateset.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Voice API

> Call control, media streaming, session supervision, and the admin surface.

# Voice API

Interactive documentation is served by the running instance at `/swagger-ui`, with the OpenAPI
3.0 document at `/api-docs/openapi.json`.

## Service

| Endpoint                     | Purpose                                     |
| ---------------------------- | ------------------------------------------- |
| `GET /`                      | Service metadata, timestamp, org id         |
| `GET /health`                | Health information, active sessions, uptime |
| `GET /health/live`           | Kubernetes liveness probe                   |
| `GET /health/ready`          | Kubernetes readiness probe                  |
| `GET /metrics`               | Prometheus metrics                          |
| `GET /swagger-ui`            | Interactive OpenAPI documentation           |
| `GET /api-docs/openapi.json` | OpenAPI 3.0 specification                   |

## Calls

| Endpoint                          | Purpose                                      |
| --------------------------------- | -------------------------------------------- |
| `POST /make-call`                 | Place an outbound call via Twilio REST       |
| `POST /voice/web-calls`           | Mint a signed browser voice session          |
| `POST /call-status`               | Twilio status callbacks, signature-validated |
| `GET /media-stream` *(WebSocket)* | Twilio media bridge                          |

`POST /make-call` supports an **`Idempotency-Key`** with 24-hour replay protection, a transient
per-call `config` (custom tools included) for prototyping, and persisted `metadata`.

<Note>
  Browser calls run the same media protocol and pipeline as phone calls, so anything configured
  for telephony — agents, tools, transfers, evals — applies unchanged.
</Note>

### Media stream authentication

The WebSocket handshake authenticates a tenant by `Authorization: Bearer …` or a short-lived
signed `?stream_token=…`.

<Warning>
  Raw tenant-token query transport is **opt-in** via `LEGACY_QUERY_AUTH_ENABLED=true` and exists
  for migration only. It defaults to off. Configure `STREAM_AUTH_SECRET` to issue signed
  `stream_token` values instead.

  In `NODE_ENV=production`, startup **fails fast** if legacy auth is off and `STREAM_AUTH_SECRET`
  is not configured — so you cannot accidentally deploy with neither.
</Warning>

## Sessions and supervision

| Endpoint                             | Purpose                   |
| ------------------------------------ | ------------------------- |
| `GET /sessions`                      | Enumerate active sessions |
| `POST /sessions/:id/actions/:action` | Supervisor action         |
| `GET /logs` *(WebSocket)*            | Real-time broadcast logs  |

Supervisor actions: **`monitor`**, **`whisper`**, **`barge`**, **`escalate`**, **`end`**.

## Functions and automations

| Endpoint                | Purpose                                                |
| ----------------------- | ------------------------------------------------------ |
| `GET /tools`            | Function registry definitions, for OpenAI tool priming |
| `POST /test-function`   | Execute a function manually with a JSON payload        |
| `POST /automations/...` | Automation endpoints backed by the function registry   |

## Human handoff

`/transfer-call` dials a human with a bounded ring timeout
(`twilio.human_agent_timeout_seconds`, default 25s). If nobody answers, `/transfer-complete`
**reconnects the caller to the AI** with a message-taking greeting rather than Twilio's default
hangup. A failed background escalation likewise speaks a recovery prompt — counted by
`escalation_bridge_failed_total` — instead of leaving the caller on a silent line.

## Admin

Admin routes require `ADMIN_API_KEY`, passed as `x-admin-key`.

| Endpoint                                                | Purpose                                                              |
| ------------------------------------------------------- | -------------------------------------------------------------------- |
| `GET /admin/sessions`                                   | Active sessions across cached tenants                                |
| `GET /admin/auth/transport`                             | Auth transport diagnostics                                           |
| `GET /admin/alerts/auth-transport`                      | Rollout alert evaluation — `ok`/`warn`/`error` with alert codes      |
| `GET /admin/tenants/cached`                             | Cached-tenant runtime summary                                        |
| `GET /admin/tenants/audio-providers`                    | Configured vs effective audio provider, fallback state and reason    |
| `GET /admin/tenants/cache-metrics`                      | Entries, hits, misses, reloads, evictions                            |
| `GET /admin/tenants/cache-metrics/by-token`             | Top token-level cache counters                                       |
| `POST /admin/tenants/reload-cached`                     | Reload cached tenants, preserving live session and log state         |
| `POST /admin/tenants/evict-idle`                        | Evict idle cache entries (`max_idle_secs`)                           |
| `GET /admin/twilio/webhook-diagnostics`                 | Tenant-resolution diagnostics — hint-cache size, counters, hit rates |
| `POST /admin/twilio/webhook-diagnostics/cache/clear`    | Clear hint-cache entries for incident recovery                       |
| `POST /admin/twilio/webhook-diagnostics/counters/reset` | Reset diagnostics counters                                           |

<Note>
  `GET /metrics` on the main port requires `x-admin-key`. The dedicated `METRICS_PORT` is
  **unauthenticated** and must be network-restricted.
</Note>

Admin tenant responses **redact secrets**, and updates can preserve existing values by sending
the `<redacted>` placeholder. Tenant reads expose deterministic config ETags, so writes can use
`If-Match` to avoid lost updates.

## Related

* [Configuration](/stateset-voice/configuration)
* [Webhooks](/stateset-voice/webhooks)
* [SDKs](/stateset-voice/sdks)
