Skip to main content

Bank reconciliation

Import statements in OFX, QFX, MT940, CAMT.053, or CSV format and let Frihet match every transaction to its invoice or expense using fuzzy matching and bank rules.

Overview​

Bank reconciliation in Frihet connects your real treasury (checking account or corporate card movements) with your accounting records (issued invoices and logged expenses). Every bank transaction passes through a structured 5-stage pipeline that ensures no movement is left in limbo or double-counted.

Prerequisites before reconciling​

To complete an end-to-end verifiable reconciliation, make sure you have:

  1. A previously recorded invoice or expense: for example, issued invoice F-2026-0001 for Estudio Norte S.L. (B12345674, facturacion@example.com) in Sent or Overdue status for €1,815.00 (€1,590.00 with 15% IRPF withholding, or €907.50 when testing a 50% partial payment).
  2. A statement imported into the matching bank account: transactions uploaded via Finance → Banking → Import Statement (synthetic CSV statement example) or via /v1/banking in the recognized stage.
  3. An optional bank rule for non-invoice charges: an active rule under Settings → Bank rules to classify maintenance fees or recurring charges (see rule example).
Illustrative documentation fixture

The Estudio Norte S.L. dataset (Tax ID B12345674, email facturacion@example.com, invoice F-2026-0001) used in this walkthrough is a synthetic documentation fixture: B12345674 only satisfies algorithmic check-digit validation (it does not prove non-existence or ownership in the AEAT census), and example.com is an IANA-reserved documentation domain (RFC 6761), not a controlled QA mailbox. These examples do not execute real bank transfers or replace verification with your real statements or in an authorized QA environment.

The 5-stage transaction pipeline​

StageDescriptionRequired action
rawNewly imported movement from a file (OFX, QFX, MT940, CAMT.053, CSV) or logged via the /v1/banking API.Immediate automatic processing.
recognizedNormalized with value date, signed amount, currency, counterparty, and cleaned reference.Evaluated by the matching and rules engine.
matchedSuccessfully linked to an issued invoice (collection) or a logged expense (payment).Reconciliation complete; the invoice moves to paid.
categorizedNo prior invoice, but classified by a bank rule (e.g., bank fees, taxes, payroll).Review and apply the pending suggestion.
excludedInternal or non-tax-relevant movement (e.g., transfer between your own bank accounts).Archived with full audit trail without altering P&L.

How intelligent matching works​

Frihet applies two resolution layers when importing transactions:

  1. Fuzzy Matching: Compares exact amount (or cent-tolerance), time window near the issue or due date, client/vendor tax ID or name, and invoice number in the bank remittance concept.
  2. Bank Rules: If the movement matches conditions you defined (amount range, text in concept, merchant name), Frihet automatically applies the configured category. Frihet also suggests rules based on your own expense history.

Step-by-step walkthrough: from imported statement to reconciled payment​

1. Import a statement and filter duplicates​

  1. Go to Finance → Banking and select your bank account (Main Operating EUR).
  2. Click Import Statement and drag your OFX, MT940, CAMT.053, or the 4-row synthetic CSV file from Bank connections.
  3. In the preview table, verify that the repeated second row (+€1,815.00 with the same date and reference SEPA-20261016-001) is flagged as Duplicate and is not imported a second time.

2. Review suggested matches, fees, or partial payments​

  1. Open Finance → Banking → Transactions and filter by Pending (recognized).
  2. On the inflow TRANSF ESTUDIO NORTE SL B12345674 FAC F-2026-0001 (+€1,815.00, or +€1,590.00 with IRPF withholding), click Review (Reconciliation review).
  3. Verify that Frihet proposes invoice F-2026-0001 for Estudio Norte S.L. based on the matching tax ID (B12345674), invoice number (F-2026-0001), and amount:
    • For a 100% full collection (€1,815.00), click Apply: the transaction moves to matched and the invoice status changes to Paid (paid) with €0.00 remaining balance.
    • For a 50% partial collection (€907.50), link the movement to the invoice: Frihet records €907.50 collected and keeps €907.50 as the remaining open balance.
    • If a suggestion points to the wrong document, dismiss it and use Link invoice to select the right invoice manually.

