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.