FlowParse
Guide September 2026 22 min read

How to embed receipt OCR in an expense app

Eight steps to add receipt and statement recognition to an expense-management app — from a first build-vs-buy decision to a monitored production integration.

FlowParse
flowparse.io

What this guide covers, and what it doesn't

This is a practical, step-by-step integration guide for a product or engineering team adding receipt (and, usually alongside it, card-statement) recognition to an expense-management or spend-platform application. It assumes you've already decided the general shape of the product — this is about the extraction layer underneath it, not the approval workflow, reimbursement logic or general-ledger export that sit on top.

It doesn't cover building your own OCR model — that's a different, much larger project, and the cost comparison in step 1 and the linked blog post at the end of this guide go into why most teams at this stage choose not to. What follows assumes you're integrating an extraction API, specifically FlowParse's, though most of the structural advice — the review path, the matching step, the monitoring habit — applies regardless of which vendor you choose.

What you need before starting

Nothing exotic. A working expense-report or expense-line data model already in your product (even a simple one), a sample of real historical receipts — ideally including some rough phone photos, not just clean scans — and someone with the authority to sign off on a per-page cost line once the budget math in step 1 is done. No data-science background is required on your side; the extraction and structuring work happens entirely on the API side of the integration.

If your platform also handles card or bank statements, pulling together a sample of a few real statement PDFs at this stage saves a step later, since step 6 covers extending the same integration to cover them.

1

Decide build vs. buy, honestly

Before any integration work starts, put a real number on both sides. A first-year in-house build — labeled training data, engineering time, a review UI, and the first year of ongoing model maintenance — commonly lands in a $120,000–$160,000 range, not counting the opportunity cost of the engineering time spent on OCR instead of your product's actual differentiators. Against that, a flat €0.035 per page has a knowable monthly cost at any volume, worked through concretely in step 3 of this guide and in the API overview's cost section.

This decision is easiest to make honestly when it's framed as opportunity cost, not just direct spend: what else could the engineering team building and maintaining an in-house OCR pipeline be building instead, for a product whose actual value proposition probably isn't "we wrote our own receipt parser".

Write the comparison down as an actual short document, with the real numbers, shared with whoever needs to sign off. Teams that skip this and integrate first tend to revisit the same debate informally two or three times over the following months; teams that settle it explicitly at the start generally don't.

FlowParse
flowparse.io
2

Get a key and test against real receipts

A free plan API key processes real documents at full accuracy against a smaller monthly allowance — there's no separate "demo mode" with different results than production. Before writing any integration code, pull a representative sample of your own historical receipts — a mix of clean scans and rough phone photos, several currencies if your users are international — and run them through POST /extract directly.

a minimal test call
curl -X POST https://flowparse.io/api/v1/extract \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@receipt.jpg"

Compare the returned fields against what you already know about each receipt. This step exists specifically to build confidence in accuracy on your own real document mix before any engineering commitment is made to the integration itself.

FlowParse
flowparse.io
3

Map the response to your data model

Most expense platforms already have a data model for an expense line — amount, date, merchant, category, currency. Mapping merchant_name, total, date, currency and line_items onto that existing schema is usually the fastest part of this whole integration — often under a day for a team already familiar with their own schema.

API fieldTypical expense-record field
merchant_namevendor
totalamount
dateexpense_date
currencycurrency_code
line_items[]expense_line_items[] (new, if not already modeled)
4

Design the capture flow around real receipts

Most receipts entering an expense app are phone photos, not scans — angled, sometimes shadowed, on paper that curls or has already started to fade. Rather than assuming an idealized flatbed-scan input, design the capture UI to nudge good-enough photos (flat surface, decent light, whole receipt in frame) without demanding scanner-quality input the extraction pipeline doesn't actually need.

FlowParse
flowparse.io
5

Build the low-confidence review path

Every extraction returns a confidence signal alongside the data. The single most common integration mistake — covered in more depth in the mistakes section below — is skipping a review path and trusting every result equally. Instead, route only results below a threshold you choose to a quick human-confirmation step, leaving the large majority of clean extractions fully automatic.

1

Set an initial confidence threshold

Start conservative — route more to review than you expect to need, and loosen it as you build confidence in production accuracy.

2

Build a lightweight confirmation UI

