Send the credential in the Authorization header: Authorization: Bearer hk_live_…. The same header works for REST, the SDK, the CLI and the MCP connector.
Owners and admins create keys in Dashboard → Settings → API access. A key is shown once and stored only as a hash; it does not expire, and revoking it takes effect immediately.
Kinds of key
| Key | Acts as | Can |
|---|---|---|
| Full, whole workspace | developer | Create, change and delete resources in every project, deploy, send mail, use AI, buy domains from the Balance. It can also delete projects. |
| Full, one project | developer | The same, but only on that project's endpoints. Workspace-wide endpoints refuse it. |
| Read-only, whole workspace | viewer | GET requests, plus reads sent as POST (vector query, memory search, storage download links). No environment variables, no SQL, no uploads. |
| Read-only, one project | viewer | Reads on that project only. |
No API key can manage billing, members or other keys, or move money out: withdrawals, refunds and payout setup need the workspace owner signed in to the dashboard.
Which key to give what
| Use | Key |
|---|---|
| Your laptop, CI, setup scripts | Full, whole workspace |
| A deployed app that uses its database, storage, payments, vectors, memory or auth pool | Full, one project |
| A deployed app that also sends mail or calls the AI Gateway | Full, whole workspace (those endpoints are workspace-wide and refuse project keys today) |
| Dashboards, monitoring, read-only AI assistants | Read-only |
Where a project key works
A project key passes every route that names its project: /api/projects/<id>/…, and item routes whose resource belongs to it — /api/databases/:id, /api/storage/:id, /api/functions/:id, /api/vectors/:id, /api/memory/:id, /api/agents/:id, /api/payments/:accountId, /api/auth-pools/:id, /api/deployments/:id.
It is refused, with 403 "This API key only works on project N", on workspace-wide routes: listing projects, /api/mail/send, /api/ai/*, /api/domains/*, /api/repos/*, /api/usage and billing.
Create a key with the API
curl -X POST https://harakumo.com/api/orgs/<workspaceId>/api-keys \
-H "Authorization: Bearer $HARAKUMO_API_KEY" -H "content-type: application/json" \
-d '{ "name": "notes-app production", "access": "full", "projectId": 12 }'
# 201 → { "key": { "id", "prefix", "access", "project_id" }, "secret": "hk_live_…" } (secret shown once)Creating keys needs the admin role, so an API key (developer or viewer) cannot mint more keys. Use the dashboard, or an admin's connector.
Other credentials
| Credential | Where it comes from | Acts as |
|---|---|---|
| Browser session | Signing in to the dashboard; an httpOnly cookie, 30 days | You, with your role in the chosen workspace |
| Connector token (hk_mcp_…) | Connecting Claude, ChatGPT or another MCP client (OAuth) | You, read-only or read-and-manage, in one workspace or all of them |
| Auth-pool client secret (as_…) | Enabling an auth pool | Only that pool's sign-in actions — never anything else |
| Auth-pool client id (ap_…) | Enabling an auth pool | Publishable: browser sign-in for that pool, when turned on |
Choosing a workspace
A key belongs to one workspace. A session or an all-workspaces connector acts in the workspace named by ?org=<id> or the x-harakumo-org header, else the one last chosen in the dashboard.
When a key is refused
| Status | Message | What to do |
|---|---|---|
| 401 | Unauthorized | The header is missing, or the key was revoked or mistyped. |
| 403 | This API key is read-only | Use a full key for writes. |
| 403 | This API key only works on project N | Use a key for that project, or a workspace key for workspace-wide routes. |
| 403 | Your role (developer) does not allow this action | The action needs an admin or owner (members, keys, billing). |
| 404 | Not found | The id does not exist or belongs to another workspace — the two look the same on purpose. |
Reference
import Harakumo from '@harakumo/sdk';
const hk = new Harakumo({ apiKey: process.env.HARAKUMO_API_KEY }); // baseUrl defaults to https://harakumo.com
// Errors throw HarakumoError with .status and .body (the JSON the API sent).harakumo login --key hk_live_… # or set HARAKUMO_API_KEY; --key and --url work on every command
harakumo whoamiAuthorization: Bearer hk_live_…
GET /api/orgs/:id/api-keys # list (admin+); secrets are never returned
POST /api/orgs/:id/api-keys { "name", "access": "full" | "read", "projectId"? }
DELETE /api/orgs/:id/api-keys/:keyId # revoke