API keys
A business's own credential: minted once, scoped to real permissions, revocable instantly.
Navigate to: Settings → API keys & webhooks (Super Administrator)
| Fact | Detail |
|---|---|
| Format | `tk_live_` followed by 64 hex characters. Sent as `Authorization: Bearer tk_live_…`. |
| Shown | Once, at creation. Trabalance stores only a SHA-256 fingerprint. |
| Scopes | The app's own feature codes with read / create / update / delete verbs — e.g. `sales_invoices:create`. Only scopes the minting user holds are offered. |
| Bound to | The user who minted it. On every call the key's scopes are checked, then that user's rights **today**. Demote the user and the key loses the same rights. |
| MCP | Tick "Allow AI assistants (MCP)" and the same key drives the MCP server, within its scopes. |
| Webhook subscriptions | Tick "Allow webhook subscriptions" and the key may create and remove its own webhook endpoints — what Zapier and Make use. |
| Expiry | Optional: never, 30, 90 or 365 days. |
| Revocation | Immediate. The key row is kept for the audit trail. |
If a call answers 403 insufficient_permissions with "no longer holds", the user behind the key lost that right. That is the intended behaviour, not a bug: fix the user's role, or mint a key from a user who holds it.
Revoking
Settings → API keys & webhooks → Revoke, then confirm. It takes effect immediately: anything holding that key gets 401 invalid_token on its very next request. There is no undo and no re-enable — the row stays only so the audit trail is complete. Mint a replacement first if the system on the other end matters.
Revoking is the right move whenever a key leaks, a contractor leaves, or a system is retired. Rotating on a schedule is what the Expires field is for.