Invoice Scanning: Turning Receipt Photos into Processable Documents
Accounts payable works on paper that arrives as photos: a receipt photographed under a desk lamp, an invoice scanned with a phone at a supplier's office, a delivery note captured in a truck cab. Every one of those photos is supposed to become an accounting record — and most of them fail quietly.
Invoice processing systems, OCR, and extraction tools are trained on clean, flat, well-lit documents. A photo of an invoice is not that: it has perspective distortion, shadows, glare, and background clutter. The result is misread amounts, wrong vendor names, and invoices that need manual re-entry.
The failure is in the capture, not the extraction
When an invoice photo fails to parse, the usual suspect is the extraction tool. In most cases the tool is fine — the input was not. Consider what a phone photo does to an invoice:
- Perspective — photographed at an angle, so the edges converge and text lines drift
- Shadows — the invoice half-covered by a shadow, washing out numbers near the edge
- Glare — reflections from a glossy surface or a window behind the photographer
- Curvature — a folded or bound document that bends in the middle
- Background — the desk, hands, or other objects in the frame
Any one of these can make a line item unreadable. €1,204.50 becomes €1,204, ACME Logistics becomes ACME Log1st1cs, and the invoice gets flagged for manual review or re-entered by hand.
The scan step: one call before extraction
A scanning API fixes the document before the extraction step ever sees it:
Invoice photo → scan API → clean, flat invoice → OCR / extraction → accounting system
The scan step does not read the invoice. It makes the invoice readable:
- Detects the page inside the photo
- Corrects perspective so the invoice is rectangular and upright
- Removes shadows and glare so text is legible edge to edge
- Flattens curvature from folded or bound documents
- Returns a clean JPG or PDF that extraction tools can actually parse
ScanKit exposes this as a single endpoint: POST /scan/crop.
import requests
def clean_invoice(photo_path: str, api_key: str) -> bytes:
with open(photo_path, "rb") as f:
r = requests.post(
"https://api.scankit.io/scan/crop",
headers={"X-API-Key": api_key},
files={"file": f},
)
r.raise_for_status()
return r.content # clean invoice ready for extraction
Add this before your extraction provider — in the upload handler of your expense app, a supplier portal, or a shared email-to-OCR inbox. One request, one clean document, and the extraction step finally receives input it was designed for.
What finance teams get
- Fewer misread invoices — extraction starts from a document, not a photo
- Less manual re-entry — fewer exceptions means fewer hours in the AP inbox
- Faster processing — clean documents go through OCR and approval without retries
- Audit-ready records — every invoice is a clean, upright, searchable file
Privacy and where the data goes
Invoices contain supplier data, amounts, and sometimes payment details. In the EU, where that data is processed is a compliance question before it is a technical one. When you add a scan step, check three things:
- Is it hosted in the EU?
- Is the upload encrypted in transit?
- Is the document deleted after processing?
ScanKit is built on those three answers: EU hosting, TLS in transit, deletion after processing. Only the clean scan leaves the request — the original photo is not stored.
The bottom line: invoice photos fail extraction because of the photo, not the tool. A scanning API turns the photo into a clean, flat, processable invoice before your extraction step ever sees it — one endpoint, one call, and the AP inbox gets quieter.
Try it with 50 free credits, no credit card required: create a free ScanKit account.
Ready to get started with ScanKit?
Start building powerful document scanning features into your applications today.