Skip to content

Authentication

Every request carries an API key in the Authorization header:

Terminal window
curl "https://rest.haasapi.com/v1/markets" \
-H "Authorization: Bearer hk_live_3f2504e0-4f89-41d3-9a0c-0305e82c3301"

Create keys in Settings → API Keys. The full key is shown once, at creation - store it somewhere safe. Keys can be disabled (reversible) or deleted (permanent) from the same page.

The prefix tells you what a key can touch:

Prefix Environment
hk_live_ Production - real accounts, real money

The hk_live_ prefix is recognizable at a glance and registered for secret scanning, so a leaked key in a public repo gets flagged.

This API accepts API keys only. Browser session tokens, OAuth tokens, and legacy credential pairs belong to other surfaces and are refused with a 401 - regardless of whether they are valid there.

A key carries scopes that bound what it can do. You choose them when you create the key, and they cannot be changed afterward - mint a new key to change them.

Scope Grants
read Read-only access to every resource - accounts, markets, bots, scripts, labs, backtests, orders, positions
bots Create, start, stop, and delete bots
scripts Create, edit, and delete scripts
labs Run and cancel backtests and labs
trading Place and cancel orders directly

A call that needs a scope the key lacks returns 403 insufficient_scope; each endpoint’s reference page names the scope it requires. A key created with no scopes (the legacy “full access” form) is unrestricted - it is also the only kind accepted on the non-REST surfaces, so keep it for the local MCP server and older integrations, and prefer scoped keys for everything on /v1.

API keys are server-side credentials. The API deliberately serves no CORS headers, so browser JavaScript cannot call it directly - build a backend, or use MCP for interactive use. A key that ships in frontend code is a key someone else now owns.

Status code Meaning
401 unauthorized No credential, or not a bearer token
401 invalid_api_key Wrong kind of token, or an unknown / disabled / revoked key
503 temporarily_unavailable The key could not be verified right now. Retry with the same key - do not discard it

That last row is deliberate: a transient backend fault will never tell you your key is dead. Only a 401 means the key itself is the problem.