Skip to main content
The journal is the record of what was done. One row per action, appended in the order the actions executed, and never touched again. Everything else in Financials is downstream of it. The ledger rows are stamped with the journal row that produced them; the invoice you see on screen is a summary of its own journal rows. If the journal survives, nothing is lost.

What a Journal Row Carries

The Actions

Fourteen action types exist, and no other way to change financial state.
Notice what is not in the list: there is no action for amending an invoice’s line items, and none for changing its type. Those are not restricted operations — they are operations that do not exist. This is the mechanism behind the rule in Invoices: type and line items are fixed at creation.

An Invoice Is Its Journal, Folded

To know an invoice’s current state, the engine reads every journal row for that invoice in sequence order and folds them into a single picture — its line items, its status, what has been paid, whether it is approved. The fold is the authority. Every precondition check runs against it, never against the convenience copy in the read tier.
1

An action arrives

A payment is recorded against invoice INV-000412-001.
2

The invoice is locked and its journal folded

The engine replays the invoice’s existing rows to establish what it is right now — is it voided, is it already fully paid, does the cited line item exist.
3

Preconditions run against that fold

A payment on a voided invoice is refused here. The refusal is based on replayed history, so it cannot be fooled by a stale cache.
4

The row is appended, then the ledger and read tier follow

Only once the action is admitted does anything get written — the journal row, its balanced ledger batch, and the updated projection, all in one transaction.

Order and Concurrency

Two actions on the same invoice never interleave. Each action takes a lock on the invoice it touches — and on each reserve scope it posts into, in a fixed order — so a payment and a void racing for the same invoice resolve one after the other, each seeing the other’s completed effect. The sequence number on every row records that resolved order permanently.

Retries Do Not Double-Post

A caller may supply the id for the journal row it is about to create. If the same id arrives twice — a network retry, a resubmitted request — the second attempt resolves to the action already recorded rather than appending a duplicate.
This is why an integration recording payments through the API should generate and reuse its own action id per payment. A retry without one is a genuinely new action, and will post a second payment.