Balance Overdraft allows a balance to be debited beyond its available funds without letting the primary balance go negative. The deficit is tracked as OverdraftUsed, and Midaz automatically handles the operation split between the primary balance and an internal companion balance. When credits arrive, repayment is prioritized — the overdraft is repaid first, and any remainder flows to Available. This mechanism supports credit lines, BNPL, settlement accounts, earned wage access, and any scenario where controlled negative positions are required.Documentation Index
Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
Use this file to discover all available pages before exploring further.
Balance direction
Balances carry a
direction field that defines how debits and credits affect the balance:
| Direction | Behavior | Typical use |
|---|---|---|
credit (default) | Debit decreases, credit increases | Asset-like balances — checking accounts, wallets, reserves |
debit | Debit increases, credit decreases | Liability-like balances — loans, overdraft tracking, payables |
Direction is set at creation time and is immutable. The overdraft companion balance (described below) always uses
direction=debit.Balance settings
The
settings object on a balance controls overdraft behavior:
| Field | Type | Description |
|---|---|---|
allowOverdraft | boolean | Enables overdraft on this balance |
overdraftLimitEnabled | boolean | Gates whether a limit is enforced |
overdraftLimit | string (decimal) | Maximum overdraft amount. Required when overdraftLimitEnabled is true. Must be greater than 0. |
A
balanceScope field also exists inside settings but is system-managed — it distinguishes internal balances (like the overdraft companion) from transactional balances. You do not set this field directly.Configuration modes
No overdraft (default)
The standard behavior. Any debit that exceeds the available balance is rejected.Unlimited overdraft
The balance can go negative without a cap. Useful for settlement or pool accounts where negative positions are normal and reconciled externally.Limited overdraft
The balance can go negative up to a defined limit. The most common mode for consumer credit products.How overdraft works
Operation split
When a debit transaction exceeds the available funds, Midaz automatically splits the operation:- The debit consumes all remaining Available, flooring it at 0.
- The excess is accrued as OverdraftUsed on the primary balance.
- A companion operation is created on the internal
"overdraft"balance (described below), recording the liability as a double-entry debit.
| Step | Available | OverdraftUsed | Description |
|---|---|---|---|
| Before | 300 | 0 | Normal state |
| After | 0 | 200 | 300 consumed from Available, 200 accrued as overdraft |
If a limit is configured, Midaz validates that the resulting OverdraftUsed does not exceed
overdraftLimit before processing. If it would, the transaction is rejected with error 0167 - ErrOverdraftLimitExceeded.Automatic repayment (refund split)
When a credit arrives andOverdraftUsed > 0, Midaz prioritizes repayment:
- The credit is applied to OverdraftUsed first, reducing the debt.
- Any remaining amount after OverdraftUsed reaches 0 flows to Available.
- A companion operation on the
"overdraft"balance records the repayment.
| Step | Available | OverdraftUsed | Description |
|---|---|---|---|
| Before | 0 | 200 | Overdraft active |
| After | 150 | 0 | 200 repaid, 150 goes to Available |
Cancelling a pending overdraft transaction
When aPENDING transaction that drew overdraft is cancelled, Midaz keeps the companion balance in lockstep with the primary:
- The cancel reverses the original hold and any overdraft drawn during the pending window —
OverdraftUsedreturns to its pre-pending value. - A companion
CREDIToperation on the"overdraft"balance shrinks the liability by the exact amount that was drawn, repaying it. - Both the primary cancel and the companion credit are applied in the same atomic batch, so the primary balance and companion balance never drift out of sync — even if the cancel arrives in a high-throughput burst.
Position
Every balance response includes a computed
position block that provides a real-time view of the balance state:
| Field | Description |
|---|---|
available | Balance.Available minus OverdraftUsed. Can be negative when overdraft is active. |
onHold | Mirrors Balance.OnHold — funds reserved by pending operations. |
overdraftLimitAvailable | Remaining overdraft headroom. "0" when overdraft is disabled. Omitted when unlimited. Positive decimal when a limit is configured. |
Companion balance
The first time
allowOverdraft flips to true on a balance — at creation or via update — Midaz auto-provisions a companion balance under the same account to record the liability side of the double-entry. It is created once per account and reused across every overdraft draw and repayment.
| Property | Value | Why |
|---|---|---|
key | "overdraft" | Reserved system key |
direction | debit | The companion tracks a liability — debits grow it, credits shrink it |
scope | internal | Blocks direct user operations |
allowSending | true | Required for DEBIT operations on the companion (overdraft draws) |
allowReceiving | true | Required for CREDIT operations on the companion (overdraft repayments) |
- It cannot be created, modified, or deleted via the public API.
- The key
"overdraft"is reserved — attempting to create a balance with this key returns error0170 - ErrReservedBalanceKey. - It mirrors the liability as a proper double-entry record, ensuring the ledger stays balanced.
The
scope: "internal" value gates direct user operations regardless of the permission flags above — any attempt to operate on this balance directly is rejected with error 0168 - ErrDirectOperationOnInternalBalance. The companion only moves through system-driven overdraft enrichment.Overdraft state on operations
Every operation exposes the overdraft state directly on the
balance and balanceAfter blocks. The overdraftUsed field captures how much overdraft was consumed before and after the operation — providing a complete audit trail without needing a separate balance query.
For operations that do not touch overdraft, both values are "0".
System-managed companion operations on the "overdraft" balance are exposed with type: "OVERDRAFT" (uppercase). The direction field carries the lifecycle semantics: "debit" for a draw, "credit" for a repayment.
overdraftUsed before/after pair — they mirror the primary balance’s overdraft transition, making the lifecycle visible from either row. The internal snapshot JSONB column on the operations table stores the same values for indexing and historical reconstruction; it is not part of the public JSON wire and surfaces on balance.overdraftUsed and balanceAfter.overdraftUsed instead. Future system-generated context can be added to the snapshot without breaking the public contract.
Overdraft events
Midaz publishes lifecycle events to RabbitMQ when overdraft state changes. Publication is enabled by default — set the flag to
"false" to opt out.
Event types
| Event | Description |
|---|---|
overdraft.drawn | Overdraft was consumed — OverdraftUsed increased |
overdraft.repaid | Overdraft was partially repaid — OverdraftUsed decreased but remains > 0 |
overdraft.cleared | Overdraft was fully repaid — OverdraftUsed reached 0 |
Example event payload
Use cases
Checking account overdraft (cheque especial)
Classic consumer credit. The customer’s checking balance can go negative up to a pre-approved limit, with interest accrued on the outstanding amount.Buy Now, Pay Later (BNPL)
A BNPL provider issues a purchase credit against the customer’s balance, creating an immediate overdraft position that is repaid in installments.Earned Wage Access / Salary advance
Employees draw against future earnings. The overdraft position is cleared when payroll credits arrive.Marketplace receivables advance
Sellers receive an advance on future receivables. The overdraft is repaid automatically as sales settlements arrive.Settlement / Pool accounts (unlimited mode)
Settlement and pool accounts routinely go negative during intraday processing. Unlimited overdraft avoids artificial rejections while the position is reconciled by end-of-day.Revolving credit lines (B2B)
Businesses draw and repay from a revolving credit facility. The overdraft limit represents the total credit line.Insurance pre-financing
Insurers pre-finance claims before premium collection cycles close. The overdraft covers the gap between payout and collection.Loyalty programs (advanced points)
Customers redeem points before earning them. The overdraft tracks the point deficit, repaid as new points are accrued.Protection rules
Overdraft introduces several immutability and access constraints to maintain ledger integrity:
- Direction is immutable. Once set at creation, a balance’s
directioncannot be changed. - Internal balances are read-only. The
"overdraft"companion balance cannot be created, deleted, or updated via the public API. PATCH requests on internal balances are rejected with error0175. - Reserved keys. The key
"overdraft"is reserved for the system-managed companion balance. - Disabling overdraft preserves outstanding debt. Setting
allowOverdraft: falsewhileOverdraftUsed > 0is allowed — the flag blocks future overdraft draws, while incoming credits keep repaying the existing debt until it reaches zero. - Limit cannot drop below usage. If
OverdraftUsed = 200, settingoverdraftLimit: "100"is rejected (error0173) — repay below the new ceiling first, or set a higher limit. - Optimistic concurrency. Balance updates use version-based concurrency control. Stale writes are rejected with error
0174— retry with the latest version.
Next steps
- Learn about Balances — the foundation that overdraft builds on.
- Understand Operations to trace how overdraft splits appear in the ledger.
- Set up the Event Publisher to consume overdraft lifecycle events.
- Explore Transactions for the full picture of double-entry accounting in Midaz.

