Skip to content

Search docs

Find pages, headings, and concepts. Press ⌘K or Ctrl+K to toggle.

Authentication

Mint, use, and revoke API keys for programmatic access to Alumia.

Alumia API keys are organization-scoped Bearer tokens issued to a specific user. They authenticate every request to /api/v1/* and inherit the org and workspace permissions of the user who minted them.

Key format

Keys follow the pattern:

alm_<env>_<48-hex-chars>
  • env is live when minted in production, test otherwise.
  • The trailing 48 hex characters come from 24 random bytes generated server-side.
  • The first 12 characters (alm_<env>_) are stored as a prefix and surfaced on list endpoints so you can recognize a key without seeing its secret.
  • The full key is hashed with SHA-256 before storage. The plaintext is returned once, in the create response.

Endpoints

MethodPathDescription
GET/api/v1/api-keysList the caller's non-revoked keys.
POST/api/v1/api-keysMint a new key. Requires step-up authentication.
DELETE/api/v1/api-keys/:idRevoke a key by ID.

GET /api/v1/api-keys

Returns metadata for keys belonging to the authenticated user in the current org. Plaintext keys and hashes are never returned.

Response:

{
  "success": true,
  "data": {
    "items": [
      {
        "id": "uuid",
        "name": "CI deploy bot",
        "prefix": "alm_live_a1",
        "scopes": ["models:read"],
        "lastUsedAt": "2026-04-30T12:01:00.000Z",
        "createdAt": "2026-03-01T00:00:00.000Z"
      }
    ]
  }
}

POST /api/v1/api-keys

Creates a new key. The plaintext key field appears only in this response.

Request body:

FieldTypeRequiredDescription
namestringyesHuman-readable label.
scopesstring[]noOrg API scopes. Defaults to ["models:read"].

Response (201):

{
  "success": true,
  "data": {
    "id": "uuid",
    "name": "CI deploy bot",
    "prefix": "alm_live_a1",
    "key": "alm_live_a1b2c3...full_secret",
    "createdAt": "2026-05-02T10:00:00.000Z"
  }
}

This route requires step-up authentication: the caller must have re-authenticated recently (TOTP, passkey, or password) within the session step-up window. API-key callers cannot mint other API keys; minting is only available from a logged-in dashboard session.

A token-bucket rate limit applies per userId + IP. Exceeding the limit returns BAD_REQUEST with the message Too many requests.

DELETE /api/v1/api-keys/:id

Revokes the key by setting revokedAt. Subsequent requests that present the revoked key are rejected with UNAUTHORIZED because the lookup filters on revokedAt IS NULL.

Response:

{ "success": true, "data": { "revoked": true } }

A revoked or unknown ID returns 404 NOT_FOUND.

Scopes

Keys are minted with org API scopes. Defaults and available scopes:

ScopeGrants
models:readList models (GET /api/v1/models). Default for new keys.
terminalAuthenticate the Alumia CLI via device login.
billing:machine:chargeCreate machine payments (org owner/admin only).

Selected REST prefixes enforce scopes (/api/v1/models, /api/v1/files, /api/v1/connections, /api/v1/api-keys, /api/v1/billing/machine-payments). Other /api/v1 routes inherit the owning user's org permissions when called with a valid key.

Hosted MCP (https://app.alumia.com/mcp) applies a separate MCP-layer read / write check on each tool — distinct from org API scopes above. See Connect via MCP.

Rotation and revocation

Keys do not expire automatically. To rotate:

  1. Mint a new key.
  2. Deploy the new key to your client.
  3. Revoke the old key once the rollout completes.

Revocation is immediate. The next request authenticated with the revoked key will fail with 401 UNAUTHORIZED.

Using a key

bash
Sign in to fill in your org and key
curl https://alumia.com/api/v1/agents \
-H "Authorization: Bearer alm_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

The key alone identifies both the org and the user. Do not send a separate org header. Keep keys server-side — never embed them in browser bundles, mobile apps, or public repositories.

Browser-only mutations

Some routes reject API-key auth even when the key belongs to an org owner. Examples include workspace create/delete, project share links, skill and guardrail edits, org settings updates, memory deletes, and adding session participants. Automate these from the dashboard (with step-up) or extend your integration to use a browser session — not an API key.

Dashboard auth (passkeys and 2FA)

API keys authenticate programmatic /api/v1 calls. Dashboard login uses email/password, magic link, OAuth, TOTP, recovery codes, and WebAuthn passkeys. Sensitive mutations require step-up within about ten minutes — see Passkeys and 2FA.

Auth surfaceUse for
API key (Authorization: Bearer alm_…)Automation, MCP, most CRUD reads/writes
Browser session + step-upAPI key mint/revoke, project sharing, skills, guardrails, workspace mutations

PATCH /api/v1/api-keys/:id

Rename a key or update its scopes array. Requires step-up when scopes change.

CLI device login

The @hasna/alumia CLI uses a browser approval flow instead of pasting API keys on first run. Endpoints (rate-limited per IP):

MethodPathDescription
POST/api/v1/auth/deviceStart device login; returns a browser approval URL.
GET/api/v1/auth/devicePoll device login code status.
POST/api/v1/auth/device/approveApprove from a signed-in browser session (requires step-up).
POST/api/v1/auth/device/tokenExchange an approved code for a one-time terminal API key.

Approval uses the same fresh passkey or TOTP step-up requirement as API key minting. See Terminal CLI.

Errors

CodeWhen
UNAUTHORIZEDHeader missing, malformed, or key revoked.
BAD_REQUESTMissing name on create, or rate limit exceeded.
FORBIDDENStep-up authentication has not been performed in this session.
NOT_FOUNDKey ID does not belong to the caller's org.