Authentication
Bearer keys for SDK / programmatic access. Cookie-bound sessions for the docs Try-It-Now widget. No third-party OAuth shim — keys are minted in your settings page.
Mint a key
Sign in, head to /settings/api-keys, and click Mint key. The full secret is shown once on creation (the hash is stored; the raw value is not). Copy it somewhere safe; if you lose it, revoke and mint a new one.
Key format
sk-genie-{org-slug}-{24 random chars}The sk-genie- prefix is enforced by the gateway — keys without it are rejected pre-hash-compare so attacker timing only sees the prefix.
Send the key
curl https://api.genie.tech/v1/chat/completions \
-H "Authorization: Bearer sk-genie-{your-key}" \
-H "Content-Type: application/json" \
-d '{"model":"qwen3:0.6b","messages":[{"role":"user","content":"hi"}]}'Permissions
- Per-key allowedModels — restrict a key to specific model ids.
- Per-key allowedCIDRs — restrict callers by IP range.
- Rate limits —
rateLimitRpm/rateLimitRpdon the key. Independent from credit-spend caps (see Budgets). - Holder + Application scope — admins mint keys with
holderUserId(the team member it belongs to) +applicationId(the per-project tenant). Spend bills against both.
Mint via API
# Owner | admin only
curl -X POST https://api.genie.tech/api/orgs/{orgId}/api-keys \
-H "Cookie: sb-...-auth-token=..." \
-H "Content-Type: application/json" \
-d '{
"name": "fedoverwatch-prod",
"holderUserId": "{bobUserId}",
"applicationId": "{fedoverwatchAppId}",
"rateLimitRpm": 60
}'{
"fullKey": "sk-genie-acme-3f9a8e3...",
"keyId": "cmoz...",
"keyPrefix": "sk-genie-acme"
}extractBearerKey. No grace period, no caching.Try-It-Now widget auth
The widgets on these doc pages don't use a Bearer key. They POST directly to /api/v1/* with your same-origin Supabase session cookie — the canonical surface accepts session auth as a first-class shape (alongside Bearer for SDKs). Same budget gates and credit attribution apply.