Authentication
API keys, sessions, scopes, email verification, and safe credential storage.
View as Markdown →Ozma uses two credential types on the control plane (https://api.ozma.app) and one on the gateway (https://gateway.ozma.app).
API keys vs sessions
| Credential | Format | Where it works | Scopes |
|---|---|---|---|
| API key | ozma_live_… (24 chars after prefix) |
Control plane + gateway | Stored on the key record; see below |
| Session token | sess_… |
Control plane only | Full marketplace scopes |
Send either as:
Authorization: Bearer <token>
Gateway rejects sessions. Proxy calls require an API key (ozma call, SDK proxyCall, MCP call_api). The web dashboard uses sessions for UI actions (billing portal, terms acceptance, profile edits).
The CLI and SDK store both in ~/.ozma/config.json. When both are present, the control plane prefers the session token; the gateway always uses the API key.
Scopes
| Scope | Purpose |
|---|---|
catalog:read |
Search, inspect, leaderboards |
proxy:call |
Gateway proxy calls |
keys:write |
Create, revoke, patch API keys |
usage:read |
Usage history |
billing:write |
Checkout, SetupIntent, portal, auto-reload |
provider:write |
Provider API lifecycle, documents, Connect |
Anonymous auto-register (POST /v1/register) mints a key with consumer scopes only: catalog:read, proxy:call, keys:write, usage:read. No billing:write or provider:write.
Email verification elevates the same key in place to add billing:write and provider:write. You do not need a second key for provider or billing tasks after verify.
Human signup and OTP login
| Flow | Endpoint | Turnstile (prod) | Credits |
|---|---|---|---|
| Web signup | POST /v1/signup or POST /v1/auth/signup |
Required | $1.00 (100 cents) after email verify |
| Passwordless login | POST /v1/auth/login/request → POST /v1/auth/login/verify |
N/A on verify | Starter credits granted idempotently on first verify |
| Email verify link | POST /v1/auth/verify-email |
N/A | Unlocks withheld signup credits |
| Agent auto-register | POST /v1/register |
Not required | 0 credits |
OTP login sends a 6-digit code (10-minute TTL, rate-limited). The login-request endpoint returns a generic response to prevent email enumeration.
npx @ozma_app/cli login --email [email protected] --code 123456
npx @ozma_app/cli verify --token <verification_token>
Revoke the current session with POST /v1/auth/logout or ozma logout.
Turnstile on signup
Production signup routes (/v1/signup, /v1/auth/signup) require a Cloudflare Turnstile token. The CLI ozma signup cannot supply a widget token and will be rejected in production — use https://ozma.app/signup or ozma login --email instead.
POST /v1/register is Turnstile-free so agents can bootstrap a key programmatically, with zero credits until a human verifies email.
POST /v1/register (agents)
curl -X POST https://api.ozma.app/v1/register
Response includes api_key (shown once), org_id, and credit_cents: 0. Free catalog APIs (price_cents = 0) work immediately. Paid APIs need email verification, prepaid credits, or a card on file.
Response header X-Ozma-Key may echo the new key for convenience.
Safe storage
- Treat
ozma_live_…like a password. Ozma stores only a SHA-256 hash; plaintext is shown once at creation. - Never commit keys to git, paste them in public issues, or embed in client-side browser code.
- Prefer environment variables (
OZMA_API_KEY) or secret managers in CI. - Use per-agent keys with budget caps instead of sharing one org-wide key.
- Revoke compromised keys immediately: dashboard,
ozma keys revoke, orDELETE /v1/keys/:id.
What requires a human
Agents can discover, call free APIs, and manage keys autonomously. These steps need a human in a browser:
- Adding a payment method (Stripe SetupIntent / Billing Portal)
- Stripe Connect KYC for paid provider payouts
- Accepting required provider terms (
428until org owner/admin accepts via session)
See Quickstart (agent) and Billing.