Categorize Expenses Automatically

You'll end up with: A categorized month of transactions in a spreadsheet, plus a saved category rules block and a reusable Claude prompt so the next import takes minutes, not hours.

Overview
15–20 min
Intermediate
Free
2 tools
Cost breakdown
Claude.aiFree
Google SheetsFree
TotalFree
Common mistake

Letting the model invent categories on the fly so your books drift month-to-month and tax time becomes archaeology. Fix: Lock a numbered taxonomy in step 2 (max ~12–15 labels), paste it into every batch prompt, and forbid new category names unless you explicitly type NEW: with a one-line definition.

Before you start
  • One month (or 30–60 rows) of card/bank transactions exported as CSV or pasted into a sheet
  • A Google Sheet (or Excel) open
  • Your real category list (even a rough draft: Software, Travel, Meals, Owner draw, etc.)
  • Claude open in a single chat you will keep through steps 2–4
1

Normalize the import into a clean working tab

One row per transaction with consistent columns before you involve AI.

Google SheetsFreeOpen Google Sheets
Exact action

Create a new spreadsheet named: Expenses — [MONTH] — working Add a tab called Import. Paste or use File → Import to bring in your bank/card CSV. Standardize columns to exactly these headers (insert/rename columns as needed): Date | Description | Amount | Source (optional) | Category (leave blank for now) Fix common import problems: - Remove merged cells and duplicate header rows - Ensure one logical transaction per row (no multi-line descriptions that belong to separate charges) Sort by Date ascending. Select the header row plus your first batch of transactions (aim for ≤60 rows in the next steps) and copy (Cmd/Ctrl+C). You will paste this into Claude in step 3.

Every row has a parseable Date, a non-empty Description, and Amount uses one consistent sign convention (refunds clearly negative or clearly labeled).
Merged headers, multiline cells, or Description blobs that are really full receipts—split or clean until you have one transaction per row before continuing.
2

Lock the taxonomy and disambiguation rules in Claude

Give the model a fixed category list and hard rules—no improvisation.

Claude.aiFreeOpen Claude.ai
Exact action

Open https://claude.ai and start a NEW chat. Keep this same chat open through steps 3 and 4. Paste the following block, replacing the bracketed sections with your real data: --- MY CATEGORY TAXONOMY (FINAL — do not add labels): [List each category with a one-line definition] REAL EXAMPLES (3 per category): [Paste short examples you have actually seen on statements, or realistic placeholders] DISAMBIGUATION RULES (hard constraints): - Example: If Description contains AWS, DIGITALOCEAN, or GITHUB → category Software (not Professional services). - Example: If Description contains UBER or LYFT and text mentions airport or flight → Travel (not Meals). GLOBAL RULES: - Do not invent new category names. - If a transaction cannot be mapped with high confidence, use exactly: Needs review (do not guess toward the closest category). --- Then send: Echo my taxonomy back as a numbered markdown table. Do not classify transactions yet. List only ambiguous merchant TYPES (not random new categories) where my rules might need tightening.

Claude returns your exact category names with no extras (no Misc, General, or Other unless those were explicitly in your list). Gaps are about merchant patterns, not invented categories.
Claude adds categories you did not list. Reply: "Forbidden: use ONLY my category names. For anything uncertain, use exactly Needs review." Ask it to regenerate the echo.
3

Batch-classify pasted transactions

Paste rows in one or two chunks in the same Claude chat and demand a reconcileable table.

Claude.aiFreeOpen Claude.ai
Exact action

In the SAME Claude chat from step 2, paste your copied sheet data as a markdown table OR tab-separated values. Above the paste, send: --- Use ONLY the taxonomy and rules already defined in this conversation. Task: Assign exactly ONE category per row from my numbered list. Output a markdown table with columns EXACTLY: Row | Suggested_category | Confidence_High_Med_Low | One_line_reason | Flag_if_split_Yes_No Rules: - Suggested_category must be one of my categories OR exactly Needs review. - One_line_reason must quote or closely paraphrase words from Description (no invented merchants). If you have more than ~40 transaction rows, split into two pastes in this same chat (Part 1 / Part 2) and keep row numbering continuous. After both parts (if split), send: Reconcile: the same Description substring must map to the same category across all rows unless Amount sign differs (e.g. refund vs purchase). --- Paste your rows after that instruction block.

Every row has Suggested_category filled (or Needs review). Reasons point to actual Description text.
The same merchant/description string gets different categories across chunks. Re-send the reconcile line from the block above; if it persists, paste the conflicting rows side-by-side and ask Claude to pick one rule.
4

Resolve Needs review rows and lock a RULES_ADDENDUM

Turn exceptions into testable substring or amount rules you can reuse next month.

Claude.aiFreeOpen Claude.ai
Exact action

In the SAME chat, copy back only rows where Suggested_category is Needs review OR Confidence is Low. For each repeating pattern, decide: (a) Approve a one-sentence new IF/THEN rule using Description substrings, Source, or an Amount threshold, OR (b) Keep as Needs review for human judgment this month. Then send: --- Output a block titled exactly: RULES_ADDENDUM Content: bullet list ONLY. Each bullet must be testable (substring, Source value, Amount >/< threshold). No bullets like "use judgment" or "when it feels like travel." Maximum 10 bullets. Do not re-print the full transaction table unless I ask. --- Edit the RULES_ADDENDUM bullets yourself if any line is vague before you move on.

RULES_ADDENDUM has ≤10 bullets; every bullet could be applied by a careful human or script without subjective vibes.
Bullets are subjective. Reply: "Rewrite every bullet as IF Description contains X THEN category Y" (or IF Amount < 0 THEN …) until they pass.
5

Save to the sheet and package next month’s prompt

Put taxonomy + addendum in a Master tab and fill Category so the workflow is repeatable.

Google SheetsFreeOpen Google Sheets
Exact action

In your spreadsheet, add a tab named Master. Paste into Master: - Your final taxonomy table - The full RULES_ADDENDUM from step 4 - Any disambiguation lines from step 2 that must never drift Back on the Import tab, fill the Category column using Claude’s Suggested_category output. Use Paste special → values only (avoid fragile live links). In Master, add a cell labeled Next_month_starter_prompt and paste a short template you will reuse, for example: "Apply ONLY the taxonomy + RULES_ADDENDUM on the Master tab to the new rows I paste below." Optional: Duplicate Import to a tab Template, delete the data rows, and keep headers for future months.

A new person could categorize next month’s CSV using Master + Next_month_starter_prompt without re-deriving categories from scratch.
Rules exist only in Claude chat history with no Master tab. Create Master now or you will redo step 2 next month.

All done!

You now have: A categorized month of transactions in a spreadsheet, plus a saved category rules block and a reusable Claude prompt so the next import takes minutes, not hours.

Explore more guides

Want this workflow built for your business?

Book a free audit