Falaah Falaah AI

Bank Reconciliation

Import a CSV, OFX, or QFX bank statement and let Muin auto-match transactions against your invoices and expenses, with AI suggestions for the remainder.

Bank Reconciliation is where the month-end close actually happens. You import a bank statement, Muin auto-matches the obvious transactions against your existing invoices and expenses, and an AI review drawer walks you through the remainder — suggesting ranked matches with a confidence score so you are confirming, not typing. Everything the bank sent stays in the system; nothing gets silently dropped.

If Payments Received is where money lands on an invoice and Bills is where it leaves on a payable, Reconciliation is where you prove the bank’s ledger and yours agree.

The Flow at a Glance

Import Statement (CSV / OFX / QFX / QBO) → Start Reconciliation Session →
Auto-Match (rules + AI) → Review Unmatched (per-transaction drawer) →
Confirm Matches → Session Marked Complete
Stage Surface
Import Finance > Reconciliation, Import Statement button (also bound to the R keyboard shortcut)
Statements list Table of imported statements with period, transaction count, closing balance, status
Start session Start Reconciliation action on an imported statement row
Auto-match Auto-Match action on an in_progress session row
Review drawer Review action on an in_progress session row
Complete Session status flips to completed once all transactions are matched or excluded

Every stage is durable — you can close the page mid-session, come back tomorrow, and resume exactly where you left off.


Importing a Statement

Click Import Statement (or press R) and pick a file. The file input accepts .csv, .ofx, .qfx, and .qbo. Muin handles each format natively — no conversion step, no third-party upload service.

Limits are enforced at the API boundary:

Limit Value Why
Maximum file size 20 MB Large-bank monthly statements comfortably fit; anything larger is almost certainly the wrong file
Maximum transactions per import 10,000 Keeps the per-import memory footprint reasonable; forces very large banks to be split into monthly chunks
Duplicate detection SHA-256 of the file bytes Uploading the same CSV twice returns the original statement instead of creating a duplicate — no phantom transactions

If your file exceeds the transaction limit, split it by month and import separately. If the file type is not supported, the banner will tell you what was rejected and you can retry with a different file without re-opening the picker.

Success and error states

The panel above the statements table shows exactly one banner per import:

  • Success — green, shows immediately after a successful import. The new statement appears in the table with status imported.
  • Error — red with a Retry button that resets the upload and re-opens the file picker. The error text surfaces the underlying reason (unsupported format, empty file, too many transactions, file too large).

The Statements Table

Once imported, every statement has a row in the Bank Statements view. The columns are deliberately the ones you need to spot a wrong import:

Column What It Shows
Bank Parsed bank name + original file name
Account Masked account number (****1234) — Muin never stores the full number
Period The statement’s start and end dates, parsed from the transactions
Transactions Count of parsed transaction rows
Balance Closing balance, formatted in the statement’s currency
Status imported, processing, reconciled, or failed
Actions Start Reconciliation when imported; a ✓ Reconciled marker when the session is reconciled

Click Start Reconciliation to create a session for the statement. The statement stays linked to the session — you can see which session closed which statement from the history.


Auto-Match: Rules + AI

Once a session is running, click Auto-Match. Muin runs every unmatched transaction through a two-stage matcher:

Stage 1 — rule-based scoring (0–100)

Each potential match (an invoice, expense, or donation in the tenant) gets a confidence score built from three signals:

Signal Weight Rule
Amount match up to 50 points Exact match = 50, within 1% = 45, within 5% = 35, within 10% = 20
Date proximity up to 30 points Same day = 30, within 1 day = 25, within 3 days = 20, within 7 days = 10
Description similarity up to 20 points Invoice number in description = 20; shared keywords with the entity description = 10–15

Any candidate scoring below 50 is dropped — suggesting a 40% match is worse than suggesting nothing. The top five remaining candidates advance.

Stage 2 — AI re-ranking

