Hey all,
Im sure some of you might remember the Flux integration Monzo had, and then a few receipt web apps spawned from this, however nothing was self hosted from what I could find.
I ended up building a small self-hosted app that fills that gap for me. It runs in the background, scans Gmail for receipt/order confirmation emails, and matches them to the corresponding Monzo transaction. It can then use OpenRouter to generate receipt data, and then submits the line items through the Monzo Receipts API so they show up natively in the app.
A few things I tried to get right:
-
It only auto-submits when itās confident in the match. Anything ambiguous gets queued for manual review so you can approve or skip it yourself
-
For anything it canāt match automatically, thereās a manual match flow - paste a Gmail URL, it parses the receipt, and you pick the transaction yourself
-
It parses email body content but also handles attached invoices and PDFs, so it works for things like utility bills or SaaS subscriptions that send a PDF rather than a formatted email
-
Where a receipt doesnāt already exist as a PDF, it generates one from the parsed data ā so thereās always something attached to the transaction
-
It handles multiple Gmail accounts and multiple Monzo accounts
-
You can run it on a schedule (I have mine run every evening) or trigger it manually
-
Notifications via Apprise (Slack, Discord, ntfy, etc.) so you know when itās done
Itās running fine for me but Iām sure there are edge cases I havenāt hit yet - different email formats, merchants I donāt shop at, that kind of thing. Iād genuinely love to know if it works (or doesnāt work) for other people.
Itās all open source if anyone wants to try it or poke around the code: GitHub - greghesp/monzo-receipts: Automatically match Monzo transactions to Gmail receipts using OAuth ā self-hosted with Docker Ā· GitHub
Docker image is on Docker Hub so it should be straightforward to spin up if you already run a home server or NAS. Happy to help if you get stuck.
Full disclaimer: Whilst I can code, I originally made this work within Claude Cowork as a scheduled job. As things got more complex, I gave Claude Code my Skill.md file and let it run with it using Superpowers
