Skip to main content

amagi-receipts-to-csv

Point it at a folder of receipt photos and PDFs and get one CSV back: date, vendor, subtotal, tax, tip, total and an expense category for every receipt. OCR runs on your own machine, so nothing is uploaded. It can also write a file that QuickBooks Online will take through Banking > Upload from file.

Built for freelancers and small-business bookkeepers who keep a shoebox (or a camera roll) of receipts and type them into a spreadsheet once a month.

amagi-receipts-to-csv reading five example receipts

Install

pipx install amagi-receipts-to-csv

Needs Python 3.10 or newer. The OCR models ship inside the rapidocr-onnxruntime package, so there is nothing else to set up and no API key.

Usage

The repo includes five made-up receipts in examples/receipts: two photos, one crumpled photo, one scanned PDF and one PDF with a real text layer.

amagi-receipts-to-csv examples/receipts
amagi-receipts-to-csv: 5 file(s) in examples\receipts
  ok     2026-10-07  Blue Fern Cafe                 23.50  Meals            blue_fern_cafe.jpg
  ok     2026-10-03  Corner Hardware & Supply       51.21  Supplies         corner_hardware.png
  check  2026-10-12  Harbor Street Parking          12.00  Parking & Tolls  crumpled_parking.jpg
         no subtotal line; subtotal is the sum of the item lines
         subtotal 11.86 looks misread; corrected to 11.06 so the receipt adds up
  ok     2026-09-28  Metro Office Supply           171.17  Office Supplies  metro_office_supply.pdf
  ok     2026-09-30  Quickfuel #118                 42.18  Fuel             quickfuel_scan.pdf
5 receipt(s): 4 ok, 1 to check. Sum of totals: 300.06
Wrote receipts.csv

receipts.csv has one row per receipt:

file,date,vendor,subtotal,tax,tip,fees,total,category,status,notes,source

A row is ok only when the date, vendor and total were all found and, if the receipt prints a subtotal, subtotal + tax + fees + tip equals the total. Everything else is check, and notes says what to look at. In the run above, OCR read the parking stub's subtotal as 11.86. The tool caught that 11.86 + 0.94 does not make 12.00, fixed the one digit that made the receipt add up, and still marked it for you to check.

source tells you how the text was read: text-layer for a PDF with real text (no OCR needed), or ocr:rapidocr / ocr:tesseract.

QuickBooks Online

amagi-receipts-to-csv examples/receipts -f qbo

This writes qbo_import.csv in the 3-column layout QuickBooks accepts for a bank upload, with each receipt as money going out:

Date,Description,Amount
10/07/2026,Blue Fern Cafe,-23.50
10/03/2026,Corner Hardware & Supply,-51.21
10/12/2026,Harbor Street Parking,-12.00
09/28/2026,Metro Office Supply,-171.17
09/30/2026,Quickfuel #118,-42.18

Use -f qbo4 if your bank account is set up for the 4-column Date, Description, Credit, Debit layout. Add --only-ok to leave out the receipts marked check until you have looked at them. Receipts with no date or no total are always left out of the QuickBooks file, and the CLI lists them.

Your own categories

The built-in categories are Meals, Fuel, Parking & Tolls, Office Supplies, Supplies, Travel, Software & Subscriptions, Postage & Shipping, Utilities & Phone and Groceries, picked by keyword. To use your own chart of accounts, pass a rules file. Your rules are tried before the built-in ones, and the vendors block cleans up names:

{
  "categories": {"Client Meals": ["blue fern"], "Vehicle": ["quickfuel"]},
  "vendors": {"sq *blue fern": "Blue Fern Cafe"}
}
amagi-receipts-to-csv receipts/ --rules rules.json

Add --no-builtin-categories to use only your list.

A local LLM for the hard ones

If you run Ollama, the tool can ask a local model about receipts where a field is missing or the amounts don't add up:

amagi-receipts-to-csv receipts/ --llm llama3.2

For LM Studio or llama.cpp, add --llm-api openai --llm-url http://localhost:1234. The model fills in missing fields, and it can replace an amount only when the receipt does not add up. Any amount or date it gives that is not printed on the receipt is thrown away, and the notes say so. The tool refuses to talk to a server that is not on your machine unless you pass --llm-allow-remote.

Options

  -o, --output OUTPUT   output file, or - for stdout (default depends on --format)
  -f, --format {csv,qbo,qbo4,json}
  -r, --recursive       look in subfolders too
  --ocr {auto,rapidocr,tesseract}
                        OCR engine: rapidocr (bundled), tesseract (if installed), auto
  --day-first           read 03/10/2026 as 3 October, not March 10
  --rules RULES         JSON file with your own categories and vendor renames
  --no-builtin-categories
                        use only the categories in --rules
  --only-ok             leave receipts marked 'check' out of the output
  --text-dir TEXT_DIR   also save the OCR text of each receipt here, for review
  --llm MODEL           ask a local model (e.g. llama3.2) about receipts the rules could not finish
  --llm-url LLM_URL     LLM server URL. Default: http://localhost:11434 (Ollama)
  --llm-api {ollama,openai}
  --llm-allow-remote    allow an LLM server that is not on localhost
  -q, --quiet           print only the output path

