Skip to main content

Statement processing

Bank statements are the most complete way to record your financial history in Clatri — richer than chat (which is good for stray day-to-day expenses) and available for every bank (unlike open banking, which only covers some countries). The agent's Statement Expert reads the document and leaves you an editable staging area you approve before anything is recorded.

This page describes the full process: statement types, the import flow, the smart features the system applies (duplicate detection, internal-transfer detection, automatic counterpart and expense-group association) and the per-entity instructions you can write to guide the extractor.

Statement types

TypeWhen the bank issues itWhat it covers
Account statementMonthly or quarterly, depending on the bankMovements of a checking or savings account in a period. Debit cards do NOT issue their own statements — their movements live in the statement of the account they're linked to.
Credit card statementAfter each statement-close dateCharges, payments, and fees from the cycle between the previous close and the current one. If your card closes on the 15th, the "April" statement covers from March 16 to April 15.

That's why it's important to correctly configure the close date and payment due date when you create the card in Clatri — the system uses them to align the statements you upload and to generate notifications.

The import flow

You upload the file (PDF, Excel, CSV, screenshot) to chat. The agent delegates to the statement_expert sub-agent which runs 5 steps:

  1. Extraction — the LLM extractor reads the document and produces a structured list of transactions. Your per-entity instructions are applied here (see below).
  2. Association resolution — for each transaction it tries to infer the counterpart (which contact) and the expense group it belongs to, consulting your contact directory and your existing groups.
  3. Duplicate detection — compares each transaction against the ones you already have recorded (manual, bank integration, previous statement) using amount + date + description. Matches are flagged as duplicates.
  4. Internal-transfer detection — if two of your accounts show the same amount with opposite signs on close dates, both sides collapse into a single internal transfer instead of one expense + one income.
  5. Staging and review — the agent returns an interactive widget with the list of transactions: new, duplicates, detected transfers, and ones that need manual review. You edit, discard, or confirm. Nothing is recorded until you approve.

Reconciliation vs new registration

When executing the import you can choose between:

  • New registration (default) — transactions are recorded and update the account's current balance. Useful for a recent statement that brings your account up to date.
  • Reconciliation — records historical transactions without modifying the current balance. Useful when you upload past months and don't want them to recalculate a balance you already knew.

Receiving statements by email (automatic)

You don't have to download and upload every statement by hand. Your bank emails it to you each month — you can have it land in Clatri only and get processed without lifting a finger.

Each profile has an inbound address (something like a1b2c3d4@inbox.clatri.com) you can forward your bank's emails to. And if you set up automatic forwarding in Gmail or Outlook with a filter on the bank's sender, every statement that arrives goes straight into the import flow above: the statement_expert reads it, leaves it in staging, and you approve.

If the PDF is password-protected (your national ID, a bank code), Clatri tries to open it with your national ID and the passwords you save.

The step by step — including how to set up forwarding in Gmail and Outlook — is in Receiving documents by email.

Per-entity instructions — what's missing for the extractor to "know you"

Each entity in Clatri has a free-text field called Statement processing instructions. You'll find it in Settings → Entities → [your entity] → Statement instructions.

It's unstructured text, in your language, where you write the conventions and quirks the LLM extractor can't guess on its own. It's prepended to the prompt with maximum priority every time you import a statement, so the agent "knows you" without you having to repeat it in every chat.

Typical use cases:

Mom: any transaction to "Julia M.", "María Castro", "MARIA CASTRO" or
"J CASTRO" is to my mom. Associate it with the "Mom" contact.

4x100 is NOT a bank fee, it's a tax. Classify it as "taxes".

Asopagos is social security, not private insurance. Category: health.

In Davivienda statements balances appear in the second column
(not the first as in most banks).

Ignore all lines containing "INTERESES CORRIENTES" — they're
bank aggregates that duplicate the actual movement.

Transfers between my Nequi and Bancolombia accounts always carry
"NEQUI" or "BANCOLOMBIA" in the description — collapse them as
internal transfers.

As you can see, it ranges from contact aliases ("Julia M = mom") to classification rules ("4x100 = tax") through bank conventions ("balances in column 2") and filter rules ("ignore X lines"). It's the only way to encode knowledge the LLM can't have otherwise because it depends on your life, your contacts, and your specific bank.

Per entity, not per account: if you have an entity Camilo personal and another Gurwi LLC, you can have different conventions in each. The personal ones can talk about mom; the company ones, about specific suppliers and clients.

Duplicate detection

When you import a statement, the system compares each new transaction against existing ones with a heuristic that combines:

  • Exact amount (same sign, same currency)
  • Date within a tolerance window (±2 days for statements, up to 5 days if the transaction came from a recurring payment because banks sometimes take time to process)
  • Description with normalization (uppercase, spaces, accents stripped; fuzzy matching)
  • Account / card — only compares against transactions from the same account

Transactions identified as duplicates appear with a special indicator in the review widget. By default they're NOT recorded, but you can force registration case by case if you decide the duplicate is actually legitimate (same amount on the same day by coincidence).

The same duplicate engine also applies to open banking — when Plaid reports a new transaction, it first checks whether you'd already recorded it manually or by a previous statement.

Internal-transfer detection

If you transfer $500,000 from your Bancolombia account to Nequi, that transaction appears twice in your statements: as Bancolombia outflow and as Nequi inflow. Without automatic detection, you'd end up with a phantom expense + phantom income that distort your cash flow.

The system detects this by comparing, in any statement you import, the transactions against the movements of your other accounts in a nearby time window. When it finds a pair (same amount, opposite signs, close dates, descriptions that often mention the other bank), it collapses them into a single internal transfer that affects both balances without counting as expense or income.

This also happens with credit card payments: if you pay the card from your checking account, the account outflow and the inflow (credit to the card balance) are reconciled as a single movement.

Automatic association to contacts and groups

During extraction, the LLM reads each transaction's description and tries to resolve:

  • Counterpart — searches your contact directory by name or alias. If it finds a match (or your per-entity instruction gives it the hint — "Julia M = mom"), it pre-assigns the contact.
  • Expense group — if the description matches the name or keywords of an existing group ("Camila's wedding", "Tabs with Andrés"), it pre-assigns the group.

These suggestions are shown in the review widget. You confirm, change, or discard them before executing the import. If you discard, transactions are recorded without the association; if you confirm, they stay linked and show up automatically when you filter by that contact or group.

Multi-currency and opening balance

If your statement is in a different currency from the account's main currency, the system asks for the exchange rate for the conversion. Transactions are stored in both currencies (original + converted) so you can see the real detail and a consistent aggregate.

Also, if the statement includes a starting / ending balance, the system uses it as an opening balance to align the historical balance calculation with your current balance — avoiding the drift that would happen if you only sum/subtract transactions.

What to do when something goes wrong

  • The extractor didn't read a transaction correctly → fix it in the staging widget before approving. If the error repeats on every import from the same bank, add the rule to the per-entity instructions so it doesn't happen again.
  • The extractor mislabeled a category → fix in staging. If it always happens, add the rule to instructions ("Asopagos is always health, not taxes").
  • The extractor duplicated a transaction that is NOT a duplicate → uncheck the duplicate flag in the widget; it'll be registered normally.
  • The extractor collapsed two things as an internal transfer when it wasn't → uncheck the flag in the widget and record the two sides separately.
  • The extractor made up data (hallucinated) → report the case in Settings → Feedback Board. The extractor is tuned but no LLM is perfect; knowing where it fails helps us improve the prompt.