Receipt Intake
Intelligent document processing · 200 real scanned receipts

Scanned receipts in, clean records out.

A pipeline that reads real, crumpled, low-resolution receipts: several OCR passes vote on each field, small learned models pick the company, date, address and total, and validation sends anything uncertain to a person instead of the database. Every number below is measured on receipts the models never saw.

Upload to S3encrypted, private inbox
s3:ObjectCreated
→
4 OCR passesTesseract 5, two models × two layouts
Lambda container
→
Field scorerscandidates + OCR voting
logistic regression
→
Validationschema rules + learned thresholds
95% precision target
→
DynamoDBor review queue
SQS, idempotent writes

Receipt

Results

Trained on 426 receipts, tested on 200 others. A field counts as right only if it matches the label exactly (amounts and dates by value; company and address as text after upper-casing and collapsing spaces).

How it works

The expensive part of document processing isn't reading text; it's knowing when the reading is wrong. So the pipeline is built around calibrated confidence and a review queue.

OCR voting

Each receipt is read four times (Tesseract's standard and "best" models, each with two page-layout modes). They make different mistakes, so every candidate carries how many passes agree with it.

Candidates, not guesses

Dates and amounts come from patterns; company and address from lines near the top. A logistic regression per field ranks candidates on position, keywords, font size, agreement and OCR confidence.

Calibrated review

Five-fold cross-validation on the training receipts sets each field's threshold: the lowest confidence at which accepted values were at least 95% right. Below it, or failing a schema rule, the field goes to a person.

Serverless on AWS

An AWS SAM template: an encrypted private S3 inbox triggers a container Lambda (Tesseract + the models). Results go to DynamoDB with conditional writes, uncertain ones to an SQS review queue.

Least privilege

The function can read only inbox/*, write one table and send to one queue. TLS-only bucket policy, KMS encryption, no public access, non-root container, dead-letter queue and CloudWatch alarms.

Reproducible

CI downloads the dataset, retrains, re-scores the test set and fails if the published numbers drift; the Lambda image is built and run on a real receipt; the handler is tested end to end against mocked S3, DynamoDB and SQS.

Data: the SROIE 2019 receipts (ICDAR competition, corrected labels). Images on this page load from that repository.