Skip to main content
Every project in astilba belongs to an organization, and every request is scoped to one org resolved from your credential — never from the request itself. Within an org, what you can do depends on your role, and programmatic access uses org API tokens.

Organizations and roles

Authentication and organizations are handled by Better Auth. You belong to one or more organizations; a freshly signed-in user’s active organization defaults to their first membership, so they can immediately work in it. Three roles matter for the parts astilba exposes today:
RoleCan
ownereverything, including minting and revoking API tokens
adminmanage projects and translations; mint and revoke API tokens
memberread and edit translations; list tokens, but not mint or revoke
Roles are enforced on the server. The dashboard hides controls you can’t use as a convenience, but the API is the real gate — a request without the role is rejected regardless of what UI made it.

API tokens

An org API token authenticates a non-interactive client — the CLI, CI, or any HTTP caller. It carries the org it was minted in, so it reaches every project in that org by slug (another org’s slug returns 404). It is sent as the x-api-key header; the CLI reads it from ASTILBA_TOKEN (or --token).

Minting

Mint a token from the dashboard’s Tokens page (owner/admin only). The plaintext key is shown exactly once — only its hash is stored, so it can never be displayed again. Copy it immediately. Programmatically, that’s POST /api/tokens, which requires a session cookie (you manage tokens from the dashboard, not with another token). The raw Better Auth key routes (/api/auth/api-key/*) are deliberately blocked so token management always goes through the role-checked /api/tokens endpoints.

Using a token

export ASTILBA_URL=https://astilba.example.com
export ASTILBA_TOKEN=
npx astilba pull --project web ./locales
Or as a raw header:
curl -H "x-api-key: $ASTILBA_TOKEN" \
  https://astilba.example.com/api/projects/web

Revoking

Revoke from the Tokens page, or DELETE /api/tokens/:id (owner/admin, session-cookie). Revocation is immediate. Mint a separate token per CI system or developer so you can revoke one without disrupting the others.

Access-control matrix

OperationEndpointWho
List tokensGET /api/tokensany member
Mint a tokenPOST /api/tokensowner / admin
Revoke a tokenDELETE /api/tokens/:idowner / admin
Read / edit translations/api/projects/*any member (session or token)
See the Server HTTP API for the full endpoint list and status codes.