It reads .jpg, .png, .webp, .tif, .bmp, .gif and .pdf. iPhone .heic photos work after pipx inject amagi-receipts-to-csv pillow-heif.

Exit codes: 0 means the run finished (even if some receipts need checking). 1 means it could not run: missing path, no receipt files, bad rules file, no OCR engine, or an LLM server that is not local. 2 means a bad option.

How accurate is it?

On the five example receipts every field matches the expected values, and the test suite checks that with the real OCR engine. Made-up receipts are the easy case, though, so we also scored it on 13 real receipt photos from Wikimedia Commons, labelled by hand. Four of them have no fair answer (out of focus, a blank guest check, a slip with no printed total, a coin-counting voucher). On the other nine:

Field Right
Date 6 of 6 labelled
Vendor 4 of 8 labelled
Total 6 of 7 labelled

Four of the 13 photos came back ok, and all four were right on every labelled field. Every miss landed on a check row. Four is a small sample, so look over your first batch closely.

To re-run the benchmark yourself (it downloads the photos once, with credits):

python bench/run_commons.py

Limits

  • Crumpled, faded, blurry and handwritten receipts lose fields. The tool marks them check instead of guessing, and the add-up check flags a misread amount, but a wrong vendor name can still come through on an ok row. Vendor is the weakest field (4 of 8 in the test above).
  • A date with no year ("07/23") is left blank.
  • One currency per receipt and no currency column. Totals are added up as plain numbers.
  • Categories come from keywords. Expect to fix some, or write a rules file.
  • Speed on a plain CPU (no GPU): the OCR model takes about 2 seconds to load, then about 2 to 6 seconds per photo. PDFs with a text layer skip OCR.

Use it from Claude Code

The repo ships a SKILL.md. Copy it to ~/.claude/skills/amagi-receipts-to-csv/SKILL.md and Claude Code will run amagi-receipts-to-csv when you ask it to put a folder of receipts in a spreadsheet or get them into QuickBooks.

Star it if it saved you an evening

If amagi-receipts-to-csv got you out of a month of typing receipts into a spreadsheet, a star helps other freelancers and bookkeepers find it. Bug reports with the OCR text of a receipt it got wrong (--text-dir saves it) are the most useful thing you can send.

Other AmagiLabs projects

  • amagilabs on GitHub: the full catalog of small open-source tools from AmagiLabs (Amagisolutionsgroup, Inc.).
  • amagi-watch: turns a video URL into something Claude can read (transcript, key frames and a timestamped index).
  • amagi-legal-review-skills: Claude Code skills for contract and lease review.

Development

pip install -e ".[dev]"
pytest

python tests/make_fixtures.py rebuilds the example receipts. The tests run the real RapidOCR engine on them; the Tesseract test is skipped if Tesseract is not installed.

License

MIT. See LICENSE. Copyright (c) 2026 Amagisolutionsgroup, Inc. (AmagiLabs).

Metadata

Release files for amagi-receipts-to-csv 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for amagi-receipts-to-csv 0.1.0
File Size Uploaded Provenance
amagi_receipts_to_csv-0.1.0.tar.gz 35.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for amagi-receipts-to-csv 0.1.0
File Interpreter ABI Platform
amagi_receipts_to_csv-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 63.4 kB

Release files / amagi_receipts_to_csv-0.1.0.tar.gz

Download URL amagi_receipts_to_csv-0.1.0.tar.gz
Size 35.3 kB
Tags Source
SHA-256 checksum
How to use checksums
272b7cde0276649d0f34213059cbeae969f15ac9c974ee2cf6bb21c8a5d460b1
BLAKE2b-256 checksum
How to use checksums
98da7e98aba667b171ed55f99f61cc45bffc079d30d38e14d89aaf6a2025b25b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.4

Release files / amagi_receipts_to_csv-0.1.0-py3-none-any.whl

Download URL amagi_receipts_to_csv-0.1.0-py3-none-any.whl
Size 28.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a3ea098df7a11154f6e0e7124e9eaf0e417bbf16c335bee44dd8500ee4605388
BLAKE2b-256 checksum
How to use checksums
598dd1076682e49326756c10e89318bbfe10559a5809f810ec96425b70a47368
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.4

Security for amagi-receipts-to-csv 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page