credit, operational, or collateral).
If you do not provide a
balanceKey, the transaction uses the default balance.Double-entry accounting
The double-entry system follows one principle. Every transaction has two entries: a debit and a credit. This structure records all financial activity and keeps your accounts balanced. Each transaction affects two accounts and keeps them in balance:
- Debits show the value received or the resources consumed.
- Credits show the value given or the resources provided.
Example
In this example, you transfer R$1000 from one account to another. The transaction has two operations:- One operation to debit R$1,000.00 from the source account.
- One operation to credit R$1,000.00 to the destination account.
N:N Transactions (Many-to-Many)
Traditional financial systems limit transactions to one-to-one or one-to-many relationships. Midaz supports N:N transactions. A single transaction can use multiple source and destination accounts.
Examples
- Marketplace payout: a single escrow account pays multiple sellers, and each seller pays a platform fee.
- Peer-to-peer with fees: one transaction debits the payer and credits both the payee and a fee account.
Atomicity and integrity
Transactions are atomic. Either all operations succeed, or none do. Partial financial events do not occur. If any part of a transaction fails validation — for example, one account has insufficient funds — Midaz does not apply the transaction. The ledger stays consistent.
Transaction source
A transaction in Midaz can start from a single source or from multiple sources.
The sum of the values in
source must equal the value after send. It must also equal the sum of the values in distribute.Single source
In a single-source transaction, Midaz takes the amount from one source account. You can also name a specific balance.Example
In this example (Figure 1):- Midaz takes BRL 30.00 from
@account1(balancecredit). - It sends 100% to
@destinationAccount1(balanceoperational)
Figure 1. Example of a single source transaction.
Multi-source
In a multi-source transaction, Midaz draws funds from multiple accounts or balances.Example
In this example (Figure 2):- Midaz sends BRL 30.00 to the destination account (
@destinationAccount1).- BRL 15.00 from
@account1(balancedefault). - BRL 15.00 from
@account2(balanceinvestment).
- BRL 15.00 from
- The destination account receives 100% of the amount.
Figure 2. Example of a multi-source transaction.
Transaction destination
Like sources, destinations can be single or multiple.
Single destination
In a single-destination transaction, Midaz sends the amount to only one destination account.Example
In this example (Figure 3):- Midaz takes BRL 30.00 from an external account (
@external/BRL). - It sends 100% to the destination account (
@destinationAccount1).
Figure 3. Example of a single destination transaction.
Multi-destination
In a multi-destination transaction, Midaz divides the amount among multiple destination accounts. You can distribute values by shares, fixed amounts, or the remaining balance.Example
In this example (Figure 4):- Midaz takes BRL 100 from the source account (
@account1). - 38% of the amount goes to account 2 (
@account2). - 50% goes to account 3 (
@account3). - A fixed BRL 2.00 goes to account 4 (
@account4). - The remaining amount goes to account 5 (
@account5).
Figure 4 Example of a multi-destination transaction.
Multi-source and multi-destination
These transactions use multiple sources and multiple destinations. They are useful for cases like a crowdfunding campaign. Midaz pools the contributions and distributes them among multiple recipients.
Example
In this example (Figure 5):- The donation is BRL 4,000.00. Midaz takes it from four different accounts.
- 25% comes from account 1 (
@account1). - 25% comes from account 2 (
@account2). - 40% comes from account 3 (
@account3) - 10% comes from account 4 (
@account4).
- 25% comes from account 1 (
- Midaz distributes the donations to four separate accounts. Each account receives a 25% share of the total.
Figure 5. Example of a multi-source and multi-destination transaction.
Transaction statuses
Every transaction in Midaz has a status. The status reflects its current stage in the lifecycle. You need these statuses to design transaction flows, configure event consumers, and read ledger data.
Status transitions
Transactions follow predictable paths through these statuses:- Standard flow: →
APPROVED(single step) - Two-phase flow: →
PENDING→APPROVED(commit) orCANCELED(cancel) - Reversal flow: →
CREATED→APPROVED(automatic) - Annotation flow: →
NOTED(terminal, no transitions)
Once a transaction reaches
NOTED or CANCELED, it cannot transition further. Both are terminal statuses.Transaction flow
When a transaction starts, Midaz validates:
- The accounts involved.
- The specified balances (
balanceKey, ordefaultif not given). - Permissions (
allowSending,allowReceiving). - Sufficient available funds in the selected balance.
APPROVED.
Initiate this type of transaction only if you intend to commit it to the ledger immediately.
pending flag to create a Two-Phase Transaction.
Two-Phase Transaction
In this flow, Midaz creates the transaction with status
PENDING. Midaz does not move funds right away. Instead, it reserves the amount in the correct balance (balanceKey, or default if you do not provide one).
- Midaz moves the reserved funds from
availabletoon_hold. - Midaz records no operations (debits or credits) in the ledger yet.
- You must explicitly
committo execute the transfer, orcancelto release the funds.
Figure 6. Anti-fraud workflow example
Two-Phase Transaction flow
1. Create a Two-Phase Transaction
- Use the Create a Transaction using JSON endpoint with
"pending": true.
balanceKey), permissions (allowSending, allowReceiving), and available funds. If valid:
- Midaz reserves funds in the correct balance.
- Midaz sets the transaction status to
PENDING. - Midaz stores the metadata but posts no debit or credit yet.
2. Commit or cancel the pending transaction
- Commit: finalizes the transaction. Funds move from
on_holdto the destination balance, and Midaz records the debit and credit operations.- Use the Commit a Pending Transaction endpoint.
- Status:
APPROVED.
- Cancel: releases the reserved funds back to
availablein the same balance.- Use the Cancel a Pending Transaction endpoint.
- Status:
CANCELED.
Past Transactions
Midaz also supports past transactions. Institutions can import legacy financial events and keep historical accuracy.
- Use the optional
transactionDatefield to set the original date of the transaction. - Transactions with financial impact recalculate the historical balance state as if Midaz processed them on that date.
- Transactions created through the Create a Transaction Annotation endpoint validate structure but do not affect balances. They suit audits, compliance, and imports where balances must stay unchanged.
Example
Submit all past transactions before you start live operations. Midaz then recalculates balances consistently across the ledger.
Transactions with no financial impact
Midaz can create transactions that it records in the ledger but that do not affect account balances. These transactions keep structural integrity and leave balances unchanged. This feature is useful when you need to:
- Import legacy transactions but keep balances unchanged.
- Record audit or compliance events.
- Add business operations that the ledger must track but that do not move funds.
How does it work?
When you create a transaction without financial impact:- Midaz stores the
balanceandbalanceAfterfields as 0 to preserve double-entry validation. - Each operation has a
balanceAffected(boolean) field:- true → the operation affects the account balance.
- false → Midaz records the operation in the ledger but does not change balances.
Even when Midaz updates no balances, it enforces double-entry rules. This keeps consistency across all transactions in the ledger.
Example
Related endpoint
- Create a Transaction Annotation — Record a transaction without financial impact in the ledger.
Real-time event publishing
Midaz supports real-time event publishing through RabbitMQ. You can track the status of your transactions as they happen. After you enable it, every transaction generates an event:
APPROVED, PENDING, CANCELED, CREATED, or NOTED. External systems subscribe to these events through topic-based routing.
For more about how to publish and consume transaction events, see the Event publisher page.
Inflows, outflows, and external accounts
Midaz uses a double-entry ledger. All value that enters or leaves the system must pass through one special account: the External Account. Midaz represents this account as
@external/{{assetCode}}. It acts as the bridge between Midaz and the external financial world (banks, PSPs, payment rails, and so on).
Why does this matter?
When you first initialize the ledger, all accounts — including@external — start with a zero balance. To reflect real-world balances, such as institutional funds held outside Midaz, you must initiate a transaction that injects funds into Midaz accounts and debits the external account.
This is the only way to bring funds into Midaz.
Inflows – Adding value into the Ledger
To credit an internal account from outside the ledger:- Source:
@external/{{assetCode}}(e.g.,@external/BRL). - Destination: One or more internal accounts (e.g.,
@organization.main).
This debits the external account and credits your internal account. The external account now shows a negative balance. This is expected: it represents the total amount your organization brought into the ledger.
Outflows – Moving value out of the Ledger
To move value from the ledger to an external destination:- Source: One or more Midaz accounts.
- Destination:
@external/{{assetCode}}.
This debits
@accountA and credits the external account. Your system then transfers the funds to the recipient through SPI or another integration.
Behavior and balance rules
@external/{{assetCode}}can have a zero or negative balance, but never positive.- Its balance is always the inverse of the combined balance of all Midaz accounts that hold that asset.
- Every inflow increases internal liquidity and reduces the external account balance (i.e., simulates a deposit).
- Every outflow does the reverse.
All value that moves between the outside world and the Midaz ledger must go through the external account.Nothing enters or leaves the system without a formal transaction. This gives you full traceability, balance integrity, and compliance with double-entry principles.
Setting a custom transaction date
The
transactionDate field lets you set a custom date for a transaction, independent of when you submit it to the API.
- Optional. If you omit it, Midaz uses the current timestamp.
- Accepted formats:
- ISO 8601 with timezone:
2026-01-15T10:30:00Z - ISO 8601 without timezone:
2026-01-15T10:30:00 - Date only:
2026-01-15
- ISO 8601 with timezone:
- Constraint: you cannot use a future date. A future date returns error
0121. - Constraint: you cannot use it on
PENDINGtransactions. AtransactionDatewith"pending": truereturns error0122.
Use cases
- Record transactions that occurred in the past (for example, same-day corrections)
- Import historical financial data into a new ledger
- Reconcile with external systems that use a different posting date
Transaction Routes
The Transaction Routes API enables structured, validated transaction processing in Midaz.
The Lerian Console and product documentation call this concept Accounting Routes. The API resource and endpoints keep the
transactionRoute / Transaction Routes name. Both refer to the same transaction-level route.Why does it matter?
With Transaction Routes, you:- Keep a consistent transaction structure across your application.
- Make your ledger more maintainable, predictable, and reliable.
- Validate financial events against predefined patterns.
- Configure transaction templates without code changes.
- Maintain data integrity through structured validation.
Initiating a transaction
There are two main ways to initiate a transaction:
Using DSL
A Domain-Specific Language (DSL) simplifies user interaction. It focuses on specific domain concepts, so non-developers can perform complex tasks without technical skills. A DSL reduces boilerplate code and embeds constraints in its syntax. It enforces business rules and lowers the risk of errors. But its predefined patterns can limit flexibility. They make custom parsers or new requirements harder to build. The Transactions DSL in Midaz is called Gold. It simplifies transaction processing with an accounting syntax. It stores transaction information in.gold files. Business teams can then define transactions and work together with technical teams.
To use the DSL, follow these steps:
1
Create the
.gold file according to the Transactions DSL structure.2
Submit the file through the Create a Transaction using DSL endpoint.
Using JSON endpoint
JSON endpoints provide a flexible, developer-friendly standard for data interchange. They give you precise control over request structures for custom workflows and specific use cases. They work with many programming languages, which makes integration and debugging easier. But this flexibility can add verbosity and user errors, because developers handle validation manually. For non-developers, JSON can be harder to read than a Domain-Specific Language (DSL) for everyday tasks.- To create a transaction with JSON, use the Create a Transaction using JSON endpoint.
If you need to reserve funds before you complete the transfer, set the
pending field to true (Two-Phase Transaction flow).Reverting a transaction
Midaz supports transaction reversal. You can undo an approved transaction. Midaz creates a mirror transaction that inverts the original debits and credits. This mechanism keeps full audit trails and cancels the financial impact on account balances.
Reversal creates a new transaction that compensates for the original. The original transaction remains in the ledger history for complete traceability.
How does it work?
When you revert a transaction, Midaz automatically:-
Inverts operations:
- CREDIT operations become source operations (
from). - DEBIT operations become destination operations (
to).
- CREDIT operations become source operations (
-
Creates a new transaction with:
- Same amount and asset code.
- Same description and metadata.
- Inverted operations (recipients become senders, senders become recipients).
- Initial status:
CREATED(notPENDING) → then progresses toAPPROVED. parentTransactionIDthat references the original transaction.
- Processes the reversal through the standard transaction flow: validation, balance updates, and history recording.
Example
Consider this scenario: Original transaction:- Account A (debit -100) → Account B (credit +100)
- Account B (debit -100) → Account A (credit +100)
- Account A returns to its previous balance (receives back the -100).
- Account B returns to its previous balance (loses the +100).
- Both transactions remain in the ledger history for audit purposes.
- The reversal transaction includes a
parentTransactionIDthat points to the original.
Reversal restrictions
Midaz enforces strict rules to keep ledger integrity. A reversal fails in these cases:1. Transaction already has a reversal
- Midaz allows only one reversal per transaction.
- This prevents multiple reversals of the same transaction.
2. Transaction is already a reversal
- You cannot revert a transaction that is itself a reversal.
- This prevents “reversals of reversals.”
3. Transaction status is not APPROVED
- You can revert only approved transactions.
- You cannot revert a transaction with status
PENDING,CREATED, orCANCELED.
4. Transaction cannot be reverted
- This happens when the transaction has no valid operations to invert.
- For example, a transaction without standard CREDIT or DEBIT operations.
Midaz reverses the CREDIT and DEBIT operations. It does not reverse ON_HOLD or RELEASE operations.
Use cases
Transaction reversal helps in several operational scenarios:1. Incorrect payment reversal
A customer paid BRL 500 to the wrong supplier.- Revert the transaction.
- Funds return to the customer’s account.
- The customer can start a new payment to the correct supplier.
2. Purchase cancellation
A store processed a BRL 1,000 sale, but the customer cancels the purchase.- Revert the sale transaction.
- Funds return to the customer’s account.
3. Operational error correction
An operator created a transaction with the wrong amount.- Revert the incorrect transaction.
- Create a new transaction with the correct amount.
4. Product return
A customer purchased and paid BRL 200, but returned the product.- Revert the payment transaction.
- The customer receives a refund.
5. Integration failure compensation
A transaction is approved but fails in an external system.- Revert to undo the accounting operation.
- Balances return to their previous state.
Blocking and unblocking funds
Some scenarios require you to flag funds as blocked — a compliance hold, a court order, a fraud investigation — and later release them. Midaz supports this with two dedicated endpoints. These endpoints create transactions whose operations are typed
BLOCK and UNBLOCK.
These transactions accept the same body as the Create a Transaction using JSON endpoint, with two key differences:
- Always posted immediately. Midaz ignores the
pendingfield in the request body and overrides it tofalse. Block and unblock transactions are never two-phase. They go straight toAPPROVED. - Operations are typed
BLOCKorUNBLOCK. This classification distinguishes them in the ledger and in operation queries. You can audit blocked-fund movements without a look at the metadata.
metadata field.
A Block transaction records a ledger movement with
BLOCK-typed operations. This differs from the balance-level controls in Balances: permission flags (allowSending / allowReceiving) and collateral balances. Those controls restrict movement but record no transaction. Use a collateral balance for a standing operational restriction. Use a Block transaction when you need an auditable ledger entry.- Use the Create a Block Transaction endpoint to block funds.
- Use the Create an Unblock Transaction endpoint to release previously blocked funds.
Managing transactions
You can manage your Transactions through the API or Lerian Console.
Via API
- Create a Transaction using DSL (deprecated) — Submit a transaction file using the Midaz DSL.
- Create a Transaction using JSON — Submit a transaction directly using a JSON payload.
- Commit a pending transaction — Finalize a reserved transaction.
- Cancel a pending transaction — Release reserved funds without executing.
- Revert a Transaction — Create a reversal transaction to undo an approved transaction.
- Create an Inflow Transaction — Register incoming funds from external sources into the Ledger.
- Create an Outflow Transaction — Move funds from internal accounts to the external world.
- Create a Block Transaction — Flag funds as blocked with
BLOCK-typed operations. - Create an Unblock Transaction — Release previously blocked funds with
UNBLOCK-typed operations. - List Transactions — View all Transactions in your workspace.
- Retrieve a Transaction — Get details of a specific Transaction.
- Update a Transaction — Edit the metadata of an existing Transaction.
- Create a Transaction Annotation — Record a transaction without financial impact in the ledger.

