Skip to main content
Every request authenticates with a bearer API key.
Authorization: Bearer pyai_live_...
x-api-key: pyai_live_... is an accepted alias for environments where setting an Authorization header is awkward.
Keys are opaque strings (up to 512 characters). Never parse, split, or decode them. They are self-validating and work on every PyAI surface the instant they are created — there is no activation or propagation delay.

Environments

PrefixEnvironmentUse it for
pyai_test_SandboxEvals, prototypes, CI. Works instantly against production models with hard daily caps and no billing.
pyai_live_ProductionReal traffic, billed against your plan and credits.
Create either in the console. The key is shown once — store it as a secret (environment variable), never in source control.

Scopes

Keys carry scopes that gate which products they can call:
ScopeGrants
hear:transcribePOST /v1/audio/transcriptions, transcription jobs (Hear)
hear:streamstreaming transcription / Cue (GET /v1/audio/transcriptions/stream)
voice:synthesizePOST /v1/audio/speech (Speak)
voice:clone/v1/voice/clones (Speak)
omni:sessionOmni realtime sessions (/v1/omni, /v1/realtime)
flow:sessionlegacy — Flow realtime sessions (retired for new customers)
GET /v1/models and GET /v1/voices are catalog reads — any active key may call them. A request whose key lacks the required scope returns 403 forbidden.

WebSocket authentication

Browsers can’t set headers on a WebSocket upgrade, so pass the key as a subprotocol:
Sec-WebSocket-Protocol: pyai-key.pyai_live_...
Server-side clients may instead append ?api_key=... to the URL. Never put the key in any other query parameter.

Rotation & revocation

Each key in the console has rotate and revoke controls.
  • Rotate issues a new secret and invalidates the old one.
  • Revoke disables the key everywhere within 60 seconds.
After revocation, calls with the old key return 401 unauthorized.
If a key is ever exposed, revoke it immediately and mint a new one — there is no penalty for rotating often.