Core concepts
Every balance you can query traces back through four resources. Money never sits loose: it always belongs to an account, inside a ledger, moved there by a transaction.
Ledgers group accounts
A ledger is a book of accounts such as Cash, Accounts Receivable, Accounts Payable, and Retained Earnings. Every account belongs to exactly one ledger.
Accounts hold one asset
An account is scoped to a single asset (AUD, BTC, loyalty points), type (asset, liability, equity, revenue, expense), and a normal balance (debit normal, credit normal).
Transactions are atomic
A transaction is a set of up to 10 entries that must net to zero per asset. It either posts completely or not at all. There's no "pending" state.
Balances are live
Reading a balance never touches history. It's a direct lookup, kept in step with every posted transaction in real time.
Conventions
A handful of rules apply across every endpoint. Knowing these up front makes the resource reference below mostly self-explanatory.
| Convention | What it means for you |
|---|---|
| Idempotency | You generate the id for every asset, ledger, account, and transaction (a UUIDv7). Retry a POST with the same id and you get the original resource back rather than a duplicate. |
| Reads vs. writes | Writes (POST/PATCH) take a flat JSON body. Reads (GET) return JSON:API: data, attributes, relationships, plus included where you asked for sideloaded data. |
| Pagination | List endpoints take cursor + limit and return meta.next_cursor when more pages exist. Cursors are opaque; don't parse them. |
| Sideloading | ?include=balance on accounts, or ?include=transaction on entries, adds the related resource to the response's included array instead of a second round trip. |
| Money | Amounts are integers in the asset's smallest unit (cents for AUD, satoshis for BTC), scaled for display by decimal_places. |
| Tenancy | Every request needs X-Tenant-ID. |
Errors
Every error follows JSON:API's error object: an array, so validation can report more than one problem at once.
POSTsource.pointer)