This guide demonstrates practical implementation patterns for omnibus accounts using Formance Ledger. The platform’s flexibility allows you to adapt these patterns to your specific business requirements, financial practices, and regulatory obligations.
What is an Omnibus Account?
An omnibus account is a pooled account held at a financial institution that aggregates assets belonging to multiple end-users. This structure enables companies to provide financial services to their clients while maintaining relationships with banking partners. From an accounting perspective, the assets held in the omnibus account represent liabilities to your end-users—they have a legal claim on the funds you hold on their behalf.Common Use Cases
- Banking Services: Local and international wire transfers, multi-currency accounts
- Financial Markets: Stock brokerage, currency exchange, collateral management
- Cryptocurrency: Deposits, issuing, reserve assets, withdrawals, remittances, redemption wallets
- Insurance & Risk: Premium collection, claims management, liquidity pools
Key Terminology
Account Classification Terms:- Nostro Account: “Our account with them” - your institution’s accounts held at partner banks
- Vostro Account: “Their account with us” - client accounts held at your institution
- Loro Account: “Their money with you” - viewed from the partner institution’s perspective
- Normal Debit Accounts: Used for assets. Debits increase the balance, credits decrease it
- Normal Credit Accounts: Used for liabilities. Credits increase the balance, debits decrease it
- Double-Entry: Every transaction affects at least two accounts, maintaining the accounting equation
- Multi-Asset Support: Handle USD, EUR, GBP, and other currencies in the same system
- Multi-Bank Operations: Maintain nostro accounts across different correspondent banks
- Nostro Reconciliation: Ensure your ledger representation matches the bank’s actual statements
Implementation Guide
This section demonstrates how to model omnibus account operations in Formance Ledger using real-world examples.System Architecture
1
Define your actors
Identify the key participants in your omnibus account system.
- Banks & Financial Institutions
- End Users (Clients)
- Platform Accounts
Normal Debit Accounts - Hold actual assets at partner banks.These accounts represent your nostro accounts and are identified by their unique identifiers:
- European accounts: IBAN format (e.g.,
FR7630004028379876543210943) - US accounts: ABA routing + account number (e.g.,
021000089:123456789)
Use sub-accounts to handle asynchronous operations where transactions are recorded across multiple events (instruction, processing, settlement).
2
Configure asset handling
Understand how Formance represents monetary values.Formance uses Universal Monetary Notation (UMN) to ensure precision:
| Traditional Format | UMN Format | Description |
|---|---|---|
\$12.34 | USD/2 1234 | 2 decimal places, value in cents |
€56.78 | EUR/2 5678 | 2 decimal places, value in cents |
¢1234 | USD/2 1234 | Already in smallest unit |
Transaction Patterns
The following Numscript examples demonstrate common omnibus account operations. Adapt these patterns to match your specific business requirements and operational workflows.Download the T-Account Movements Excel Template to visualize all accounting entries with detailed T-account diagrams for each omnibus flow described in this guide.
Client Deposit (Payin)
Record a deposit when funds arrive at your bank account with clear client identification. Scenario: A client deposits money into your omnibus account, and you can identify them from the transaction reference.Variables
- $asset (asset): Asset in Universal Monetary Notation (e.g.,
EUR/2,USD/2) - $amount (number): Transaction amount in the smallest currency unit (e.g., cents)
- $bank_number (account): Bank account identifier (IBAN or routing:account format)
- $client_id (account): Unique client identifier for account routing
- $reference (string): Transaction reference for audit trail and reconciliation
Accounts Used
- @banks:$bank_number:main : Nostro account holding actual funds (normal debit)
- @clients:$client_id:main : Client liability account (normal credit)
Numscript
The
allowing unbounded overdraft clause permits the bank account to go negative, accommodating scenarios where ledger updates occur before bank statement reconciliation.Example Usage
EUR deposit - Try in Playground →Unidentified Deposit (Suspense Account)
Handle deposits when you cannot immediately identify the client from the transaction details. Scenario: Funds arrive at your omnibus account but the payment reference doesn’t clearly identify the sending client. Why This Happens:- Missing or incorrect payment references
- Bank statement processing delays
- Third-party payment intermediaries
- Manual or cash deposits
Variables
- $asset (asset): Asset in Universal Monetary Notation
- $amount (number): Transaction amount in smallest currency unit
- $bank_number (account): Bank account identifier receiving the funds
- $platform_name (account): Platform identifier for organizing suspense accounts
- $reference (string): Available transaction reference (even if incomplete)
Accounts Used
- @banks:$bank_number:main : Nostro account receiving funds (normal debit)
- @platform:$platform_name:suspense:payin : Temporary holding account for unidentified deposits (normal credit)
Numscript
Example Usage
EUR unidentified deposit - Try in Playground →Resolving Suspense Transactions
Once you identify the client, create a second transaction to move funds from suspense to their account:Client Withdrawal (Payout)
Process client withdrawals using a three-stage flow that handles the asynchronous nature of banking operations.Formance Ledger maintains consistency at all times, adhering to the accounting equation. However, real-world bank transfers are not instantaneous, requiring careful management of in-flight funds.
1
Step 1: Instruction
Client initiates withdrawal. Immediately reserve funds in a payout sub-account to prevent double-spending.Status: Funds reserved, available balance reduced
2
Step 2: Transmission
Submit payout instruction to the bank via API or batch file (PAIN.001 in SEPA, ACH in US).Status: Pending bank processing
3
Step 3: Settlement
Bank confirms funds have been debited from the omnibus account.Status: Payout complete, funds removed from ledger
Step 1: Reserve Funds
Immediately reserve funds when a payout is initiated to prevent the client from spending the same money twice.Variables
- $asset (asset): Asset in Universal Monetary Notation
- $amount (number): Withdrawal amount in smallest currency unit
- $bank_number (account): Bank account identifier for the payout
- $client_id (account): Client initiating the withdrawal
- $reference (string): Internal reference for the transaction
- $payref (string): Unique payout reference for bank reconciliation (end-to-end ID)
Accounts Used
- @clients:$client_id:main : Client liability account (normal credit)
- @banks:$bank_number:payout:$payref : In-flight funds holding account (normal debit)
Numscript
The payout reference (
$payref) must be unique and recoverable from bank statements. Use formats like end-to-end IDs (SEPA) or trace numbers (ACH).Example Usage
EUR payout initiation - Try in Playground →Step 2: Transmit to Bank
This operational step occurs outside the ledger. Your systems prepare and submit payout instructions to your banking partner.
- ISO 20022 standard format for credit transfers
- Can include multiple payments in a single file
- Supports end-to-end identification for reconciliation
- Typically submitted via SFTP, EBICS, or Swift FileAct
- Timing: Same-day, daily, or multiple batches per day depending on your agreement
- NACHA format for batch payments
- Standard batch cutoff times (usually multiple daily windows)
- Trace numbers for transaction tracking
- Typically 1-2 business days for settlement
- Alternative: Real-time payment networks (RTP, FedNow) for instant transfers
- Many banks or PSPs now offer real-time API access
- Instant payment initiation with real-time status updates
- Webhook notifications for settlement
- Examples: Adyen, Banking Circle, Column, Increase, Stripe Treasury
Step 3: Confirm Settlement
Record the final settlement when the bank confirms funds have been debited from the omnibus account.Variables
- $asset (asset): Asset in Universal Monetary Notation
- $amount (number): Settlement amount in smallest currency unit
- $bank_number (account): Bank account identifier
- $reference (string): Settlement confirmation reference
- $payref (string): Original payout reference for matching
Accounts Used
- @banks:$bank_number:payout:$payref : In-flight payout account (normal debit)
- @banks:$bank_number:main : Main bank account (normal debit)
Numscript
Example Usage
EUR payout settlement - Try in Playground →After settlement, the payout sub-account balance returns to zero, and your ledger accurately reflects the actual bank account balance.
Why Not Use @world?
The @world account appears in many documentation examples as a convenient source for assets — it can go into unlimited overdraft, simplifying transaction examples. While useful for tutorials, using real bank accounts in production provides significant advantages:
Better Reconciliation:
- Direct comparison with bank statements
- Clear audit trail matching external records
- Simplified compliance and reporting
- Track in-flight funds and pending settlements
- Monitor actual vs. available balances
- Identify discrepancies quickly
- Understand cash flow by banking partner
- Analyze fees and transaction costs per bank
- Optimize banking relationships with data
- Less single source constraint avoiding row-locking contingency on the database
- Better parallel processing
@world remains useful for documentation examples, testing environments, internal transfers not involving external banks, prototyping before banking integrations, and use cases with sub-ledgers that are specific to managing assets or liabilities only.Advanced Ledger Features
Enhance your omnibus account implementation with these powerful Formance Ledger capabilities:Bi-temporality
Handle delayed bank statement processing by recording transactions with both effective dates and processing timestamps.Use case: Process yesterday’s bank statement today while maintaining accurate point-in-time balances.
Metadata
Enrich transactions and accounts with custom business data for powerful querying and reporting.Use case: Tag transactions by department, client segment, or payment purpose for financial analysis.
Multi-Asset Support
Handle multiple currencies in the same account structure without currency-specific ledgers.Use case: Manage EUR, USD, and GBP in a single account hierarchy, reusing the same Numscripts across all assets.
Event Publishing
Stream ledger events to other systems for real-time notifications and integrations.Use case: Trigger client notifications, update dashboards, or sync with accounting systems as transactions occur.