3. Categorize non-invoice bank charges and exclude internal transfers​

  1. On the -€12.50 charge (COMISION MANTENIMIENTO CUENTA OCT), apply the suggestion from your bank rule or click Create rule so it moves to the categorized stage.
  2. For an internal transfer between two bank accounts owned by your company, click Exclude (excluded) to preserve the bank audit trail without inflating revenue or expenses.

Expected result after reconciliation​

After processing the four rows of the synthetic statement, the verifiable state in Frihet is:

Statement movementAmountFinal pipeline stageImpact on invoicing and reports
TRANSF ESTUDIO NORTE SL B12345674 FAC F-2026-0001 (row 1)+€1,815.00matchedInvoice F-2026-0001 moves to Paid (paid), leaves Reports → Aging, and appears in Reports → Payments.
TRANSF ESTUDIO NORTE SL B12345674 FAC F-2026-0001 (row 2)+€1,815.00Skipped (Duplicate)Creates no second transaction and never alters cash balance or report totals.
COMISION MANTENIMIENTO CUENTA OCT (row 3)-€12.50categorizedBooked under financial/bank fee expenses via bank rule; visible in Reports → Expenses.
TRANSF ESTUDIO NORTE SL ENTREGA 50 PCT F-2026-0002 (row 4)+€907.50matched (partial)Logs a €907.50 partial collection in Reports → Payments and leaves €907.50 open in Reports → Aging.

Reconciliation failure cases and recovery​

Discrepancy or failure caseTypical root causeRecovery action in Frihet
1. CSV swaps inflows/outflows or rejects dates during importThe bank exported charges as positive numbers or used an ambiguous regional date format (MM/DD/YYYY).Pick your bank's template when uploading the CSV under Finance → Banking → Import Statement, or export in CAMT.053 / OFX.
2. You uploaded the same date range twice and worry about double-countingOverlapping dates between two consecutive bank exports.Frihet blocks repeated rows by flagging them as Duplicate during import; if you pushed a duplicate manual transaction via API, mark it as Exclude (excluded).
3. A single bank transfer pays multiple invoices (F-2026-0001 and F-2026-0002)The client grouped two or more invoices into one SEPA wire (e.g. €3,630.00).Do not force the full amount onto a single invoice: split the transaction across the target invoices following Multi-invoice collection from a single transfer.
4. Difference between invoice (€1,815.00) and bank inflow due to fee or partial payThe client paid 50% (€907.50), applied 15% IRPF withholding (€1,590.00), or Stripe deducted its processing fee before payout.For a partial payment, link the received amount (€907.50) so the remainder stays open; for a fee deducted at source, reconcile the invoice and record the bank/gateway fee expense.
5. The invoice is in USD while the bank account settles in EURThe bank converted the currency at the settlement date's exchange rate.Reconcile the movement in the bank account's currency or review the exchange-rate difference in Multi-currency.

Supported statement formats​

FormatExtensionAdvantages
OFX / QFX.ofx, .qfxIncludes a unique transaction identifier (FITID) that prevents duplicates across overlapping date exports.
MT940 (SWIFT).sta, .mt940European corporate banking standard with verifiable opening/closing balances and structured SEPA references.
CAMT.053.xmlISO 20022 SEPA XML bank-to-customer statement standard.
CSV.csvCompatible with any bank or neobank; automatic detection or a bank template.

Automation via REST API and MCP​

Accounting agents and automated workflows can inspect transactions and manage bank rules via the REST API or the @frihet/mcp-server MCP server:

# List bank transactions waiting for reconciliation
curl "https://api.frihet.io/v1/banking/transactions?status=recognized" \
-H "X-API-Key: $FRIHET_API_KEY"

MCP tools for bank reconciliation​

  • list_bank_accounts / get_bank_account — Query your bank accounts and current balances.
  • list_transactions — Filter bank movements by account, date range, or pipeline stage.
  • match_transaction_to_invoice — Link a bank transaction directly to its corresponding invoice.
  • categorize_transaction — Assign an accounting category to a bank movement.
  • frihet_bank_rules_list / frihet_bank_rule_create — Audit and create automated reconciliation rules.

See the full reference in REST API and MCP Server.

Next action​