A finance tracker that runs itself, every night, without me touching it.
Expenso ingests my bank alert emails, classifies every transaction, flags anomalies, and answers plain-English questions about my spending — automated end to end with a nightly job. Eliminated about 3 hours a week of manual finance tracking.
Watch it in action
A two-minute walkthrough of the dashboard, classification, and the natural-language query interface.
Inside the dashboard
Screenshots from the redesigned app — annual and monthly overviews with matched-period anomaly flagging, the daily spend trend, and the transactions feed.
The pipeline
Expenso connects to Gmail via OAuth2, pulls bank alert emails incrementally, and parses each one into a structured transaction — amount, date, direction, merchant, UPI reference. Only confirmed successful transactions are kept; failed or attempted ones are discarded. The whole thing is built to be re-run safely: every insert is idempotent, so a missed night just catches up automatically the next run, with zero duplicate or lost data across 9+ months of nightly runs since 1 December 2025.
Data quality, made visible
A dedicated pipeline-health page reports on the automation itself, not just the spending: messages waiting on extraction or classification, retryable processing failures, and a rolling count of candidate vs. accepted notifications from the last 7 days. If a bank alert can't be confidently parsed into a transaction, it isn't silently dropped or guessed at — it lands in a separate review queue instead, held there until a parser fix reprocesses it. This is distinct from spend classification (below): it's about whether a message could be turned into a transaction at all, not which category that transaction belongs to.
Classification that gets better on its own
Every transaction moves through three tiers before it's filed:
1 · Rule-based
Substring match against 74+ known merchant patterns. Instant, full confidence.
2 · LLM fallback
Unmatched merchants go to Claude Haiku, which returns a confidence score. Anything ≥0.9 is auto-promoted into a new rule for next time.
3 · Manual override
Anything still wrong gets corrected inline — and that correction is learned as a rule too, so the system never makes the same mistake twice.
Ask it anything about your spending
A natural-language query interface translates plain-English questions into SQL via Claude Haiku, runs them against PostgreSQL, and returns a formatted answer — including multi-step analytical queries using CTEs. Every generated query is validated before it runs: SELECT/WITH only, no DDL, capped at 50 rows, 8-second timeout.
- "What is my highest expense ever?"
- "Top 5 merchants last 90 days"
- "Which month did I spend the most?"
Design principles
Immutability — raw emails are never modified; every transaction is re-derivable from source. Idempotency — every insert uses ON CONFLICT logic, so re-running any phase is always safe. Self-healing — incremental ingestion means the pipeline recovers from a missed night without intervention. Honest about gaps — every view is labeled as captured from bank notifications, never presented as reconciled truth; missing coverage shows up as an explicit gap, not a silent zero. A macOS launchd job runs the full cycle every night at 00:01.