Categories Configuration
The file config/categories.yaml defines spending categories, auto-categorisation rules, and tag rules. Copy from the example:
cp config/categories.yaml.example config/categories.yamlThe file has three sections: categories, rules, and tag_rules.
Categories
Define all spending and income categories:
categories: # Income - name: Salary is_income: true - name: Interest Income is_income: true
# Expenses with optional monthly budgets - name: Groceries budget_monthly: 600 - name: Eating Out budget_monthly: 300 - name: Utilities budget_monthly: 300
# Business (ATO deductible) - name: "Business: Hosting & Infrastructure" - name: "Business: Software & Subscriptions"
# Financial - name: Transfers - name: UncategorizedCategory fields
| Field | Required | Description |
|---|---|---|
name | Yes | Unique category name |
is_income | No | Set true for income categories |
budget_monthly | No | Monthly budget amount for the budget tracker |
Naming convention: Categories starting with Business: are automatically allocated at 100% to your business in the split engine. Categories starting with Rental: are for rental property expenses.
Rules
Rules assign categories to transactions automatically. They are matched top-to-bottom and first match wins.
Rule types
Source-based rules match all transactions from a source:
rules: - type: source source_type: airbnb category: Airbnb IncomeRegex rules match against the transaction description:
- type: regex pattern: "WOOLWORTHS|COLES |ALDI |IGA |HARRIS FARM|COSTCO" category: GroceriesPatterns are matched case-insensitively against the uppercase description.
Rule ordering matters
Rules are evaluated top-to-bottom. Put specific patterns before generic ones:
rules: # Specific: credit card interest (before mortgage interest) - type: regex pattern: "INTEREST CHARGED" category: Fees & Charges
# Generic: mortgage interest - type: regex pattern: "INTEREST CHARGE" category: MortgageBusiness rules should go near the top so they match before personal categories:
rules: # Business hosting (matched first) - type: regex pattern: "NAMECHEAP|DIGITAL ?OCEAN|CLOUDFLARE|AWS" category: "Business: Hosting & Infrastructure"
# Business software - type: regex pattern: "GITHUB|FIGMA|ADOBE|OPENAI|ANTHROPIC" category: "Business: Software & Subscriptions"
# Personal shopping (matched later) - type: regex pattern: "AMAZON|EBAY" category: ShoppingAdding a new merchant
To add a merchant, append a regex rule. If the merchant name appears differently across banks, use alternation:
- type: regex pattern: "UBER ?EATS|DOORDASH|MENULOG|DELIVEROO" category: Eating OutTips for writing patterns:
- Use
|to match multiple merchants in one rule - Use
\\bfor word boundaries when a pattern is too broad - Use
^to anchor at the start of the description - Use
\\dto match digits (e.g.7-ELEVEN \\d) - Use
\\.to match a literal dot (e.g.APPLE\\.COM) - Spaces matter:
"COLES "(with trailing space) avoids matching “COLESLAW”
Confidence levels
The categoriser assigns a confidence score:
| Match type | Confidence |
|---|---|
| Source-based rule | 1.0 |
| Exact match | 0.9 |
| Regex match | 0.8 |
| Learned (from manual override) | 0.7 |
| Uncategorized | 0.0 |
Tag rules
Tags are orthogonal to categories — a transaction has one category but can have many tags. Tags enable sub-classification for reporting.
tag_rules: # Transport sub-types - tag: flight pattern: "JETSTAR|QANTAS|VIRGIN AUSTRALIA" - tag: taxi pattern: "UBER TRIP|UBER AUSTRALIA|TAXI" - tag: train pattern: "OPAL|TRANSPORTFORNSW"
# Insurance sub-types - tag: health-insurance pattern: "MEDIBANK|AMBULANCE"
# Business sub-types (for ATO detail) - tag: biz-hosting pattern: "NAMECHEAP|DIGITAL ?OCEAN|CLOUDFLARE|AWS" - tag: biz-software pattern: "GITHUB|FIGMA|ADOBE"
# Utility sub-types - tag: internet pattern: "TPG" - tag: mobile pattern: "OPTUS|VODAFONE"Tags are used by the business split engine to determine which portion of a bill is business-deductible (e.g. 50% of the internet-tagged utility bill).
Tag rule fields
| Field | Required | Description |
|---|---|---|
tag | Yes | Tag name (lowercase, hyphenated) |
pattern | Yes | Regex pattern matched against description |
source_type | No | Only match transactions from this source |
Learned rules
When you manually change a transaction’s category in the dashboard, the system stores the description-to-category mapping in the category_rules_learned database table. Next time a transaction with the same description appears, it will be auto-categorised with confidence 0.7.
After editing
Run ledger init to reload categories into the database:
ledger initTo re-categorise existing transactions with new rules, re-ingest the archived files or use the dashboard to update individual transactions.