Skip to main content
Documentation menu

Getting started

Authentication & access tokens

Every programmatic request to Excaliwow authenticates with a Personal Access Token. Mint one in your account settings, pick the capabilities it needs, and use it from the API, the CLI, or the MCP server.

Create a token

Tokens live in your account settings on the hosted product. To create one:

Capabilities

A token holds a set of capabilities — any subset of the four below, chosen when you mint it. Pick the narrowest set that does the job: a token that only ever reads diagrams should hold just read; an agent that creates and edits needs read + write and nothing more.

CapabilityDescription
readEvery read endpoint: list diagrams, get a diagram, render it to PNG/SVG, and list folders. (The identity check GET /api/v1/me answers for any valid token, regardless of capabilities.)
writeCreate a diagram or folder, rename, move, and merge an edit into a diagram. Needed by anything that generates or modifies content — including the MCP server.
publishToggle a diagram's public share link (including its password). Separable on purpose: a token that writes diagrams does not have to be able to expose them.
deleteDelete a diagram (to trash) or a folder.

Calling an endpoint without the capability it requires returns 403 insufficient_scope. Capabilities are fixed at mint time — to broaden a token's access, mint a new one and revoke the old.

Capabilities bound what a token may do; which diagrams it reaches follows your account's access. A token can read and edit (by id) diagrams you own, diagrams shared with you directly, and diagrams in a workspace you're a member of — your role there sets the ceiling, with editor access required for edits. delete and publish act only on diagrams you own, and anything outside your access answers 404 not_found.

Authenticate a request

Send the token in the standard bearer header on every request:

Header
Authorization: Bearer <token>

The quickest way to confirm a token works is to call the identity endpoint, which echoes back the calling user and the token's capabilities:

Verify a token
curl https://excaliwow.com/api/v1/me \
  -H "Authorization: Bearer <token>"

# 200 OK
# {
#   "id": "<userId>",
#   "email": "you@example.com",
#   "capabilities": ["read", "write", "publish", "delete"],
#   "scope": "read-write"
# }

The scope field is a legacy coarse summary kept for older clients: read-write when the token holds every capability, otherwise read. Use capabilities in new integrations.

See the REST API reference for the full set of endpoints.

Use it with the CLI and MCP

Both the CLI and the MCP server read your token from the EXCALIWOW_TOKEN environment variable:

Environment variable
export EXCALIWOW_TOKEN="<token>"

The CLI can also store a login so you do not have to set the variable each time. It validates the token before saving it:

CLI login
excaliwow auth login          # paste the token at the masked prompt

# non-interactively, or in CI:
excaliwow auth login --token "$EXCALIWOW_TOKEN"

When both are present, EXCALIWOW_TOKEN takes precedence over the stored login. See the CLI guide and the MCP server guide for setup details.

Verified email required

Your account email must be verified before a token can do anything beyond the identity check. A request from an unverified account returns 403 email_unverified. The one exception is GET /api/v1/me, which still answers so you can confirm a token is valid. Verify your email from your account, then retry.

Rate limits

Requests are rate limited per user across two independent buckets, one for reads and one for writes:

BucketApplies toDescription
Read requestsGET120 requests per minute (default).
Write requestsPOST / PUT / PATCH / DELETE30 requests per minute (default).
WindowBoth60 seconds. The two buckets are counted independently, per user.

Going over a cap returns 429 with a Retry-After header (in seconds) indicating when the window resets. Wait that long, then retry.

Errors

Every failure returns JSON with the same shape. The error field is a stable machine code; the optional message is a human-readable sentence and is omitted entirely when there is no extra detail.

Error envelope
{
  "error": "<machine_code>",
  "message"?: "<human sentence>"
}
CodeStatusDescription
unauthorized401The token is missing, malformed, unknown, expired, or revoked. All auth failures return this single code with no further detail.
insufficient_scope403The token is valid but does not hold the capability the endpoint requires — e.g. a read-only token calling a write endpoint, or a token without publish toggling a public link. Mint a token with the missing capability.
email_unverified403The token is valid, but your account email is not verified. Verify your email, then retry.
rate_limited429You exceeded the read or write cap. The response carries a Retry-After header (whole seconds) telling you when to retry.

One 401 for every auth failure

A missing, malformed, unknown, expired, or revoked token all collapse to the same 401 unauthorized. The response does not tell you which one it was, so check the token itself if a call you expected to work returns 401.

Keep tokens safe

Treat a token like a password

A token is a credential to your account — one holding every capability has full control of all your diagrams, so handle it the way you would any secret. Minting with fewer capabilities limits the blast radius of a leak.

  • Never commit a token to source control or paste it into a shared chat.
  • When you sign in with the CLI, the token is stored at ~/.config/excaliwow/config.json with owner-only (600) permissions.
  • Revoke a token any time from Settings, then Developer / API tokens. A revoked token stops working immediately.