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 Authorization header is present, it is the only header considered. A malformed value is not retried against x-api-key.
  • The scheme name is case-insensitive (Bearer or bearer).
  • 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.

Format
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.

ScopeGrantsStatus
inferencePOST /v1/chat/completions and POST /v1/responses.Live
sandboxesPOST /v1/sandbox/executions.Live
receiptsGET /v1/receipts/{receipt_id} for receipts that belong to the key's project.Live
agentsReserved 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.

ConditionStatusType
No key in Authorization or x-api-key401invalid_api_key
Malformed, unknown, revoked or expired key401invalid_api_key
The key's project is archived403forbidden
The key lacks the endpoint's scope403insufficient_scope
The model is outside the key's or project's allowlist403model_not_allowed
401 Unauthorized
{
  "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.