When the rule-based stage produces multiple plausible candidates, Muin sends the bank transaction plus the candidate summaries to the AI ranker, which can adjust scores based on semantic cues the keyword matcher misses (“ACME Corp Inc” vs. “ACME Corporation” on an invoice). The AI ranker is budget-limited per session to keep costs bounded — once the session budget is consumed, the remaining transactions fall back to rule-based scoring alone.

What gets applied

A threshold (default 80) decides what auto-applies vs. what surfaces as a suggestion:

Confidence Outcome
≥ threshold (default 80) Automatically applied — transaction is matched to the entity, no review needed
50 – threshold Left unmatched with ranked suggestions available in the review drawer
< 50 Dropped — transaction stays unmatched with no suggestions

You can adjust the threshold from the API (min_confidence query parameter, range 50–100), but the UI defaults to 80 and most users leave it there. The session’s match rate on the sessions table shows how well the auto-matcher did at a glance.


The Review Drawer

Click Review on an in_progress session to open the reconciliation review drawer. This is where you work through transactions the auto-matcher could not confidently resolve.

Every unmatched bank transaction appears as a row. Expand a row to see up to five ranked match suggestions pulled live from the reconciliation API. Each suggestion shows:

Element What It Means
Entity-type badge invoice, expense, donor, etc. — which record this suggestion is pointing at
Confidence badge Color-coded: green ≥ 80, amber ≥ 60, blue otherwise
Reason text A short human-readable explanation of why this candidate was suggested (amount match, date proximity, description keyword)
Confirm button One click matches the transaction to the suggested entity and records who confirmed it
AI feedback button Thumb-up / thumb-down on the AI’s suggestion — the feedback is scoped to the reconciliation_match feature and feeds future model tuning

Confirming a suggestion posts a single match action to the bulk match endpoint. The session’s match counters update immediately and the transaction moves out of the unmatched list. You can confirm as many as you want in one sitting, or just the ones you are sure of — the session stays in_progress and waits for you to come back to the rest.

Nonprofit tenants — donor suggestions

If the organization has the nonprofit module enabled and the matcher finds a donor candidate (rather than an invoice or expense), the confirm flow opens a dedicated nonprofit reconciliation tab that lets you record the match as a donation with the right receipt metadata. This keeps donations out of the generic invoice/expense paths where they would otherwise produce an accountant-confusing ledger entry.


The Sessions Table

Switch the header filter to Reconciliation Sessions to see every session — in-progress, completed, partial, or cancelled. The columns mirror what a reviewer needs to pick up someone else’s work:

Column Shows
Session Session name + start timestamp
Period Statement start / end date
Progress N matched / M total transactions, plus unmatched and excluded counts
Match Rate A bar + percentage of transactions matched against total
Status in_progress, completed, partial, or cancelled
Actions Auto-Match + Review while in progress; View Report once completed

The review button disables itself once there are no unmatched transactions left, so a reviewer does not wander into an empty drawer.


What Reconciliation Does Not Do (Today)

  • Live bank-feed sync. Reconciliation is statement-file-based today. Automatic transaction sync from Plaid or the bank’s API is tracked as external work and not part of this flow.
  • Create invoices or expenses on the fly. The matcher matches against entities that already exist. If a transaction has no plausible match, you excluded it or create the invoice/expense separately first.
  • Edit parsed transactions. The raw transactions are trusted as the bank sent them. If the parse is wrong, fix the statement at the bank and re-import; the duplicate-detection will keep the original out of your way.
  • POS receipt reconciliation. POS orders have their own payment settlement path — this flow is for bank-statement transactions, not individual POS receipts.

Where Reconciliation Fits

You are here You might also want
Reconciliation Payments Received — to record a payment against an invoice before matching
Reconciliation Bills — to record an expense before matching it to a bank debit
Reconciliation AR Aging — to see which invoices are still unpaid after reconciling

The goal: at the end of every month, every transaction on the bank statement is either matched to a Muin record or explicitly excluded — and the two ledgers agree without a spreadsheet.