Reconciliation
Match imported bank transactions against your ledger with auto-matching and exception handling.
Overview
The reconciliation engine matches imported external records against your internal ledger data. It supports three types of records:
| Record Type | What It Is | Reconciles Against |
|---|---|---|
| Transactions | Bank debits/credits, trades, payments | Events and journal entries |
| Positions | Holdings snapshots at a point in time | Computed ledger balances per account |
| Balances | End-of-period account confirmations | Trial balance and account totals |
Import Sources
Records can be imported through several methods:
| Method | Description |
|---|---|
| Plaid | Automatic sync from connected bank accounts |
| CSV | Upload CSV files from any source |
| On-chain | Blockchain transaction scanning |
| Manual | User-entered records |
| API | External system integration |
Transaction Reconciliation
Import
Import transactions from your bank, broker, exchange, or blockchain wallet. Each transaction includes a date, description, amount, currency, and optional reference numbers.
Duplicate detection runs automatically during import — transactions with matching external IDs, transaction hashes, or identical date/amount/description combinations are skipped.
Auto-Matching
After import, run the auto-match engine to find corresponding ledger events. The engine scores potential matches using multiple signals:
| Signal | What It Checks |
|---|---|
| Amount | Exact match, close match (within 5%), or normalized match (handling tax/tip variations) |
| Date | Same date, within 3 days, or within 7 days |
| Counterparty | Exact name match or fuzzy match (handles variations like "AMZN*1A2B3C" matching "Amazon") |
| Reference | Invoice or check number matches |
| Historical patterns | Known counterparty-to-account mappings learned from previous matches |
Transactions scoring above the auto-match threshold (default: 90/100) are automatically matched. Lower-scoring matches are flagged for manual review.
Manual Matching
For unmatched transactions, you can:
- Match to an existing event — link the transaction to a ledger event
- Create a new event — generate a ledger event directly from the transaction, which flows through the posting engine
- Exclude — mark the transaction as not relevant (e.g. internal transfers)
The system learns from your manual matches — counterparty patterns are saved and applied to future auto-matching.
Status Lifecycle
Each transaction progresses through these statuses:
- Unmatched — no corresponding ledger event found
- Matched — linked to a ledger event (auto or manual)
- Confirmed — match verified and locked
- Excluded — marked as not relevant
You can unmatch a previously matched transaction to send it back to the unmatched queue.
Position Reconciliation
Import holdings snapshots from brokers, custodians, or blockchain wallets to verify that your ledger balances match external records.
The engine matches imported positions to ledger accounts by currency and name, then computes the variance between the imported quantity and the ledger balance as of the snapshot date.
Balance Reconciliation
Import end-of-period balance confirmations to verify that your ledger account totals match external statements.
The engine matches imported balances to ledger accounts by account code, name, or role mapping, then computes the variance between the reported balance and the computed ledger balance.
Reconciliation Workflow
- Import — upload CSV or sync from a connected source
- Auto-match — run the matching engine to find correspondences
- Review — examine matched and unmatched items in the dashboard
- Resolve exceptions — handle unmatched items (match, create event, or exclude)
- Confirm — lock reconciled items
Use Confirm All to bulk-confirm all matched items in a batch.
API Reference
Reading Data
GET /api/reconciliation?entityId=...&type=transactions&status=UNMATCHED| Param | Description |
|---|---|
entityId | Required |
type | transactions (default), positions, or balances |
status | Filter by status (UNMATCHED, MATCHED, CONFIRMED, EXCLUDED) |
batchId | Filter by import batch |
summary | Set to true for aggregate counts only |
limit / offset | Pagination |
Transaction Actions
| Action | Description |
|---|---|
import | Import transaction records |
auto_match | Run auto-matching engine |
find_candidates | Get ranked match candidates for a transaction |
manual_match | Link a transaction to an event |
unmatch | Unlink a previously matched transaction |
confirm | Confirm and lock a matched transaction |
confirm_all | Bulk confirm all matched transactions |
exclude | Mark a transaction as not relevant |
create_event | Create a ledger event from an unmatched transaction |
Position Actions
import_positions, auto_match_positions, confirm_position, unmatch_position, exclude_position
Balance Actions
import_balances, auto_match_balances, confirm_balance, unmatch_balance, exclude_balance
All write operations use POST /api/reconciliation with an action field.