1. Double-entry accounting fundamentals
Midaz is built on strict double-entry bookkeeping. The rules are simple but non-negotiable:
- Every transaction must have at least one debit and one credit.
- Total debits must equal total credits.
- Every movement impacts the ledger in a balanced way.
Think in terms of where value comes from (the debit side / source) and where it goes (the credit side / destination). Every Midaz operation lands on one side of that equation.
2. Chart of Accounts in Midaz
In traditional accounting, the Chart of Accounts (CoA) defines account categories (Assets, Liabilities, Equity, Income, Expenses), their hierarchy, and how movements are classified.
Midaz does not have a dedicated Chart of Accounts API. The CoA is not a resource you create or retrieve — it is the result of how you combine assets, accounts, segments, portfolios, and account types. The
code field on Accounting Entries (e.g. 1.1.1.001) is where traditional account numbering appears in practice, annotating each posting with its classification.- Assets define what is moved — currencies (BRL, USD), points/miles, crypto tokens, or internal units of value — along with decimal precision and regulatory metadata.
- Accounts are balance containers. Each belongs to a portfolio, a segment, an account type, and an asset code, and is identified by an alias (e.g.
@external/BRL) to make routing intuitive. - Segments categorize and isolate accounts (customer vs. internal funds, business units, multi-tenant separation).
- Portfolios group accounts that share a purpose or belong to the same entity.
code values on your Accounting Entries to reflect your account numbering scheme.
A recommended process
Map your financial model
List the balances you need: customer balances, internal accounts, reserve/settlement accounts, fee and revenue accounts. This is your CoA blueprint.
Define account types
Create an Account Type per conceptual category — e.g.
CASH, SETTLEMENT, FEE_REVENUE, FEE_EXPENSE, TREASURY.Create segments and portfolios
Segments separate business domains (
CUSTOMER_FUNDS); portfolios manage ownership and grouping (customer_12345_wallet).3. Setting up Account Types
Account Types are templates for the accounts in your ledger. They define how accounts behave — allowed operations, internal vs. external classification, and reconciliation rules — and let you classify accounts according to your financial structure. A typical setup for a payments product:
- CASH → liquid customer funds
- SETTLEMENT → funds awaiting clearing
- FEE_REVENUE → fees collected
- FEE_EXPENSE → provider fees
- TREASURY → internal operations
type field, and how to manage Account Types via the API, see Account Types.
Understanding balance buckets
Before wiring up two-phase flows, it helps to know that each balance tracks funds in distinct buckets. A balance amount is exposed through three fields:available— funds free to be spent or sent right now. Debits and credits to a balance move this number.onHold— funds reserved by a pendingholdand not yet committed. They are removed fromavailablebut still belong to the account until the hold is committed or cancelled.scale— the number of decimal places used to interpret the integer amounts (e.g.scale: 2meansavailable: 100is1.00). It defines precision, not a separate pool of funds.
available and onHold on the source balance:
| Action | available | onHold |
|---|---|---|
| Direct | Debited (source) / credited (destination) | unchanged |
| Hold | ↓ decreased on source | ↑ increased on source |
| Commit | credited on destination | ↓ released from source |
| Cancel | ↑ returned to source | ↓ released back to available |
| Revert | restored on both sides via a counter-transaction | unchanged |
4. Defining Accounting Entries (Rubricas)
Accounting Entries (Rubricas) map a transaction action to the ledger accounts it debits and credits. Rather than computing accounting classifications by hand for each movement, you register rubrics once and let Midaz resolve them automatically — recording the resulting
routeCode and routeDescription on each operation.
Rubrics are configured per action on each Operation Route, inside the accountingEntries block. Source routes require the debit rubric, destination routes require the credit rubric, and bidirectional routes require both.
The five action types
| Action | Code | What it does |
|---|---|---|
| Direct | direct | Immediate, single-step debit/credit between two accounts, no intermediate stages (e.g. a fee or adjustment). |
| Hold | hold | Reserves funds by creating a pending movement (available → on_hold on the source). |
| Commit | commit | Confirms a previously held amount, releasing on_hold to the destination. |
| Cancel | cancel | Cancels a hold, returning on_hold value to available on the source. |
| Revert | revert | Reverses a completed direct transaction via a counter-transaction. |
5. Transaction routing
Routing is a two-layer system that resolves at runtime:
- Operation Routes define the accounting logic for each leg of a transaction — which accounts are debited/credited, balance keys, validation rules — and carry the Accounting Entries (rubricas) above.
- Transaction Routes define the business event that triggers accounting (
PIX_CASH_OUT,WALLET_TRANSFER,BANK_SLIP_SETTLEMENT, …) and combine Operation Routes into a balanced financial event.
6. End-to-end example — a Pix payment
Let’s tie it together with a simple Pix cash-out: a customer sends BRL out of their wallet to an external account.
Account setup
Create the accounts on your ledger:
customer_12345_brl— Account TypeCASH, assetBRL@external/BRL— the external settlement account for funds leaving the ledger
Rubrica registration
On the Operation Route for the customer leg (source), register the
direct debit rubric. On the external leg (destination), register the direct credit rubric:Transaction
Submit a transaction against the
PIX_CASH_OUT Transaction Route, moving, say, 100.00 BRL from customer_12345_brl to @external/BRL.hold, commit, and cancel rubrics on the route and submit the corresponding actions; each stage resolves its own rubric.
7. Validation modes
By default, if no rubric is registered for an action, the transaction proceeds normally and the
routeCode/routeDescription fields are simply left empty for that operation — no error is raised. This graceful mode is convenient while you are still onboarding routes.
In production, set accounting.validateRoutes to true in the Ledger Settings to enforce that every action has a registered rubric:
0117 ErrAccountingRouteNotFound. This prevents movements from silently landing without an accounting classification.
Next steps
- Review the Accounting overview and reference pages for full field-level detail.
- Once your ledger produces structured postings, see Lerian Reporter to transform ledger events into reconciliation files, financial statements, and COSIF-aligned regulatory outputs.

