Skip to main content
A single customer rarely has a single balance. The same person can hold a main account, a benefit account, a blocked account, a product sub-account, or a promotional balance. Each balance has its own rules, its own statement, and its own reconciliation needs. The common shortcut treats these as labels on one account and sorts them out in application code. That works until balances, ledgers, statements, or operational rules must diverge. At that point, a single account can no longer tell the truth about where the money is. This page shows the reference architecture for one customer with many Midaz accounts. It maps each part of the model to a native platform entity. Then it walks through an example: three accounts for the same customer document.

Why this matters


For product and operations teams, each balance becomes its own account. The Ledger then enforces every segregation rule — a blocked outflow, a benefit-only spend, a promotional balance with an expiry. The rule lives in the Ledger, not in application logic. Each account carries its own statement and reconciliation trail. For engineering teams, each external address resolves to a specific account before Midaz posts a transaction. Core banking numbers and payment-rail identifiers each point to one balance. You never guess which balance an incoming event belongs to. There is no separate balance store to keep in sync with the Ledger.

The reference architecture


The model is one owner, N accounts, N external identifiers:
  • One owner — the customer, identified by a document (CPF, CNPJ, tax ID). The owner represents who holds the relationship. It does not carry a balance and does not decide transaction routing.
  • N accounts — each account is a self-contained accounting position, with its own balance, ledger, statement, and rules.
  • N external identifiers — the addresses other systems (a core banking platform, a payment rail) use to reach a specific account. Each identifier resolves to exactly one account.
A middleware layer keeps the map between external identifiers and accounts. It resolves each identifier to the correct account before the call to Midaz. Midaz remains the source of truth for accounts, balances, and entries.
One customer, many accounts — reference architecture

Reference architecture: one customer, many accounts.

When balance, ledger, statement, or operational rule differs by destination, point each identifier at a distinct account. An external identifier is not just a nickname for one shared balance.

How Midaz maps the model


Every part of this architecture maps to a native Midaz entity. You do not build a separate balance store or invent an accounting layer.
Much of what an external “alias registry” would do is already native. The account alias is the in-Ledger address. entityId stores your external system’s identifier. The middleware’s job is narrow — translate an external rail identifier into the right account alias, then post.

Prerequisites


This example assumes a running Midaz environment with the following in place:
Midaz represents values in the smallest unit of the currency. For BRL, 15000 means R$ 150.00 (centavos).

Building three accounts for one customer


The customer with document 12345678900 needs three accounts. The main account is free for ordinary movement. The benefit account follows product rules. The blocked account accepts inflows but restricts outflows.
1

Enable Account Type validation

Turn on validation so every account must declare a registered type. This is what lets the Ledger enforce each account’s nature.
Settings take effect immediately — no redeployment needed.
2

Register the Account Types

Create one Account Type per balance nature. The keyValue is what each account’s type field must match.
Repeat for benefit_account (movement under product rules) and restricted_account. The restricted_account is the blocked account: it accepts inflows but conditions or blocks outflows.
3

Create the three accounts

Each account links to the BRL asset and declares its type. It carries an alias (its in-Ledger address) and an entityId (its identifier in your external system).
Create the benefit account with alias @cust_12345678900_benefit, entityId 0001/88888-2, and type benefit_account. Create the blocked account with alias @cust_12345678900_blocked, entityId 0002/77777-0, and type restricted_account.
The entityId is where you store the external address that other systems use to reach this account — your map between Midaz and your source system.
4

Register the customer as a Holder

Create one Holder for the customer. The same Holder owns all three accounts and keeps identity in one place.
In Midaz v4, CRM is part of the ledger binary, so it needs no separate service or port. The organization ID travels in the URL path — see Getting started with CRM for the full schema.
Save the returned holderId — you’ll use it in the next step.
5

Link each account to the Holder

Create one Instrument per ledger account to attach banking and regulatory context. The Instrument powers CRM-driven features and keeps customer-facing details out of the Ledger.
Notice how the main account’s entityId (0001/12345-1) decomposes into the branch (0001) and account (12345) you record here. That external address now resolves to one specific account. Repeat for the benefit and blocked accounts, and point accountId at each one.
The result: one customer, three accounts, three distinct external addresses. Each account keeps its own balance, statement, and rules under a single Holder.

The transaction boundary


When an external event arrives, the resolution happens before the call to Midaz. Each layer stays in its lane, and that preserves accounting clarity.
1

External event

A transaction, query, or settlement arrives with an external identifier.
2

Middleware resolves the identifier

The middleware looks up the external identifier and resolves it to the correct Midaz account alias. It also applies status validation (active, blocked, closed).
3

Midaz posts to the right account

Midaz records the entry against the resolved account and preserves balance and ledger. Statement and reconciliation stay separate by account.
An identifier for a blocked or closed account must fail validation before the call to Midaz. Routing decisions belong in the middleware. The Ledger stays the source of truth for balances and entries.

What this unlocks


  • Real segregation — each balance has its own ledger and statement. You cannot spend a blocked balance through the main account by accident.
  • Unambiguous routing — every external event has a single, well-defined destination account.
  • Centralized identity — one Holder owns many accounts. Identity and contact data live in one place while balances stay separate.
  • Native, not bolted-on — accounts, types, aliases, and entityId are platform primitives, so there’s no parallel balance store to reconcile against the Ledger.

What you need to get started


Next steps


Accounts

The core financial unit — aliases, entityId, and external accounts.

Account Types

Classify accounts and enforce their nature with route validation.

Portfolios

Group a customer’s accounts to view the total relationship.

CRM: Holders & Instruments

Centralize identity and attach banking and regulatory context.