Skip to content
All insights AI for credit & lending operations

Cash-flow underwriting: turning bank transactions into affordability signals

Open-banking and bank-statement data is raw noise until you categorise, dedupe and derive income and affordability. Here is the pipeline we build for lenders.

5 min read #credit#underwriting#open-banking
Financial services professionals working through an AI initiative

Cash-flow underwriting reads a borrower’s actual bank activity, classifies every transaction, reconstructs income and committed outgoings, and turns that into affordability signals a lending decision can use. The raw feed is close to useless on its own: duplicate lines, cryptic merchant strings, pending entries that later change, transfers that look like income. The value is in the pipeline that cleans it.

A single bank feed is a stream of dated amounts with short, inconsistent descriptions. One person’s salary arrives as SALARY ACME LTD; another’s as a same-day faster payment from a name that also happens to be their flatmate. A loan repayment and a subscription can look identical. Underwriting on that directly produces a model that is confident and wrong. Everything useful happens in the layers between the feed and the feature.

From raw feed to a clean ledger

Modelling comes later. The first job is getting a ledger you can trust. Open-banking APIs and parsed PDF statements both deliver the same headaches, and most of the early failures happen here rather than in the classifier.

  • Deduplication. Aggregators re-send transactions, pending entries get reissued as settled with a different reference, and a re-pulled statement overlaps the last one. We resolve each transaction to a stable identity from amount, counterparty, date and account, then collapse the duplicates. Getting this wrong double-counts income or double-counts debt, and both are dangerous.
  • Pending versus settled. A pending debit can change amount or vanish. We decide per feature whether pending activity is admissible; balance volatility features use it, committed-outgoing features wait for settlement.
  • Reconciliation. Running balance minus the summed transactions should tie out. When it does not, there is a gap in the feed, and a gap in the feed means the income figure is understated. We reconcile before anything downstream reads the data, and hold back applications where the ledger does not balance instead of scoring them anyway.
  • Multi-account netting. Someone with a current account and a savings account moves money between them. Those internal transfers are not income and not spending. Entity resolution across the applicant’s own accounts removes them; miss it and every transfer inflates both sides of the affordability picture.

Only once the ledger balances and the internal transfers are gone does categorisation earn its keep.

Categorisation you can defend

Transaction categorisation is the core of the system, and it is where teams reach for a large model too quickly. Most transactions are categorised by their counterparty, and counterparties repeat. A resolved merchant directory plus rules handles the high-volume, unambiguous cases at near-perfect precision and no per-call cost. The model earns its place on the long tail: unrecognised merchants, ambiguous free-text payments, transfers that need a purpose inferred from pattern.

Two categories carry most of the decision weight and deserve their own treatment.

Income means recurring, attributable inflow. Plenty of money arrives that is not income, so the classifier has to separate salary from a one-off gift, from a loan drawdown that lands as a credit, from a refund. We look for periodicity, a stable counterparty, and amounts that cluster, then derive gross monthly income with a confidence band rather than a single number. A window that does not span a full pay cycle gets a wider band and a flag, not a guess.

Committed outgoings are the mirror image. Rent, existing loan and card repayments, utilities, insurance, childcare, and any other obligation the borrower cannot easily drop. These drive the affordability assessment far more than discretionary spend does. Under the FCA’s affordability rules for consumer credit, the lender has to assess whether repayments are sustainable without undue difficulty, and that assessment leans directly on how well you separate committed from discretionary.

Every categoriser needs a held-out eval set drawn from the real payment mix, with a false-positive budget set per category. Precision on gambling, loan repayments and salary matters more than precision on groceries, because those categories move the decision. We track precision and recall by category, not one blended accuracy number that hides the errors that count.

Features that hold up at decision time

Categorised transactions become affordability features, and this is where point-in-time correctness stops being a nice-to-have. Every feature is computed as of the decision timestamp using only bookings dated at or before it. Labels come from a later, non-overlapping window. If a feature accidentally reads a transaction that settled after the decision, the model learns to predict the future from the future, scores beautifully in backtest, and collapses in production. That is lookahead leakage, and it is the most common way a cash-flow model looks better offline than it ever performs live.

The features that survive tend to be the boring ones:

  • Derived gross and net monthly income, with the confidence band attached.
  • Disposable income after committed outgoings, and its month-to-month stability.
  • Debt-service ratios computed from observed repayments, not stated ones.
  • Balance behaviour: days in overdraft, buffer at month-end, volatility around quarter-end when tax and annual charges land.
  • Adverse signals: returned direct debits, gambling intensity, salary that stopped three months ago.

These live in a feature store so the exact values used for a decision are reproducible, and so training and serving read the same definitions. When a regulator, an internal model-risk reviewer, or an ombudsman asks why an application was declined, you reconstruct the ledger, the categorisation, and the feature vector as they stood at decision time. That lineage is also what makes an adverse-action explanation truthful rather than reverse-engineered.

Cash-flow features drift. Merchant naming conventions change, a bank alters its statement format, a new payment scheme shifts how salaries arrive, and categorisation quietly degrades. We monitor category distributions and income-detection rates against the eval baseline and alert on movement, because a categoriser that silently drops from good to mediocre will quietly move the accept rate before anyone notices in the loss numbers.

The engineering payoff is straight-through processing on the clean cases and a human review queue for the rest: short windows, unreconciled ledgers, low-confidence income, contradictory signals. The pipeline should decide the unambiguous applications on its own and route the genuinely uncertain ones to a person, with the ledger and the derived figures in front of them.

FAQ

Can you underwrite on 60 or 90 days of open-banking data?

You can underwrite thin windows, but not on the same features as long histories. Ninety days rarely covers a full income cycle plus a quarter-end, so gross-income confidence is lower and any seasonal or annual charge is invisible. We flag short-window applications and score them with a model trained only on short windows, rather than extrapolating from features that need twelve months.

How do you stop income and affordability features from leaking future information?

Every feature is computed as of the decision timestamp, using only transactions with a booking date at or before that moment. The feature store enforces point-in-time joins, and the training labels are drawn from a later, non-overlapping window. If a feature cannot be reconstructed from data that existed at decision time, it does not ship.

What accuracy should a transaction categoriser hit before it is usable?

There is no single number, because the cost of an error depends on the category. Misclassifying a coffee shop barely moves the decision; misclassifying a loan repayment or a gambling transaction can flip it. We set per-category precision and recall targets tied to how much each category weighs in the affordability calculation, and hold out a labelled eval set that reflects the real merchant and payment mix.

Working on something similar?

Tell us about your data and the workflow around it, and we will give you a straight read.

Book a 30-min intro call