Show the extracted fields next to the receipt image, letting a user correct a field in seconds rather than re-entering the whole receipt.

3

Log corrections

A field that's frequently corrected on a particular receipt format is a signal worth tracking, even without retraining anything on your side.

6

Wire up statement extraction and matching

Once receipt extraction is stable, most platforms add card or bank statement extraction next — turning a monthly statement PDF into transaction rows, then matching each submitted receipt to the transaction it explains. The feature page on line-item matching covers the matching logic in detail; this step is about sequencing it correctly after receipts are already working well.

Sequencing matters here more than it might seem. Statement extraction shares the same POST /extractendpoint as receipts, so there's no separate API surface to learn — the work in this step is almost entirely the matching logic on your own side: comparing amount, date and merchant name between a receipt and each candidate transaction, and deciding what confidence level counts as a reliable automatic match versus one that needs a quick human confirmation. Building that logic against receipt data you already trust, rather than debugging two new pipelines simultaneously, is why this step consistently goes faster as step 6 than it would if statements and receipts were built together from day one.

FlowParse
flowparse.io
flowparse.iono audio needed
0:00 / 0:00
7

Handle multi-currency and multi-language receipts

For a platform with an international user base, currency and language handling isn't optional from day one. The API returns the currency and totals exactly as printed on the receipt — a hotel folio in euros stays in euros — leaving conversion to a reporting currency to your own exchange-rate logic, applied at whatever point in your workflow makes sense (submission time, approval time, or export time, depending on how your platform already handles multi-currency expenses).

FlowParse
flowparse.io
8

Monitor accuracy and spend in production

Launch isn't the end of this integration. Two things are worth tracking on an ongoing basis: the rate of low-confidence flags over time (a rising rate can indicate a new receipt format your review process hasn't adapted to), and actual monthly spend against the budget built in step 1, readable directly from GET /usage.

A simple weekly or monthly internal dashboard — total pages processed, current spend, low-confidence rate — is usually enough; this doesn't need a dedicated observability system, just a habit of actually looking at the numbers rather than assuming the integration keeps working exactly as it did on launch day.

FlowParse
flowparse.io

Who should own each step internally

Steps 1 and 8 — the cost decision and ongoing monitoring — are naturally shared between engineering and finance, since one estimates and builds while the other approves and tracks the resulting budget line. Steps 2 through 6, the actual integration work, sit squarely with engineering and usually don't need product or design input beyond reviewing the capture-flow and review-UI mockups that come out of steps 4 and 5. Step 7's currency handling is worth a quick check-in with whoever owns your platform's existing multi-currency logic, if you have any, so the two systems agree on conversion timing and source.

For a small team, one engineer can realistically own the whole integration end to end — nothing here requires a dedicated project manager or a cross-functional working group, which is itself part of why this integration is faster than most teams expect going in.

A note on data residency and regulatory requirements

An expense platform serving customers in regulated industries or specific jurisdictions sometimes has data-residency or processing-location requirements that need confirming before any document leaves your own infrastructure. This is worth checking early — during step 1's evaluation, not after a production integration is already built — by reviewing the current data-handling and infrastructure details on the security pageagainst your own compliance requirements or your customers' specific contractual terms.

For most expense-management use cases this isn't a blocker, but for a platform selling into specific regulated sectors, it's the kind of question worth a five-minute check before writing any integration code rather than discovering an issue during a customer's security review much later.

A full worked integration, start to finish

A five-person team at a mid-stage spend-platform startup, currently doing manual receipt entry for 600 active users, decides to automate. Volume estimate: 15 receipts/user/month at roughly 1 page each, plus one 3-page statement per user per month.

WeekWork done
Week 1Steps 1–3: cost model approved, key issued, 50 historical receipts tested, schema mapped
Week 2Steps 4–5: capture flow updated, low-confidence review UI shipped behind a flag
Week 3Step 6: statement extraction and matching added, tested against a full monthly cycle
Week 4Steps 7–8: currency handling confirmed for EU/UK users, monitoring dashboard wired to GET /usage, full rollout

Estimated monthly cost at this volume: 600 × 15 × 1 = 9,000 receipt pages plus 600 × 3 = 1,800 statement pages, 10,800 pages total, roughly €378 a month — against the engineering time previously spent on manual review and correction, this typically pays for itself well inside the first month.

