Labnotes

Published

How Expense reads a receipt

How Expense reads a receipt

Every receipt that lands in Expense has to become four fields: merchant, date, amount, category. A model can do that. Model calls also cost money and seconds, so the pipeline is built around not making them. Most receipts never reach one.

Text comes first. An email body or a PDF text layer already carries the receipt as text, so there is nothing to read. Parse it.

Then the known-merchant skip. If you have bought from this merchant in the last 90 days and the total parses deterministically, both the 1,234.56 and the 1.234,56 conventions, the expense fills itself in from your own history: your category, your report. Zero tokens.

Then the cache. The same bytes uploaded again within a week, a retry, or the same receipt arriving through the web and through the MCP tool, return the stored result instead of recomputing it.

Whatever is left goes to a model, with a tight prompt and hard caps on the output. Images go to a vision model rather than local OCR, because it copes better with glare, skew, and photocopies. Tesseract only steps in when the provider itself errors.

The fun part is the logs. Skip lines and cache hits outnumber model calls by a wide margin, which is the whole point.

🔥 Looking for more? Subscribe to Weekend Reading.