Getting started
Authentication
How requests are authenticated, which scopes each endpoint requires, and how keys are stored.
Every /v1 endpoint requires a project API key. Keys are created in the console and belong to a single project; all usage, billing and receipts are attributed to that project.
Sending your key
Send the key in the Authorization header using the Bearer scheme. The x-api-key header is accepted as an alternative for clients that cannot set Authorization.
curl https://www.hushcompute.xyz/v1/models \
-H "Authorization: Bearer $HUSH_API_KEY"- If an
Authorizationheader is present, it is the only header considered. A malformed value is not retried againstx-api-key. - The scheme name is case-insensitive (
Bearerorbearer). - Keys are never accepted in query strings. URLs end up in logs, browser history and proxies.
Key format
Keys have the form proj_live_ followed by 32 base62 characters. The first 18 characters (proj_live_ plus 8 random characters) form a public prefix, shown in the console so you can tell keys apart without revealing them.
proj_live_XXXXXXXX························
└─ prefix (18 chars) ─┘└─ secret remainder ─┘Scopes
A key must hold at least one scope. Each endpoint checks for the scope it needs and returns insufficient_scope (HTTP 403) when it is missing.
| Scope | Grants | Status |
|---|---|---|
| inference | POST /v1/chat/completions and POST /v1/responses. | Live |
| sandboxes | POST /v1/sandbox/executions. | Live |
| receipts | GET /v1/receipts/{receipt_id} for receipts that belong to the key's project. | Live |
| agents | Reserved for the agents API. Hosted agents are currently created and run from the console; the scope has no effect on existing endpoints. | Coming soon |
GET /v1/models requires a valid key but no particular scope. Public proof pages and GET /api/proofs/{receipt_id} require no key at all.
Authentication failures
Authentication errors use the standard error shape. For an unknown, malformed, revoked or expired key the message is identical, so a response never reveals which of these applies.
| Condition | Status | Type |
|---|---|---|
| No key in Authorization or x-api-key | 401 | invalid_api_key |
| Malformed, unknown, revoked or expired key | 401 | invalid_api_key |
| The key's project is archived | 403 | forbidden |
| The key lacks the endpoint's scope | 403 | insufficient_scope |
| The model is outside the key's or project's allowlist | 403 | model_not_allowed |
{
"error": {
"type": "invalid_api_key",
"message": "The API key is invalid, expired or revoked.",
"request_id": "req_01K58ZT0M3J7Q9B2VE4N8C6R1D"
}
}How keys are stored
The full key is shown once, when it is created. The platform stores only the public prefix and an HMAC-SHA256 hash of the key, computed with a server-side secret. Consequences:
- A lost key cannot be recovered or displayed again. Create a new key and revoke the old one.
- A copy of the database alone is not enough to test candidate keys offline, because the HMAC secret is held separately.
- Requests look the key up by prefix and compare hashes in constant time, so lookup misses and mismatches take similar time.
Console sessions
The console playground authenticates with your signed-in session and acts with full project scope. Session cookies are not accepted by the public API; use an API key for programmatic access.
Browser requests and CORS
The API answers cross-origin requests only from origins the operator has explicitly allowed. For allowed origins it permits GET, POST and OPTIONS, the request headers authorization, content-type and x-api-key, exposes x-request-id and x-receipt-id, and caches preflight results for 600 seconds.
Security practices
- Use one key per service or environment so each can be revoked independently.
- Grant only the scopes a service needs, and restrict keys to the models it uses.
- Set a monthly limit and an expiration on keys used by automated or third-party systems.
- Load keys from a secret manager or environment variables. Never commit them. If a key is exposed, revoke it immediately; revocation takes effect on the next request.