Authorization: Bearer <token> mechanism but serve different callers:
Each type also has a
_test_ variant (see Test keys below). The token’s prefix is what routes a request to the right auth guard — mixing them up (e.g. sending an agent credential where an API key is expected) fails authentication rather than silently working.
API key format
hasp_api_live_ and are globally unique. The 32-character body uses the Crockford base32 alphabet (ambiguous lookalike characters 0, O, 1, l, I excluded). The full token is shown exactly once on creation. HASP stores only a SHA-256 hash — if you lose the token, revoke it and issue a new one.
A key can optionally be given an expiry (expires_at, an ISO 8601 timestamp in the future) when it is created. A key without expires_at never expires. After expires_at the key is rejected with INVALID_API_KEY.
Sending the token
Pass the key in theAuthorization header on every request:
POST /v1/messages and POST /v1/messages/count_tokens) also accept the key in the x-api-key header — the header the Anthropic SDKs and Anthropic-native coding agents send when configured with an API key. If both headers are present, Authorization wins. Every other endpoint accepts only Authorization: Bearer.
Test keys
Every key is minted in eitherlive or test mode, distinguished by prefix: hasp_api_live_* vs hasp_api_test_*. Test-mode keys are for development against the real API without touching production billing:
- Requests draw from a separate sandbox token allotment (per your API tier), not your org’s regular AI credit balance.
- Exceeding the allotment, or having no active API subscription / Free Evaluation, returns
402 sandbox_allotment_exhaustedrather than the regularCONSUMPTION_BLOCKEDcredit error. - Everything else — scopes, BAA requirement, PHI handling, rate limits — behaves identically to a live key. Test mode changes billing, not behavior.
isTestMode() is always false for those caller types; only personal access tokens draw from the sandbox allotment.
Agent credentials
An agent credential (hasp_agt_live_*) is a delegated, scope-constrained credential an AI agent uses to act on a human’s behalf — distinct from a personal API key a human or service holds directly. Agent credentials carry their own rate limits, concurrency caps, and delegation-chain-depth limits independent of the parent key (see the (Agent SDK) codes in the Error Reference). Full lifecycle — registering an agent, issuing a credential, granting scopes, revocation — is covered in Agents overview.
Device authorization
If you’re integrating via thehasp CLI on a machine with no browser (SSH, containers), authenticate with the RFC 8628 device authorization grant instead of the standard browser redirect flow. See Device Authorization.
Scopes
Every API key has one or more scopes, assigned at creation and immutable after (issue a new key to change them). A request to a route protected by a scope the key does not have returns403 MISSING_SCOPE. Scope grants are additive — a key with multiple scopes gets the union of what each grants.
Assign only the scopes a key needs. A key used for chat-only integrations should carry only
ai:chat.
Developer credentials (hasp_pat_live_*) use their own two-scope vocabulary: inference:write grants the same inference endpoints as ai:chat; inference:read grants no capability-gated endpoint on its own. A developer credential has no control-plane or file-upload access.
Creating keys
Via the dashboard: API → Keys → Create Key (/developers/keys/new).
Via the API (requires a key with a scope granting Capability::ApiKeyWrite — currently control:read):
BAA requirement
All requests additionally require an active Business Associate Agreement (BAA) on your organization. If your org has no active BAA, every request — regardless of key validity — returns:Error responses
Agent and developer credentials have their own authentication error codes (
AGENT_CREDENTIAL_NOT_FOUND, DEVELOPER_CREDENTIAL_REVOKED, etc.) — see the full Error Reference.
Data API
The Data API (https://{org}.usehasp.run/api/hasp/v1/projects/{project}/…) reads and writes an app’s records. It is a separate surface from the AI API, with its own credentials — an AI API key (hasp_api_*) does not authenticate it. A request is authenticated by one of:
When several are present, the session is checked first, then the bearer token.
Writes pass the same BAA gate as the AI API — see BAA requirement. Errors use the same envelope and codes as the AI API — see Error responses.