Authentication and scopes
How API keys work, the two scopes, and what each request is allowed to do.
View as MarkdownKey format
A key looks like hpk_ followed by 64 hex characters (32 bytes of randomness) - the same entropy
budget HeimPulse uses for its own session ids. Send it as a bearer token:
Authorization: Bearer hpk_...
Keys are hashed (SHA-256) at rest. HeimPulse cannot look up, recover, or re-display a key’s plaintext after the moment it’s created - if you lose it, revoke it and mint a new one.
Scopes
Every key has exactly one scope, chosen at creation:
read_write(the default) - can read and mutate anything the API surface allows.read_only- everyGETstill works; anyPOST/PATCH/DELETEis rejected with403.
There’s no finer-grained, per-resource permission model today (e.g. “services only, not incidents”) - if you need that separation, mint separate keys per integration and give each only the scope it needs.
What a key can see
A key is scoped to exactly the org it was minted in. There is no {org_id} in any /v1 URL - the
org is entirely implied by which key authenticated the request, so a key can never be pointed at
another org’s data by editing a URL.
What a key can’t do
API keys are deliberately narrow. They cannot:
- Manage billing or change the org’s plan.
- Invite, remove, or manage org members.
- Manage other API keys (minting/revoking keys is dashboard-only, owner-gated - the same reason a Stripe or GitHub token can’t mint other tokens through the API it itself authenticates).
- Read or configure notification channels (webhooks/Slack/email).
- Touch anything outside
/v1- the session-cookie-authenticated dashboard API is a separate surface entirely.
See API keys vs. webhooks if you’re trying to decide which mechanism fits what you’re building.