Authentication

Token types, scopes, and how access is enforced
View as Markdown

All API requests authenticate with a Bearer token in the Authorization header:

Authorization: Bearer <token>

Token types

TypePrefixScopeUse for
Personal access tokenlct_pat_Every workspace the user belongs toPersonal scripts, Claude Desktop, Cursor, ChatGPT, MCP clients
Workspace tokenlct_live_One workspace, bound to the accountE-shop / accounting integrations that act as the workspace itself

A personal access token spans multiple workspaces, so you always pass the workspace_id in the path. A workspace token is bound to one workspace — the workspace_id in the path must match, or the request returns 403.

Sandbox tokens use the lct_test_ prefix and are valid only against test-mode workspaces. Sandbox mode is on the roadmap.

Scopes

Tokens carry granular scopes in three tiers, per resource:

  • read:<resource> — list and get
  • write:<resource> — read + create + update
  • manage:<resource> — write + custom actions (issue, mark paid, send, delete)

Resources include invoices, quotes, proformas, credit_notes, expenses, contacts, bank_accounts. A wildcard like read:* or manage:* grants the tier across all resources.

Scopes are capped at creation by the issuing user’s own permissions — a token can never grant more than the user has. If the user later loses a role, the token’s effective power shrinks with it.

Errors

A missing or invalid token returns 401:

1{
2 "error": "unauthenticated",
3 "message": "Authentication required.",
4 "request_id": "8f9e4c2b-...",
5 "docs_url": "https://docs.lucanto.eu/api/v1/errors/unauthenticated"
6}

A valid token without the required scope returns 403 (forbidden). See Errors.