Authentication
Every /api/v1/ request is authenticated with an API key and secret, sent as
two headers:
api-key: your_key_here
api-secret: your_secret_here
Not an Authorization: Bearer header — two separate headers, both required.
Example request
curl https://ledger.finopsbricks.com/api/v1/accounts \
-H "api-key: $LEDGER_API_KEY" \
-H "api-secret: $LEDGER_API_SECRET"
Creating a key
Keys are created per organization under Settings → API Keys. A key belongs to exactly one organization, and every request it makes is scoped to that organization's data. There is no way to reach another organization's ledger with it, and account ids from one are meaningless in another.
Permissions
A key carries a scope per model and per action:
| Model | read | create | edit | delete |
|---|---|---|---|---|
accounts | ✓ | ✓ | ✓ | ✓ |
transactions | ✓ | ✓ | ✓ | ✓ |
entries | ✓ | — | — | — |
reports | ✓ | — | — | — |
tags | ✓ | ✓ | ✓ | ✓ |
entries and reports are read-only at every scope, not by policy but by
construction. Entries are created only as part of a transaction, because an
entry writable on its own could leave a transaction unbalanced — see
the transactions endpoint.
Two presets are available when creating a key:
- Full Access — everything in the table above. For importers and agents that write.
- Read Only —
readon every model. For reporting, review, and anything that should be incapable of changing the books.
Failure modes
| Status | Meaning |
|---|---|
| 401 | Missing, unknown, or expired credentials |
| 403 | Valid key, but its scope does not cover this model and action |
A 403 names the permission that was missing:
{
"error": {
"code": "FORBIDDEN",
"message": "API key lacks transactions:create permission"
}
}