Passport Scan API
A passport-scanning microservice — MRZ extraction with ICAO checksum validation and per-field confidence, from photo to JSON.
Client engagement — source code stays private. Shown: architecture and flows.
Upload a passport photo — or capture one with the phone camera — and the service returns structured data: around eighteen fields from the machine-readable zone (names, document number, nationality, dates, gender), plus a cropped face image and the MRZ strip itself, all as JSON.
The pipeline is tuned for accuracy on real-world photos: OpenCV preprocessing crops to the MRZ region of interest, deep-learning OCR runs with its character set locked to the MRZ alphabet, and if nothing legible comes back, the image is automatically retried at multiple scales before giving up with a friendly error.
The differentiating layer is honesty about its own output. Every extracted field is validated against the ICAO 9303 check digits — the same 7-3-1 weighted checksums border systems use — plus document expiry, and each field ships with its own pass/fail verdict. The UI renders them as green and red dots, so a human operator knows exactly which value to re-check instead of trusting or distrusting the whole scan.
System architecture
The modules that make it up, and how data flows between them.
Upload + rear-camera capture
FastAPI · upload · temp-file mgmt
OpenCV + EasyOCR · MRZ + face
ICAO 9303 check digits · expiry
Hover a module to trace what it feeds.
Scan flow
One photo, end to end — from upload to validated JSON.
- 1
Image in
A file upload or live camera capture is saved temporarily and loaded for processing.
- 2
Preprocess
Grayscale conversion and a crop to the bottom band of the document, where the machine-readable zone lives.
- 3
OCR attempt
Text foundThe MRZ lines move on to parsing.
Nothing legibleThe image is automatically retried at 350%, 420% and 450% scale; if it still fails, a clear error JSON comes back instead of garbage fields.
- 4
Face crop
A Haar cascade locates the portrait and crops it with padding — a missing face is non-fatal and simply returns null.
- 5
Parse & validate
The two MRZ lines are parsed as TD3 format and every field is checked against its ICAO 9303 check digit plus document expiry.
- 6
Respond & clean up
JSON ships with ~18 fields, per-field validity flags and base64 crops of face and MRZ — and the uploaded image is deleted.
Engineering highlights
The details that keep it alive with real money on the line.
Per-field trust signals
Every value carries its own checksum verdict — operators re-check one field, not the whole document.
Accuracy hardening
Character-set allowlisting, region-of-interest cropping and automatic multi-scale retries lift real-world photo accuracy well above naive OCR.
Privacy by default
Uploaded passport images are deleted immediately after processing — nothing sensitive accumulates on the server.
Mobile-first capture
The frontend drives the device's rear camera directly, so field use needs no scanner hardware.
Under the hood
The stack, and the system in numbers.