Skip to content
Documentation
Esc
navigateopen⌘Jpreview
On this page

Authentication

API keys for the control plane, short-lived WebSocket tokens for the media stream — what to use where, and how to handle both safely.

Every Orvyn API surface is authenticated, with two different credential types for two different planes:

Credential Where it is used Lifetime
API key All six /v1/ REST endpoints (headers) Long-lived, admin-managed
WebSocket token The media WebSocket (?token= in ws_url) Short-lived, 5 minutes

API key authentication

All /v1/ routes accept your API key via either header:

Authorization: Bearer <api_key>
x-api-key: <api_key>

Where keys come from

API keys are created and revoked through the admin surface of the API itself:

  • POST /v1/api-keys — create a key. The plaintext is shown exactly once at creation; Orvyn stores only a SHA-256 hash.
  • DELETE /v1/api-keys/{key_id} — revoke a key. Revocation takes effect immediately; keys do not expire on their own.

Auth errors

Status error.code Meaning
401 missing_api_key No key provided
403 invalid_api_key Key not recognized or revoked
503 api_auth_not_configured Server has no keys configured

WebSocket token authentication

The media WebSocket (GET /v1/sessions/{session_id}/ws) is not API-key authenticated. It uses a short-lived HMAC-signed token embedded in the connection URL:

wss://<orvyn-public-api-host>/v1/sessions/{session_id}/ws?token=...

Token properties

Property Value
Signing HMAC-SHA256
TTL 5 minutes (300 seconds)
Payload Session id, tenant id, purpose — never the raw API key
Binding Bound to one session id and one tenant

The token is the authorization: anyone holding a valid token can connect to that session’s WebSocket. This is by design, but it means the URL must be handled like a credential.

Token lifecycle

You receive the first token in the POST /v1/sessions response (stream.ws_url includes it). For reconnects after the 5-minute expiry, mint a fresh one:

curl -X POST \
  "https://<orvyn-public-api-host>/v1/sessions/$SESSION_ID/client-token" \
  -H "Authorization: Bearer $AVTR_API_KEY"
{
  "success": true,
  "data": {
    "ws_url": "wss://<orvyn-public-api-host>/v1/sessions/session:.../ws?token=eyJ...",
    "token_expires_at": 1718352600000
  },
  "timings": { "latency_ms": 3 }
}

What to never put in a URL

Never in a URL Use instead
API keys (Authorization values) Headers on REST calls
Long-lived provider credentials provider_config in POST /v1/sessions, minted per session by your backend
The full ws_url in logs/analytics Open the connection, then discard the URL

Request correlation

Every /v1/ response includes an X-Request-Id header for tracing. You may supply your own (1–128 characters of [a-zA-Z0-9_-]); it is echoed back when valid, otherwise a fresh id is generated. The id also appears in the timings object of JSON responses.

Request shape contract

Every response uses one envelope:

{
  "success": true,
  "data": {},
  "timings": { "latency_ms": 123 }
}

Errors keep the same shape with "success": false and an error object carrying a stable code — see errors, limits & security.

Was this page helpful?