Skip to main content

API tokens

An API token is how a script, a service, or an agent authenticates to the REST API without a browser login. It is long-lived, stored hashed, and revocable, which makes it different from the short-lived session token the web app uses.

Minting one

Create a token from the app, or over the API:

POST /api/v1/me/api-tokens

Give it a name (so you can tell your tokens apart later) and, optionally, an expiry and a set of scopes. The response includes the token's plaintext value exactly once:

{ "id": "…", "name": "backup script", "token_prefix": "cbt_AbCdEfGh",
"expires_at": null, "token": "cbt_AbCd…" }

The full value starts with cbt_. Cobblr keeps only a SHA-256 hash of it, so it can never show you the value again; if you lose it, revoke it and mint a new one. The token_prefix is stored for display, so the token list can show you which one is which without holding the secret.

List your tokens (hashes only, never the plaintext) with GET /api/v1/me/api-tokens. Each row carries last_used_at, expires_at, and revoked_at so you can see what is live and what has lapsed.

Expiry and revocation

Leave expires_at unset and the token never expires. Set it to an ISO timestamp and the token stops working after it. Either way you can revoke a token at any time, which invalidates it immediately: an authenticated request with a revoked or expired token is rejected the same as a bad one.

What a token can do

A token acts as the user who created it, so its baseline reach is that person's role in each workspace. There are two modes:

  • Unscoped (no scopes given). The token can do anything its owner can do, across the workspaces they belong to. Use this for a trusted script you run yourself; treat it like a password.
  • Scoped. Attach one or more scopes and the token becomes deny-by-default: it is clamped to the routes those scopes allow and nothing else, even though it still carries the owner's identity. A token scoped to one job can only do that job.

Scopes are a fixed, curated set, each mapping to a narrow list of routes, rather than a general read/write-per-area permission builder. Fetch the current choices with GET /api/v1/me/api-token-scopes. The two most relevant to a self-hoster:

  • devices:edge: lets an on-site edge bridge register, poll, respond, and self-update for one workspace. Safe to hand to a bridge running on a Pi or a mini-PC, because it can reach nothing else.
  • drive:control: lets an agent drive your own open browser tab (open pages, point, follow along) and reads or writes no workspace data. It is gated further by a per-workspace opt-in that is off by default. See Connecting Claude.

The remaining scopes exist for first-party operational tooling (feedback intake, release announcements, and the like) and are narrow by design.

Handling tokens safely

Never put a token literally on a command line or in a committed file. Read it from an environment variable or a file with tight permissions, and prefer a scoped token whenever the job is narrow enough to name.