I built the front-end identity-verification flow for Neoke, a travel digital-identity startup. A traveler photographs a government ID, takes a selfie, and gets a verified result on one mobile page. I wrote the webcam capture layer with react-webcam — document and selfie capture, a review-and-retake step, and front/back camera switching on mobile.
I posted the captured ID to a /process-document endpoint that returns OCR fields (the MRZ string, document number, expiry, and all four check digits) and the selfie to a /facematch endpoint that returns a match score, which I rendered as a confidence dial with high/moderate/low tiers. I also built a separate Timatic tool that calls IATA's travel-requirements API to check document validity against a trip itinerary.
The hard part
Sharp ID photos across every browser
Browser cameras are inconsistent — Safari, Chrome, and mobile each interpret getUserMedia resolution constraints differently, so screenshots came back blurry, wrong-sized, or black. I rebuilt the capture component on react-webcam with forced screenshot source sizing, separate resolution constraints for mobile (960×1280) and desktop (1920×1440), and a Safari-specific fix — producing ID images sharp enough for the OCR endpoint to read the MRZ and check digits.
Highlights
- Built a 7-route React verification flow: capture, review, selfie, results, and guest registration.
- Wired 2 backend integrations: /process-document (OCR + MRZ + check digits) and /facematch (match score).
- Fixed cross-browser webcam capture, including a Safari-specific bug and mobile front/back switching.
- Integrated IATA Timatic's document-request API with OAuth2 client-credentials token exchange.
- Built a 5-section, Zod-validated guest registration form with draw-or-type signature capture.
Stack