How Automatic Transaction Categorization Works — and Why Transfers Get Counted Wrong
Every app that connects to your bank promises to sort your spending for you. Most of them get the ordinary purchases right and then quietly ruin your totals with transfers, credit card payments, refunds, and savings contributions. Here's how automatic categorization actually works, exactly where it breaks, and how to tell whether your numbers can be trusted.

On this page
Every app that connects to your bank makes the same promise: link your accounts and we'll sort your spending for you. And for ordinary purchases, that promise is largely kept. A card tap at a grocery store gets filed under groceries with no help from you.
The trouble starts with the transactions that aren't purchases at all. You move $500 from chequing to savings and your spending jumps by $500. You pay off your Visa and the app counts the same restaurant meal twice. A refund lands and nothing changes. None of this is a bug in your budget — it's a predictable consequence of how automatic categorization works.
This guide explains the actual pipeline that lets an app automatically categorize bank transactions, then walks through the six places it reliably goes wrong, and finishes with how to check whether your own totals are honest.
How apps automatically categorize bank transactions
There is no magic here. Categorization is a chain of four steps, and each step can introduce an error that the next step inherits.
1. The raw feed from your bank
Your bank doesn't send an app a tidy record that says "lunch at a Thai place." It sends something closer to a line off your statement: a date, an amount, a direction, an account, and a description string that was designed for a printed statement in 1994 — POS PURCHASE 8823 MONTREAL QC, PREAUTH DEBIT 00042177, INTERAC E-TRANSFER SENT.
That description is the raw material. Everything downstream is an attempt to work out what it meant.
2. Merchant normalization
The next step is turning that string into a recognizable merchant. Data providers maintain enrichment layers that map messy descriptors to real businesses — stripping store numbers, payment-processor prefixes, city and province codes, and reference numbers, then matching what's left against a merchant database.
When this works you get "Tim Hortons" instead of TIM HORTONS #2281 CALGARY AB. When it doesn't, you get a category assigned to a merchant nobody has identified — which is the root cause of a whole class of errors covered below.
3. A category taxonomy
Enriched transactions get mapped onto a fixed set of categories. Apps built on open banking connections typically use their provider's taxonomy rather than inventing one: a primary category (food and drink, transportation, rent and utilities, transfers in, transfers out, loan payments) and a more specific sub-category underneath it.
This matters more than it sounds. Transfers are categories in that taxonomy, exactly like restaurants are. The provider is telling the app "this was money moving between accounts." Whether the app listens to that signal is a design decision, and it's the decision that separates apps whose totals you can trust from apps whose totals you can't.
4. Rules, then AI for the leftovers
Most of the volume is handled by deterministic rules: if the category is groceries, it's a necessity; if it's transfers out, it isn't spending at all. Rules are fast, free, consistent, and — crucially — auditable. The same transaction always lands the same way.
What's left over is the ambiguous tail: general merchandise, generic services, unidentifiable merchants, "other." This is where AI transaction categorization earns its place. A language model can read the description, the merchant, the amount, and the payment channel together and make a judgment that a static rule can't. It's genuinely better than rules on the hard cases and genuinely unnecessary on the easy ones. An app that runs every transaction through a model is spending money to be less consistent.
The practical takeaway: good categorization is mostly rules, with AI reserved for the residue.
Why your bank transfer gets counted as spending
Here's the single most common complaint about automatic categorization, and it has a mechanical explanation.
When you move $500 from your chequing account to your savings account, your bank does not record one event. It records two, in two different places:
- In chequing: $500 out.
- In savings: $500 in.
An app that treats every outflow as spending and every inflow as income now believes you spent $500 and earned $500. Your spending total is inflated by $500, your income is inflated by $500, and your savings rate is quietly nonsense. That is the whole mechanism behind why a bank transfer gets counted as spending — the app applied a rule about direction instead of a rule about meaning.
The correct handling is not complicated. A transfer is money changing location within your own finances. It is not consumption and it is not earnings. It should be recognized as a transfer and excluded from both totals.
Why some apps count transfers twice
The double-counting version is the same problem with an extra step, and it shows up when you've connected both sides of the movement.
If only your chequing account is linked, the app sees $500 leave and never sees it arrive. Annoying, but a single error. Once you link savings too, the app sees both legs — and if it hasn't recognized them as two halves of one movement, it books both. Now your dashboard shows $500 of spending and $500 of income for an event where your net worth didn't change by a cent.
The irony is that connecting more accounts makes an unsophisticated app worse, not better. This is worth knowing if you're tracking spending across multiple bank accounts — the more complete your picture, the more the transfer handling matters.
Why credit card payments get counted as an expense
This one costs people the most accuracy, because credit card payments are large and monthly.
Follow a single $80 dinner through a system that gets this wrong:
- You pay with your Visa. The card account records an $80 restaurant charge. That's the real expense — it happened when you ate.
- Two weeks later you pay your card from chequing. Chequing records an $800 payment to the credit card.
- The app books both. Your dining is $80 and your "credit card payment" is $800, sitting somewhere in your spending total.
You spent $80 on dinner. The app says $880 of money left your accounts, and if it files the payment as spending, your monthly total is inflated by the entire balance you paid off — every month. The $800 wasn't consumption; it was settling a debt for purchases already counted individually on the card.
The correct handling: the purchase on the card is the expense, and the payment from chequing is a transfer between your accounts. It's the same principle as the savings transfer — the money moved from an asset to a liability rather than between two assets, but you consumed nothing at the moment of payment.
Two related cases fall out of the same logic:
- Interest and fees on the card are real expenses. The principal repayment isn't. If you carry a balance, the interest genuinely left your finances and should be counted.
- Statement-balance payments to a card you've only just connected can look enormous, because the purchases they're paying for predate your connection and were never imported. That's a history problem, not a categorization problem, and it settles after a full cycle.
Four more places categorization quietly breaks
Transfers and card payments are the big two. These four are smaller but they distort the same totals.
Refunds and returns
A refund is a negative expense, not income. If you return a $200 jacket, your clothing spending for the month should fall by $200 — the refund should be netted against the category it came from.
Apps that file refunds as income leave the original $200 sitting in your clothing total and add $200 of phantom earnings. Both numbers are wrong in the direction that flatters you, which is the worst kind of wrong. The tell is easy to spot: return something, then check whether the original category went down or your income went up.
Savings and investment contributions
Money moving into a TFSA, an RRSP, or a high-interest savings account is the transfer problem wearing a different hat — and it's the version that matters most, because it hits precisely the people doing the right thing.
Contributing $600 a month to a TFSA and having it counted as spending means the app is penalizing you for saving. Worse, it makes your savings rate uncomputable: the app can't tell you what percentage of your income you kept, because it thinks you consumed it. Contributions belong in their own bucket — money you kept, not money you spent.
Cash withdrawals
Cash is the genuinely hard case, and it deserves an honest answer rather than a clever one.
When you withdraw $100 from an ATM, no system on earth knows what you did with it. The transaction record ends at the machine. Providers typically classify withdrawals as a transfer-type event, and that's the defensible default — but it is defensible in a different way from the others. A savings transfer is definitely not spending. A cash withdrawal is probably spending, eventually, on something unknowable.
The practical approach: treat withdrawals as their own line rather than forcing them into a category. If cash is a large share of your spending, that's the one place where a small amount of manual attention actually buys you accuracy — and it's worth knowing that no app can solve it for you.
Merchant names that don't identify the purchase
Some descriptors resist identification entirely. Payment aggregators (SQ *, SP *, PAYPAL *), numbered companies, small independent businesses that never made it into a merchant database, and generic e-commerce descriptors all arrive as strings that don't say what was bought.
Providers hand these back as low-confidence or "other." What an app does next is revealing:
- A good app admits it. It marks the transaction as unresolved and leaves it out of confident claims until it knows better.
- A weaker app guesses silently. You get a clean-looking dashboard where an unknown share of the numbers is invented.
An honest "we're not sure about this one" is more useful than a confident wrong answer, because it tells you where to look.
Automatic transaction categorization in Canada: what's different
Most writing on this topic is American, and a few Canadian specifics genuinely change the answers.
- Interac e-Transfers are the big one. They're used for everything — splitting a dinner bill, paying rent, moving money to your own account at another bank, paying a contractor. The descriptor rarely says which. An e-Transfer to yourself is a transfer; rent is a housing expense; your half of dinner is dining. No amount of enrichment reliably separates those, so expect e-Transfers to need a look.
- Bilingual and abbreviated descriptors. Canadian statement strings mix English and French and truncate aggressively, which gives merchant matching less to work with than a typical US descriptor.
- Cross-institution behaviour is normal here. Chequing at a big five bank, savings at EQ or Wealthsimple, a card somewhere else — which makes cross-account transfers frequent, not exceptional. Transfer handling isn't an edge case in a Canadian context; it's a core requirement.
- Coverage varies by institution. Enrichment quality isn't uniform across every Canadian bank and credit union. Check your own accounts rather than assuming.
How to check whether your app is getting this right
Five minutes, five checks. Do them on your own data — they work on any app.
- Move money between two connected accounts. Then check both your spending and income totals for the month. Neither should change. If both moved, the app isn't recognizing transfers.
- Look at the month you paid a credit card. Is the payment sitting in your spending total? If your monthly spending roughly equals your card payment plus your card purchases, you're double-counting.
- Return something. Watch whether the original category drops or your income rises. It should be the former.
- Find your last savings contribution. Is it filed as spending? If yes, your savings rate is meaningless in that app.
- Sort by largest transactions. Errors are almost always big: transfers, card payments, rent, payroll. A quick scan of your top ten catches most of the damage.
If an app fails these, the fix isn't to categorize everything by hand — that's just a spreadsheet with extra steps. It's to use something that handles the structural cases correctly out of the box. If you're weighing options, our comparison of budgeting apps in Canada covers how the main ones differ.
Do you still have to categorize manually?
Mostly no, and the honest answer has a shape worth stating.
For a typical Canadian household, the large majority of transactions are routine card purchases at identifiable merchants, and those are handled without you. The residue is small: unidentifiable merchants, ambiguous e-Transfers, cash, and the occasional purchase that's technically groceries but was really a birthday present.
So an expense tracker with no manual entry is a realistic promise in the sense that matters — you should never be typing in transactions, and you should never be sorting a hundred lines a month. It is not a promise that every line will be perfect forever. The useful question isn't "does it need zero corrections?" but "does it get the structural cases right without me?" Transfers, card payments, refunds, and savings contributions are structural. A misfiled coffee shop is cosmetic.
How Boreal handles it
Boreal is built on the ordering described above, deliberately.
- Transfers, credit card payments, and income are treated as structural. They're recognized from the category signal and are never counted as discretionary spending, so moving money between your own accounts doesn't inflate what you spent.
- Deterministic rules handle the clear cases. Categories that unambiguously map to necessities or discretionary spending are resolved by rule — consistent, repeatable, and the same every time.
- AI is used for the ambiguous tail only, where the merchant or category isn't clear enough for a rule to be honest.
- Unclear transactions stay marked unclear. When neither rules nor context resolve a transaction, Boreal records it as unresolved rather than guessing, and keeps it out of confident claims about your spending.
- Your corrections stick. When you re-categorize something, your decision takes priority over every automated source and is reused for similar transactions.
The point of all this is what sits on top of it: sentences like "dining is up 22% this month" are only worth reading if the number underneath them excludes the $500 you moved to savings. Boreal connects read-only through Plaid, can't move your money, and never sells your data — see how Boreal works for what happens to the data after it arrives, or is it safe to connect your bank account if that's the open question.
Best for: People who want their spending totals to be correct — not just automatic — without hand-sorting transactions every month.
Quick recap
- Categorization is a four-step chain: raw bank descriptor → merchant normalization → category taxonomy → rules, with AI for the ambiguous remainder.
- Transfers get counted as spending when an app treats direction as meaning; connecting both accounts turns one error into double-counting.
- Credit card payments aren't expenses — the purchase on the card is. Counting the payment inflates your month by the whole balance.
- Refunds should net against their category, not appear as income; savings contributions are money kept, not money spent.
- Cash withdrawals are honestly unresolvable — treat them as their own line rather than trusting a guess.
- Test your own app in five minutes: move money, check a card-payment month, return something, find a savings contribution, scan your largest transactions.
The bottom line
Automatic categorization isn't one feature — it's a pipeline, and the interesting failures aren't in the merchant names. They're in the transactions that were never purchases: the transfer to savings, the payment to the Visa, the refund, the TFSA contribution.
Get those wrong and you don't have a slightly-off dashboard, you have a systematically inflated one, in a direction that makes you look like a worse manager of money than you are. Get them right and the automatic part actually delivers what it promised: numbers you didn't have to assemble, that you can also believe.
If you've ever looked at a spending total and thought that can't be right — you were probably correct, and now you know exactly which transaction to go find.
Frequently asked questions
How do apps automatically categorize bank transactions?
In four steps. The app receives a raw record from your bank — date, amount, direction, and a statement descriptor like POS PURCHASE 8823 MONTREAL QC. That descriptor is normalized into a recognizable merchant by stripping store numbers, processor prefixes, and location codes. The merchant and transaction are then mapped onto a fixed category taxonomy (groceries, transportation, transfers, loan payments, and so on). Finally, deterministic rules resolve the clear cases, and an AI model is used only for the ambiguous remainder where a static rule would be guessing.
Why is my bank transfer counted as spending?
Because the app is applying a rule about direction instead of a rule about meaning. When you move $500 from chequing to savings, your bank records two separate events: $500 out of one account and $500 into the other. An app that treats every outflow as spending books the $500 as an expense, and if your savings account is also connected, it books the arrival as income too. Transfers are a distinct category in every major transaction taxonomy — a well-built app recognizes them and excludes them from both your spending and your income.
Why does my budget app count transfers twice?
Because you've connected both sides of the movement and the app hasn't matched them as two halves of one event. With only your chequing account linked, the app sees money leave and never sees it arrive. Once savings is linked too, it sees both legs and counts both — showing spending and income for a transaction where nothing was actually spent or earned. Counterintuitively, connecting more accounts makes an app with poor transfer handling less accurate, not more.
Is a credit card payment an expense?
No. The expense happened when you made the purchase on the card; the payment is a transfer that settles a debt for purchases already recorded. If an app counts both, your monthly spending is inflated by the entire balance you paid off — an $80 dinner and an $800 card payment become $880 of apparent spending. The exception is interest and fees on the card, which are genuine expenses because that money really did leave your finances.
How should refunds be categorized?
A refund should be netted against the category it came from, not recorded as income. Returning a $200 jacket should reduce your clothing spending for the month by $200. Apps that file refunds as income leave the original charge in your spending total and add $200 of income that you never earned, so both numbers end up wrong. To test your own app, return something and check whether the original category went down or your income went up.
How are cash withdrawals categorized?
Usually as a transfer-type event, because the transaction record ends at the ATM — no system knows what the cash was later spent on. That's the defensible default, but it's weaker than the transfer rule for account-to-account movement: a savings transfer is definitely not spending, while a cash withdrawal probably is spending on something unknowable. The practical approach is to keep withdrawals as their own line rather than forcing them into a spending category, and to add manual detail only if cash is a large share of your budget.
Do I still have to categorize transactions manually?
For most transactions, no. Ordinary card purchases at identifiable merchants are handled automatically, so an expense tracker with no manual entry is a realistic promise — you shouldn't be typing in transactions or sorting a hundred lines a month. What remains is a small tail: unidentifiable merchants, ambiguous Interac e-Transfers, cash, and purchases that don't match their merchant's usual category. The right test isn't whether an app needs zero corrections, but whether it gets the structural cases — transfers, credit card payments, refunds, savings contributions — right without you.
Is AI transaction categorization better than rules?
Only for the hard cases. Deterministic rules are faster, cheaper, and more consistent, and they resolve the large majority of transactions identically every time — which matters, because a category that changes between months makes your trends untrustworthy. AI is genuinely better where the merchant is unidentifiable or the category is ambiguous, since a model can weigh the description, amount, and payment channel together. The best design uses rules first and AI for the remainder; running every transaction through a model costs more and produces less consistency.
Tags
Take control of your money
Boreal turns your accounts into clear, AI-powered insights. Join the early access.
Related posts
How to Predict Your Bank Balance at the End of the Month
Your balance today doesn't tell you whether you'll make it to payday. Here's how to predict your bank balance at the end of the month using the bills, income and everyday spending you already have — including a simple worked example, and how an app can project your cash and warn you before you dip.
How to Track Your Spending Without Making a Budget
Not everyone wants to build a budget — and you don't have to. If your goal is to understand where your money goes and avoid surprises, here's how to track spending without budgeting: no categories to set up, no transactions to sort, no spreadsheet to babysit.
AI Budgeting Apps in Canada: What AI Should Actually Do With Your Money
"AI budgeting app" can mean almost anything right now — from a chatbot repeating generic tips to software that actually reads your transactions. Here's how to tell the difference, and what an AI money app in Canada should really do for you.