receipt2actual
Pair a receipt to the transaction it paid for in Actual Budget, on your own machine. The file goes into a folder you own, filed by the month it settled, and the transaction's note gets the path. In the desktop app, click the note and Finder or Explorer opens with the receipt selected. Nothing is uploaded anywhere.
The problem
Actual has no attachment field. "Upload attachment support for transactions" was asked for in January 2023, collected over two hundred thumbs-up, and was closed by a bot four months later for lack of activity. People are still asking in 2026. So the receipt that proves a transaction lives on a phone, in an email, or in a scanner folder, and at audit time you go looking for it by hand.
How it works
receipt2actual finds the transaction three ways. Name the file AMOUNT_YYYY-MM-DD_anything.pdf and it pairs with no reading of the file at all. Hand it a PDF receipt with a readable total and date and it reads them off the page. Anything else, or two transactions that both fit, gets you a numbered list to pick from. Then it copies the file into the vault and appends the path to the note, after anything you already wrote there.
receipt2actual add 45.23_2026-09-01_costco.pdf
receipt2actual add IMG_20260901_scan.pdf
receipt2actual pair receipt.jpg
receipt2actual show costco # opens the paired file in your OS viewer
The vault is a plain folder, ~/ActualReceipts by default, laid out YYYY/MM/<transaction>__<filename>, with an append-only index beside the files. Your budget is reached through Actual's own API and the only field it ever writes is the note. Amount, payee, date, category and cleared status are left exactly as Actual has them.
The audit
Every pairing is a claim: this file is this transaction's receipt. verify checks the claim in both directions, every file against its transaction and every transaction against its file, and exits non-zero the moment anything does not hold: a file deleted by hand, a transaction removed from the budget, a note edited, a file whose bytes changed, a stray file nobody paired. A cron job can gate on the exit code alone.
receipt2actual verify
12/12 pairings ok, 0 orphan(s)
What it will not do
No OCR: a scanned image with no text layer is refused, not guessed at. The note carries an absolute path, so a budget lives with one machine; move the vault or the machine and relink rewrites every marker, then runs verify so you know it lined up.
Get it
Clone the repository. Node 22.13 or newer, MIT licensed, tests included, runs on Windows, Linux and macOS. Found a receipt it read wrong or a transaction it missed? Open an issue.