> ## 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.

# Balances

> Track multiple Balances per Account to segment funds — investment reserves, credit limits, and operational funds without extra Accounts.

A **Balance** represents the value that a specific account holds in Midaz. It reflects the result of all operations — debits and credits — over time. Each balance belongs to one asset, such as BRL, USD, or BTC.

## Multiple balances

***

A single account can hold several balances. A unique key identifies each one. This lets institutions segment funds without creating multiple accounts for the same customer.

<Danger>
  External accounts cannot have multiple balances. **Each external account holds exactly one balance.**
</Danger>

Typical use cases include:

* Investment reserves
* Credit limits
* Collateral (blocked) funds
* Day-to-day operational funds

This approach (*Figure 1*) increases flexibility. It keeps the double-entry model — debit and credit — intact for accounting consistency, traceability, and transparency.

<Frame caption="Figure 1. Multiple balances diagram.">
  <img src="https://mintcdn.com/lerian-49cb71fc/SFzzdxyH5SN7w_fC/images/en/d2/account-multiple-balances.svg?fit=max&auto=format&n=SFzzdxyH5SN7w_fC&q=85&s=6e8e5e71d3176e9ca70225624afcbb20" alt="Account with multiple balances" width="975" height="604" data-path="images/en/d2/account-multiple-balances.svg" />
</Frame>

<Warning>
  If a transaction does not provide a `balanceKey`, Midaz uses the account's default balance.
</Warning>

### Balance key

A `key` field identifies each balance uniquely within the account.

* **Maximum length**: 100 characters, with no whitespace.
* **Default key**: `"default"`. Midaz creates the default balance automatically when the account is created.
* **Uniqueness**: Each key must be unique per account. A request to create a balance with a key that already exists on the account returns an error.
* **In transactions**: If a transaction does not specify a `balanceKey`, Midaz uses the balance with key `"default"`.

<Note>
  You set the `key` at creation time and cannot change it later. Choose descriptive keys like `"credit"`, `"collateral"`, or `"savings"` to make your balance model self-documenting.
</Note>

### Permission flags

Each balance has two independent permission flags that control whether it can participate in transactions:

| Flag             | Type    | Description                                         |
| ---------------- | ------- | --------------------------------------------------- |
| `allowSending`   | boolean | Whether funds can be sent **from** this balance     |
| `allowReceiving` | boolean | Whether funds can be received **into** this balance |

These flags are **per-balance** — they apply to one balance, not to the whole account. Both default to `true` when you do not set them.

**Common use cases:**

* **Freeze a balance**: Set both `allowSending` and `allowReceiving` to `false` to prevent any movement.
* **Receive-only balance**: Set `allowSending` to `false` to block outbound transfers and still accept inflows.
* **Send-only balance**: Set `allowReceiving` to `false` to prevent new funds from entering this balance.

You can set both flags when you create a balance. You can also update them independently through the [Update a Balance](/en/reference/midaz/update-a-balance) endpoint. If an update request omits a flag, its current value stays unchanged.

<Warning>
  Midaz reads permission flags during transaction validation. A PATCH that changes only `allowSending` or `allowReceiving` does not rewrite an existing Valkey entry, so do not assume the immediately next cache-hit transaction will observe the change. Changes never alter operations already processed.
</Warning>

## Usage examples

***

* **User Wallet (BRL)**: A digital wallet that shows an available balance of R\$500.
  * *Use case*: Show the balance in a mobile banking app and validate funds before a payment.
* **Settlement Account (USD)**: A liquidity provider account with a USD balance of \$120,000.
  * *Use case*: Make sure daily treasury operations keep enough buffer for FX settlements.
* **Blocked Balance (BRL)**: An account balance reserved as collateral.
  * *Use case*: Prevent the use of funds until a loan closes or the borrower meets the conditions.

