Authentication
Bearer-token auth with per-organization API keys.
Every request (except the health probe) requires a Bearer token:
Authorization: Bearer ax_live_xxxxxxxxxxxxxxxxxxxxKeys are per-organization, not per-user. Generating a key gives full access to that org's books and files. Revoking it kills all integrations using it.
Generating a key
In the app: Settings → API keys → + New key.
- Enter a name (e.g. "Production webhook").
- Pick an environment:
liveortest. They use the same backend today;testis reserved for future sandbox isolation. - Click Generate key.
The plaintext key is shown exactly once. Copy it immediately and put it in your secret manager (1Password, AWS Secrets Manager, doppler, whatever). We only store a salted SHA-256 hash — if you lose the plaintext, you have to generate a new one and update your integration.
Key prefixes
| Prefix | Purpose |
|---|---|
ax_live_… | Production keys. Real data, real consequences. |
ax_test_… | Reserved for sandbox isolation (not yet enforced). |
Revoking
Same page → row hover → Revoke. Confirms with an alert dialog. Once revoked, any further request with that key gets a 401 immediately.
Revoking is immediate and irreversible. There's no "undo." Generate a new key if you need to restore access.
What the key sees
Today: full access to everything in the org — read and write on books,
read and write on files, read on audit log, manage other API keys (not
yet exposed via API). Scopes exist in the schema (books:read,
books:write, etc.) but aren't enforced yet. Roadmap.
Rotation
Best practice: rotate keys every few months and on any team change. Workflow:
- Generate new key.
- Update integration to use it.
- Wait until traffic settles on the new key.
- Revoke the old one.
→ Errors