x-api-key headerEvery request to a /v1/* or /deposits/* route (the machine-facing JSON
API) must carry an x-api-key header with your tenant's API key:
curl -s -X POST https://your-gateway-host/v1/ai/complete \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "hello"}'
The gateway looks that key up against its tenant table and resolves it to your tenant before your request handler ever runs. If the header is missing, or its value doesn't match any tenant, you get back the same response either way:
{"error": "Missing or invalid API key"}
HTTP/1.1 401 Unauthorized
Both cases return an identical status and message on purpose — a distinguishable "no such key" vs. "you sent nothing at all" response would let someone probe for which keys are almost-valid. If your tenant account has been suspended by an operator, a correctly-identified key instead gets:
{"error": "This tenant's access has been suspended"}
HTTP/1.1 403 Forbidden — a different status (403, not 401) because in
this case you are correctly authenticated; you're just not currently
allowed to use the gateway. Suspension blocks API usage and new actions
like this one; it does not affect your ability to log into and view your
dashboard.
Your tenant also has a dashboard login (email + password) at
/login, used only to view your account,
manage deposits, and reveal/regenerate your API key in a browser. It is a
completely different authentication system from the x-api-key header:
API key (x-api-key) | Dashboard login (/login) | |
|---|---|---|
| Used for | /v1/*, /deposits/* — machine-to-machine JSON calls | /account/* — a human using a browser |
| Credential | A single long-lived key string | Email + password, exchanged for a session cookie |
| Where it's checked | On every request, via the x-api-key header | Once at login; a signed session cookie carries it afterward |
Your API key never grants access to the dashboard, and your dashboard password is never accepted as an API credential — they authenticate two genuinely different kinds of caller (a script/service vs. a person in a browser), and neither can be substituted for the other.