What this automation does
The reviewer reads every line so your managers only read the lines that matter.
- Collect. When a report is submitted in Expensify, Ramp or Brex, or when an employee drops a spreadsheet and receipt images into a shared folder, the workflow pulls the report and every receipt.
- Read the receipts. A vision model extracts merchant, date, total, tax, tip, currency and, for itemized receipts, the line items. It also notes whether the image is an itemized receipt or only a card slip.
- Check the hard rules in code. Missing receipts above your threshold, amounts that differ from the receipt, dates outside the trip, meals above the daily cap, mileage claims longer than a mapped route, and the same receipt submitted twice, including by two different employees.
- Check the soft rules with the policy. For lines that pass the hard rules but look unusual, the model compares the line with the numbered policy clauses and returns clean, flag or question, plus the clause it relied on.
- Route. Clean reports go to the manager as ready to approve. Flagged reports go with each flagged line, the receipt image, the reason and the quoted clause, in Slack or email.
- Learn from decisions. Every manager override is logged, so you can see which flags are noise and which policy clauses keep causing confusion.
When it is worth building
It pays off when finance or managers spend real time on reports and still miss things. Typical triggers are a monthly close that waits on expense approvals, managers who approve without opening receipts, or a duplicate or personal expense found months later during an audit.
If your company is small and everyone uses one expense tool with policy rules already switched on, start there. This build is worth it when the policy contains judgment calls such as “client entertainment must have a business purpose and attendee list”, when spend arrives through several cards or tools, or when you want one consistent reviewer across teams with different managers. If the bigger problem is simply collecting receipts at all, start with receipt capture and categorization instead.
Architecture
| Layer | What we use | Why |
|---|---|---|
| Intake | Expensify, Ramp or Brex APIs through n8n’s HTTP Request node, or a Google Drive folder plus a submission sheet | Meets reports where employees already submit them |
| Receipt reading | OpenAI’s GPT models or Claude through the API, with vision input | Reads photos, PDFs and screenshots without a template per merchant |
| Hard rules | A code step with a limits table finance can edit | Caps, dates and arithmetic must be exact and repeatable |
| Duplicate detection | Image hash plus a fuzzy key of merchant, date and amount, stored in Postgres | Catches the same dinner claimed by two people, which single-report tools often miss |
| Policy check | An LLM call with numbered policy clauses and a required citation field | Handles the gray areas while staying tied to written policy |
| Review surface | Slack direct messages or an email digest per manager | Managers see only what needs judgment, with evidence attached |
How to build it
- Turn the policy into two lists. Rules a computer can check exactly (meal cap, receipt threshold, mileage rate, no alcohol on solo meals) go into a limits table. Everything else stays in the numbered policy text for the model.
- Build the receipt schema. Define the fields you need, including receipt type and currency. Test on fifty real receipts, including crumpled, rotated and foreign ones, before writing any routing.
- Write the hard checks. Implement them as small functions that return a reason code, so every flag is explainable without the model.
- Add duplicate detection across employees. Store a perceptual hash of every receipt image and a normalized merchant, date and amount key. Check both against the full history, not just the current report.
- Add the policy check. Send only the lines that passed hard checks but match a risk pattern, such as weekend dates, round amounts or high-risk categories. Require a clause citation in the structured output, and treat missing citations as clean.
- Design the manager message. One line per flagged item with the receipt thumbnail, the reason and the clause. Approve all, approve with exceptions, and send back should each be one click.
- Shadow first. Run for one full expense cycle alongside the current process and compare flags to what finance actually caught by hand.
The downloadable starter template below includes the receipt extraction, the hard-rule check step and the Slack manager summary as a starting point.
What breaks in production
- Card slips without items. A card slip proves payment but not what was bought. Treat it as a soft flag for meals and entertainment, and ask the employee for the itemized receipt rather than rejecting.
- Tips and adjustments. The card charge is higher than the printed receipt because of a handwritten tip. Allow a configurable tip band before flagging an amount mismatch.
- Foreign currency. The receipt is in euros, the card charge is in dollars and the rates differ by date. Compare using the card’s converted amount and allow a small tolerance.
- Threshold gaming. Over time, more receipts land just under the receipt threshold. Track the distribution per employee and surface outliers to finance, not managers.
- Group meals. One person pays for six. Without an attendee list, per-person caps cannot be checked. Make attendees a required field for the category.
- Policy drift. Finance updates the policy PDF but nobody updates the clause file. Version the clause file and show the version in every flag.
Timeline and cost
A setup for one expense tool and one policy typically takes two to four weeks, including one shadow cycle. Lumeor builds it for $5,000 to $12,000, depending on the number of intake sources, how much of the policy is judgment versus hard rules, and whether you need multi-entity or multi-currency handling. Model usage scales with receipt volume and is usually modest, since only flagged lines get the longer policy call. For the trade-offs between model providers on vision and structured output, see OpenAI API vs Claude API. The extraction techniques here overlap with the general document data extraction guide.
How to measure success
- Manager minutes per report, before and after
- Share of reports that arrive marked clean and are approved without edits
- Flags overturned by managers, by reason code, which tells you which rules are noise
- Out-of-policy dollars caught per month, including cross-employee duplicates
- Days from submission to reimbursement
- Reports sent back for missing receipts, trending down as employees adapt