Authentication
Every request carries a workspace API key in the Authorization header:
A key starts with hsk_. It belongs to the workspace, not to the person who created it, so it keeps working when people join or leave.
Create a key
In the dashboard, open Settings → API keys → Create API key. Only owners and admins see the tab, and creating a key asks for a recent sign-in.
- Name: what it's for, such as "Production CI".
- Role:
viewer,developer(the default) oradmin, never above your own role. - Expires: 30 days, 90 days (the default), 1 year, or never.
The secret is shown once and can't be retrieved afterwards: Hiraiship stores only a hash. Lost it? Revoke the key and create another. A workspace can have 25 active keys.
Keep it secret
A key acts on the whole workspace. Store it in your CI's secrets, never in a repository, and give it the lowest role that does the job.
Roles
Each route of the reference says the role it requires. A key's role is a fixed set of permissions:
| Permission | Viewer | Developer | Admin |
|---|---|---|---|
Read projects, deployments, domains, variables and usage (workspace.read) | ✓ | ✓ | ✓ |
Create projects (project.create) | ✓ | ✓ | |
Change build settings, create and rename environments (project.update) | ✓ | ✓ | |
Deploy, redeploy, cancel and roll back (deployment.create) | ✓ | ✓ | |
Manage environment variables (variables.write) | ✓ | ✓ | |
Manage domains (domains.write) | ✓ | ✓ |
admin adds project.delete and workspace.update, which no route of this reference needs yet: a developer key covers all of it.
A request beyond the key's role gets a 403 naming the missing permission:
What no key can do
Some actions are for people, whatever a key's role: members and invitations, API keys themselves (a key can't create or revoke keys, so a leaked one can't make itself permanent), the spend limit, transferring ownership, and connecting GitHub. Those routes answer a key with:
The workspace header
The dashboard and the CLI pick a workspace with an X-Hiraiship-Workspace header. A key doesn't need it: it always acts in its own workspace. If you send the header anyway, it must name the key's workspace (its slug), or the request fails with 403 api_key_workspace_mismatch.
Invalid keys
| Status | code | Meaning |
|---|---|---|
401 | api_key_invalid | No key with that value. |
401 | api_key_revoked | The key was revoked. Revoking takes effect on the next request. |
401 | api_key_expired | The key has passed its expiry date. |
429 | rate_limited | Too many requests for this key: see Limits. |