<Note>
  A blocked (collateral) balance restricts funds at the **balance level**. Midaz holds the value in a separate balance and combines it with permission flags to keep the funds unavailable. This differs from a [Block transaction](/en/midaz/transactions#blocking-and-unblocking-funds), which records a ledger movement with `BLOCK`-typed operations. A Block transaction flags funds for reasons like a compliance hold. Use a collateral balance for a standing operational restriction. Use a Block transaction when you need an auditable ledger entry.
</Note>

## Balance structure

***

* **Balance > Account**: Each Balance belongs to an Account, which holds and moves value.
* **Balance > Asset**: Each Balance uses a specific Asset, such as BRL or BTC.
* **Balance > Ledger**: Balances exist within a Ledger, which enables multi-book environments.
* **Balance > Key**: Each Balance has a unique key within the account (e.g., `default`, `credit`, `collateral`).

*Figure 2* shows an example of the structure.

<Frame caption="Figure 2. Balance structure relationships diagram.">
  <img src="https://mintcdn.com/lerian-49cb71fc/SFzzdxyH5SN7w_fC/images/en/d2/balance-structure-relationships.svg?fit=max&auto=format&n=SFzzdxyH5SN7w_fC&q=85&s=7b2fdced4a1a0db1ed925b210b01b16d" alt="Balance structure relationships" width="1114" height="1037" data-path="images/en/d2/balance-structure-relationships.svg" />
</Frame>

A balance is more than just a number. It includes metadata about the state of funds, such as pending operations and effective availability.

## Key characteristics

***

* **Real-time tracking**: Midaz updates balances with every confirmed operation.
* **Multiple balances per account**: Accounts can hold several balances, each with its own rules.
* **Single source of truth**: Balances reflect the net sum of all operations on the account.
* **Query by context**: You can list balances within an organization and ledger, retrieve them by account ID or alias, and retrieve an External Account’s balance by asset code. The balance-list endpoints do not filter by a generic asset code or `balanceKey`.
* **Supports external accounts**: You can retrieve balances for internal or external accounts, such as liquidity pools or partners.

## Using balances in transactions

***

The following transaction endpoints accept a `balanceKey` field to specify which balance to use:

* [Create a Transaction using JSON](/en/reference/midaz/create-a-transaction-using-json)
* [Create an Inflow Transaction](/en/reference/midaz/create-an-inflow-transaction)
* [Create an Outflow Transaction](/en/reference/midaz/create-an-outflow-transaction)
* [Create a Transaction Annotation](/en/reference/midaz/create-a-transaction-annotation)

If a request does not provide a `balanceKey`, Midaz uses the account's default balance.

### New fields in responses

* `balanceKey` - Appears in transactions and operations to show which balance the transaction used.
* `key` - Appears in balances to identify each balance uniquely.

<Danger>
  Always use the `balanceKey` consistently across requests and responses. This avoids mismatches when accounts hold multiple balances.
</Danger>

## Cache key changes (Valkey)

***

Balances in the cache (Valkey) include the `balanceKey`.

### Previous format

```json theme={null}
<org_id>:<ledger_id>:<account_alias>
```

### New format

```json theme={null}
balance:{transactions}:<org_id>:<ledger_id>:<account_alias>#<balance_key>
```

The key carries the `balance:{transactions}:` prefix, and the `balance_key` is appended to the account alias with a `#` separator. A tenant namespace can prefix the key further in multi-tenant deployments.

<Warning>
  Update direct Valkey readers to construct `balance:{transactions}:<org_id>:<ledger_id>:<account_alias>#<balance_key>`, including `#default` for the default balance. Reads using the previous key format miss the current cache entry.
</Warning>

## Overdraft

***

Balances support **overdraft** — the ability to debit a balance beyond its available funds. When you enable overdraft, Midaz tracks the deficit as `overdraftUsed`. Midaz also handles the operation split and repayment automatically.

Two fields support this feature:

* **`direction`** — For an automatically created default balance, direction is `credit` for non-external accounts and `debit` for External Accounts. Additional balances may set direction at creation; it cannot change afterward.
* **`settings`** — Controls overdraft behavior: `allowOverdraft`, `overdraftLimitEnabled`, and `overdraftLimit`.

<Note>
  Midaz **reserves** the key `"overdraft"` for the system-managed companion balance that records the liability side. A request to create a balance with this key returns an error.
</Note>

`settings.balanceScope` also distinguishes balances by scope. **Transactional** balances (the default) are user-managed and take part in regular transactions. The system operates **internal** balances exclusively — like the overdraft companion. User transactions cannot target, modify, or delete them through the public API.

For full details on configuration modes, operation splits, automatic repayment, events, and use cases, see [Balance Overdraft](/en/midaz/balance-overdraft).

## Balance history

***

Midaz provides **point-in-time queries** for balances. You can retrieve a balance state at a past timestamp on or after the balance’s creation. If no operation exists before that timestamp, Midaz returns the initial zero state; it returns `404` when the requested timestamp precedes balance creation. This supports auditing, reconciliation, and historical reporting.

### How it works

When you query balance history, Midaz returns historical identity and amount fields. It omits `allowSending`, `allowReceiving`, `deletedAt`, and `metadata`; the current implementation also does not reconstruct historical `direction` or `settings`, and returns `overdraftUsed` as zero. Do not treat it as a full regular-balance response minus permission flags.

<Tip>
  **Why does history exclude permission flags?**

  `allowSending` and `allowReceiving` are mutable operational settings. You can toggle them at any time without a ledger entry. Balance amounts (`available`, `onHold`) change only from recorded transactions. Permission flags represent the *current* operational state of a balance, not a fact about its past.

  Historical audits and reconciliation care about **amounts** at a point in time. Whether sending or receiving worked at a given moment does not matter for audit or reconciliation. Mutable permission state in immutable snapshots would add ambiguity without value.
</Tip>

### Use cases

* **Regulatory auditing**: Prove the exact balance of an account at a specific compliance checkpoint.
* **Reconciliation**: Compare balance snapshots across systems at matching timestamps.
* **Dispute resolution**: Retrieve the precise account state at the time of a contested transaction.
* **End-of-day reporting**: Capture balance positions at market close for treasury operations.

<Warning>
  The `date` parameter is required. It must follow the format `yyyy-mm-dd hh:mm:ss` (e.g., `2026-01-15 10:30:00`). Midaz returns `404` when the requested timestamp precedes balance creation.
</Warning>

### Querying balance history

You can query history for a single balance or for all balances of an account:

* [Retrieve Balance History](/en/reference/midaz/retrieve-balance-history) - Get the state of a specific balance at a given point in time.
* [Retrieve Balance History by Account](/en/reference/midaz/retrieve-balance-history-by-account) - Get the state of all balances for an account at a given point in time.

## Managing Balances

***

You can retrieve your balances through the API. The Midaz ledger engine computes balance amounts from transactions — you cannot set `available` or `onHold` directly. You manage the balance records — key, permission flags, and settings — through the endpoints below.

* [Create a Balance](/en/reference/midaz/create-a-balance) - Create a new balance for an account by defining a unique key.
* [List Balances](/en/reference/midaz/list-balances) - Retrieve all balances by organization and ledger.
* [Retrieve a Balance](/en/reference/midaz/retrieve-a-balance) - Get the balance of a specific account by its unique ID.
* [Retrieve Balances by Account](/en/reference/midaz/retrieve-balances-by-account) - Get the balance for a specific account.
* [Retrieve a Balance by Account Alias](/en/reference/midaz/retrieve-a-balance-by-account-alias) - Get the balance with a human-readable account alias (e.g., @user123).
* [Retrieve a Balance of an External Account](/en/reference/midaz/retrieve-a-balance-of-an-external-account) - Retrieve the balance of an external account (e.g., `@external/BRL`).
* [Update a Balance](/en/reference/midaz/update-a-balance) - Update the permission flags and settings of a balance.
* [Delete a Balance](/en/reference/midaz/delete-a-balance) - Delete a balance entry from the system.

<Tip>
  Do you want to trace **how** a balance formed? Use the Operations API to inspect the ledger history that affected that account.
</Tip>

## Next steps

***

* Use the [Operations API](/en/midaz/operations) to trace transactions that involve multiple balances.
* Combine multiple balances with [Accounting Routes](/en/midaz/transaction-routing-entities) to create flexible and scalable financial flows.
