Getting started
Authentication & keys
Store, validate, rotate, and revoke CLSSAI API keys safely.
On this page
This page is for developers and operators who decide where API keys live and how a team rotates them.
Use the standard server-side header for OpenAI-compatible calls:
Authorization: Bearer $CLSSAI_API_KEYCreate and manage keys at Workspace keys (sign-in required). Never put a key in frontend source or application logs. Store it in a server-side secret manager or environment variable. Prefer authentication headers. Every route also accepts a ?key= query parameter, and it takes precedence over headers; if a client requires it, keep the URL server-side and sanitize it from logs.
Native clients may use their standard authentication form: x-api-key for Anthropic and x-goog-api-key for Gemini. Anthropic Messages also accepts Authorization: Bearer. Gemini does not: send the key as x-goog-api-key or as a ?key= query parameter. A Bearer token on a Gemini route is passed upstream and rejected with 401. A ?key= query parameter is accepted on every route, not only Gemini's; use it only when a client leaves you no header option.
Validate a key#
The public model list does not require a key, so it confirms connectivity rather than key validity.
curl https://api.clssai.com/v1/models \
-H "Content-Type: application/json"Validate the key with a minimal inference call:
curl https://api.clssai.com/v1/chat/completions \
-H "Authorization: Bearer $CLSSAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"openai/gpt-5.4-nano","messages":[{"role":"user","content":"Reply with OK."}],"max_tokens":8}'Inspect balance and key state#
GET /v1/balance validates the presented key and returns its current balance projection and state. Expired or disabled keys still return HTTP 200 from this endpoint; check both booleans before allowing work.
curl https://api.clssai.com/v1/balance \
-H "Authorization: Bearer $CLSSAI_API_KEY"{
"object": "balance",
"key": "sk-...abc123",
"identity": "account",
"remaining_usd": 2.25,
"limit_usd": 2.5,
"recharge_usd": 2,
"credit_usd": 1,
"allocated_usd": 0.5,
"consumption_usd": 0.25,
"grace_usd": 0.1,
"expires_at": null,
"expired": false,
"disabled": false,
"tier": "free",
"tier_until": null,
"settlement": "asynchronous",
"note": "consumption_usd settles asynchronously and can lag recent requests by minutes; shared child Keys report the parent balance."
}identity is account, allocated_child, or shared_child. A shared child reports its parent's balance without exposing the parent key. consumption_usd can lag by several minutes because settlement is asynchronous. The projection is remaining_usd = max(limit_usd - consumption_usd, 0). expires_at is null for a key with no expiry, otherwise a Unix timestamp in seconds. grace_usd is a small request-admission allowance, not spendable balance; do not include it in remaining_usd. tier is the account's membership (free, plus, pro, or business), and tier_until is the end of its current period as a Unix timestamp in seconds, or null on free.
Rotate or revoke#
Create the replacement key, update server secrets, verify one request, and then revoke or unbind the old key in Workspace keys. A console key can also be rotated in place: the new key keeps the name, expiry, and limits, and the old key stops immediately or after a 1- or 24-hour grace period. After that it returns 401 key_revoked. Keys can be account keys, independently funded child keys, or shared child keys whose usage is charged to a parent. An expired or disabled child can fail independently; an allocated child also stops when its parent is disabled or expired.
Authentication failures#
A missing or unknown key returns 401. Expired, disabled, parent-disabled, or depleted keys return 402. Other upstream authorization decisions can be returned as 403.
{"error":"Unauthorized: Missing API key"}A rotated key whose grace period has ended, or a revoked key, returns 401 with an object error and code key_revoked. A key over its daily or monthly spending limit returns 402 with a top-level code of key_daily_limit or key_monthly_limit. See Errors & rate limits for the bodies.
For 401, confirm that the environment variable is present, begins with sk-, and is sent in the header. For 402, inspect the key state and balance rather than retrying unchanged.
Common mistakes#
- Include
/v1in the OpenAI SDK base URL. - Do not send secrets from browser JavaScript. A browser call may succeed; the key is still exposed to every visitor.
- Do not paste a complete key into logs or support messages.
- Check
expiredanddisabledin a 200 balance response, and do not treatgrace_usdas balance. - Use the Anthropic SDK base URL without
/v1. - For Gemini, use
x-goog-api-keyor?key=instead of Bearer authentication. - Spell
:freeand:batchmodel variants as completeauthor/model:variantIDs. - Use
cf-ray, not a made-up application header, as the inference trace identifier.
Find answers to common questions or diagnose a failed request.
Frequently asked questions →Troubleshoot errors →