Authentication
Every request authenticates with an API key in the standard Authorization header. Keys are created in the dashboard and can be scoped and restricted per use case.
The Authorization header
every request
Authorization: Bearer sk-gw-...
That is the only authentication mechanism — no query-string tokens, no cookies. The OpenAI SDKs send this header for you when you set api_key.
Key format and storage
- Keys start with
sk-gw-. The full key is shown exactly once, at creation. We store only a SHA-256 hash plus the last 4 characters — a lost key cannot be recovered, only replaced. - Create, revoke and configure keys on the API keys page of the dashboard. A programmatic key-management API is planned, not available yet.
Scopes
A key carries one or both scopes; endpoints outside them return 403.
| Scope | Grants |
|---|---|
chat | Inference: POST /v1/chat/completions |
usage:read | Read-only billing surfaces: GET /v1/credits, GET /v1/generation, GET /v1/usage |
GET /v1/models needs any valid key, no specific scope. A missing scope returns missing_scope; the message names the scope the endpoint needs.
Per-key restrictions
Each restriction is optional and set per key in the dashboard:
- Allowed models — calls outside the list return
403 model_not_allowed. - IP allowlist — calls from other IPs return
401 ip_not_allowed(the key itself stays valid). - Expiry date — after it, the key returns
401 key_expired. - Rate and spend caps — per-key rpm/tpm and a daily budget can be set below the organization limits; see Rate limits.
The four 401 codes
| Code | Meaning |
|---|---|
invalid_api_key | The key is unknown. Check you copied it whole, including the sk-gw- prefix. |
key_revoked | The key was revoked in the dashboard. Create a new one. |
key_expired | The key is past its expiry date. Create a new one. |
ip_not_allowed | The key is valid but the calling IP is outside its allowlist. |
Keeping keys safe
- Load keys from environment variables or a secret manager — never commit them.
- Call the gateway from your backend. A key shipped inside a browser or mobile app is public.
- Use one key per application or environment so a leak has a small blast radius.
- Set per-key limits (rpm, tpm, daily budget) when you create the key — they are your pre-paid damage cap if it ever leaks.
If a key leaks
- Revoke it now on the API keys page — revocation is immediate, in-flight requests finish but no new request authenticates.
- Create a replacement key and rotate it into your deployment.
- Check
GET /v1/usageand the request log for traffic you do not recognize during the exposure window — spend is capped by your balance and any per-key daily budget, and prepaid means the worst case is bounded. - If anything looks off or you need help reading the window, write to [email protected] with the key’s last 4 characters (never the full key).