By the end of week 4, the team has replaced a fully manual process with one that only routes genuinely ambiguous cases to a human — commonly somewhere in the low single-digit percentage of total volume, depending on the mix of scan quality and receipt formats in a given user base. The remaining manual work is a fraction of what it was, and it's concentrated on the cases that actually need judgment rather than spread evenly across every single receipt submitted.

Put in ROI terms this team could take to their own finance lead: four engineering-weeks and roughly €378 a month in extraction cost replaced a process that was previously consuming several hours a week of manual receipt review across the finance-ops function, with the automated version scaling to ten times the user base without a proportional increase in either the engineering maintenance burden or the review workload — the same shape of payback most teams following this guide report, whether their starting volume is a few hundred receipts a month or several hundred thousand.

Questions worth asking any vendor, not just FlowParse

Whichever extraction API a team ultimately picks, the same handful of questions separate a vendor evaluation that catches a problem before signing from one that discovers it three months into production. Worth asking directly, in writing, rather than assuming a favourable default answer:

QuestionWhy it matters
Is pricing flat, or does it change by document complexity or plan tier?A tiered or complexity-based rate reintroduces exactly the cost-forecasting uncertainty step 1's budget comparison was meant to remove.
Are receipts and statements one endpoint, or separate products?A separate product per document type usually means separate pricing, separate SDKs and separate accuracy characteristics to evaluate.
What happens to a document after it's processed?A vendor's data-retention and deletion policy is worth confirming explicitly, not assumed — see the security section on the core API page.
Is there a free tier that uses production-grade accuracy?A demo mode with different accuracy than production tells you nothing useful about how the vendor will actually perform.
What does a confidence signal actually mean, concretely?A vague 'confidence score' with no documented meaning is much harder to build a reliable review-routing threshold around.

Running this list against more than one vendor, even briefly, is worth the extra half-day it takes — a comparison written down with real answers is a much stronger basis for step 1's decision document than a single vendor's own marketing claims taken at face value. FlowParse's own answers to these five questions are covered directly on the core API overview, the flat-rate pricing page, and the security page.

API versioning, uptime and what happens during an outage

A production integration depends on the extraction API being available and its response shape staying stable over time — two operational questions worth settling before launch, not discovered during an incident. On versioning: a response schema that can change without notice forces a defensive parsing layer on your side just to stay safe; confirm the vendor's policy on breaking changes and whether new optional fields are ever added without warning (generally fine to ignore gracefully) versus existing fields changing shape (generally not, and worth an advance-notice commitment). FlowParse's current field schema is documented in full on the API documentation page, which is the canonical source to check against rather than relying on a copy pasted into your own internal wiki.

On availability: because this integration is typically called synchronously from a user-facing capture flow, a brief outage or elevated latency shouldn't block the user entirely. Queueing the document and letting the user continue — the same pattern mentioned in the FAQ below — is the standard defensive design, and it's worth building that queue path from the start rather than retrofitting it after the first real outage makes the gap obvious.

FlowParse
flowparse.io

Common mistakes in this integration

Skipping the low-confidence review path entirely

Trusting every extraction equally means the rare genuinely wrong result reaches a general ledger unreviewed — a small percentage of cases, but the ones worth catching.

Hardcoding the per-page rate instead of reading it live

If the published rate is ever revised, an integration reading a hardcoded constant silently miscalculates its own cost forecasts.

Assuming every receipt itemises

A taxi or parking receipt often has no line items at all — treat an empty line_items array as normal, not an extraction failure.

Building statement matching before receipt extraction is stable

Matching logic is much easier to debug once you're confident the receipt data feeding it is already accurate.

Not testing on your own worst-case receipts

A clean sample of scans tests the easy case; a handful of your ugliest real phone-photo receipts tests what production will actually look like.

FlowParse
flowparse.io

Best practices for a durable integration

Read the price object live, don't hardcode the rate

Every response carries its own exact cost — summing it is more robust than a hardcoded constant that can drift out of date.

Roll out behind a flag to a small user cohort first

Confirms real-world accuracy and UX before every user's receipts flow through the new path.

Keep the manual-entry fallback available indefinitely

A tiny fraction of receipts will always need it — removing the fallback entirely just moves that friction somewhere worse.

Review the low-confidence rate monthly, not just at launch

A drift upward is an early signal worth investigating before it becomes a larger data-quality problem.

How long each step takes

StepTypical time
1–2: Decision + first test1–2 days
3: Schema mappingLess than a day
4–5: Capture flow + review UI3–5 days
6: Statement matching3–5 days
7–8: Currency handling + monitoring2–3 days

A printable checklist

Real build-vs-buy cost comparison approved

API key issued, tested against a real historical-receipt sample

Response fields mapped to the existing expense-record schema

Capture flow tested against rough, real phone-photo receipts

Low-confidence review UI built and behind a rollout flag

Statement extraction and matching wired up

Multi-currency handling confirmed for every supported region

GET /usage wired into an internal spend-monitoring dashboard

Building the spend-monitoring dashboard in step 8

A minimal version of this dashboard needs only three numbers, pulled from GET /usage on whatever cadence you check it: pages processed this month, spend this month, and how both compare to the budget from step 1. Most teams start with a scheduled script that posts this to an internal Slack channel weekly, which is enough to catch a meaningful drift without building a dedicated internal tool.

A slightly more useful version also tracks the low-confidence rate over time, since that number tends to move before the cost number does — a rising rate of flagged receipts is often the first sign of a new receipt format or a data-quality issue, arriving weeks before it would show up as an unexpected cost change.

a minimal weekly usage check
curl -s https://flowparse.io/api/v1/usage \
  -H "Authorization: Bearer YOUR_API_KEY" \
  | jq '.thisMonth'

Doing this with a team of one versus a team of five

A solo engineer can realistically complete steps 1 through 8 in the timeline given in the time section above, sequentially, without help — nothing here requires specialized skills beyond regular backend engineering. A larger team mostly gains speed through parallelism rather than through needing more hands per step: one person on steps 1–3, another on the capture-flow and review UI in steps 4–5, and a third on statement matching in step 6, converging in steps 7–8.

What doesn't compress well regardless of team size is step 2's accuracy validation — it's deliberately a slow, careful step, since every later step's design decisions depend on trusting its result. Rushing it to hit a team-of-five timeline is the most common way this integration goes wrong even with adequate headcount.

FlowParse
flowparse.io

Who this guide is for

Product and engineering teams at an expense-management, spend-platform or procurement SaaS company adding or replacing receipt-and-statement recognition — whether this is the first version of the capability or a migration off an existing vendor.

Scaling from a pilot to full production volume

Nothing about this integration changes structurally between a 600-user pilot and a 100,000-user production rollout — the flat per-page rate and the same API surface apply at any volume. What does change is the value of the monitoring built in step 8: at higher volume, a small percentage low-confidence rate represents a much larger absolute number of receipts, making the review-queue capacity worth revisiting as usage grows.

One thing genuinely does need revisiting at scale that doesn't at a pilot: the review-queue staffing itself. A 2% low-confidence rate on 600 receipts a month is roughly 12 documents someone glances at; the same 2% rate on 100,000 receipts a month is 2,000 documents, which needs an actual staffed process rather than an engineer checking a queue between other work. Planning for that transition before volume forces it is the main structural change scale introduces.

A short glossary

Confidence signal

A per-extraction indicator of how certain the result is, used to route low-confidence cases to review.

Line item

One individual entry printed on a receipt — description, quantity, price — as distinct from the receipt total.

Matching

Connecting a submitted receipt to the statement transaction it corresponds to.

Reconciliation check

Confirming a document's own printed numbers are internally consistent before returning a result.

One habit worth keeping after launch

Revisit the low-confidence rate and the actual monthly spend once a month, even after the integration feels finished. Both numbers are cheap to check and are the earliest signal that something in your receipt mix — a new merchant format, a new region, a volume spike — has changed since launch.

Teams that keep this habit consistently report catching issues within days rather than discovering them weeks later through an unrelated complaint or a finance-team question about a number that doesn't look right — the small ongoing cost of checking two numbers a month is considerably cheaper than any of the alternatives.

Frequently asked questions

Start step 1 today

Get a free API key and run your own historical receipts through it before writing any integration code.

Keep reading