Umrah Visa Automation: From WhatsApp Photo to Government Portal
UmrahFlow turns a pilgrim's WhatsApp passport photo into a staged, ready-to-submit Umrah visa job. AI does the hard reading, and people make the two decisions that matter.
By Wasif Rehman · · Automation
In short
- Model the pipeline as states in a database, not calls between services, so every step is resumable and inspectable.
- Put AI where reading is hard and humans where mistakes are expensive.
- A drain loop keeps webhooks fast, survives crashes and lets the agent treat a photo album as one submission.
- When automation touches an external system of record, stop one step short and hand a person a loaded, verified, one-keystroke action.
- Test the seams: one smoke script should tell you whether a WhatsApp photo still becomes a staged visa job.
Why Umrah visa processing needs automation
Umrah visa processing is a paperwork business run over WhatsApp. Agents receive passport photos in chat, retype the details into spreadsheets, and then retype them again into the Saudi Nusuk portal.
UmrahFlow is a freelance project I built to automate that pipeline end to end: from the first WhatsApp photo to a staged, ready-to-submit visa job. It deliberately keeps one human decision in the middle and one at the end.
How the visa automation pipeline is built
The system is a chain of five services. Each one does one job and hands off to the next.
| Service | What it does |
|---|---|
| WhatsApp relay | Receives messages from pilgrims on the agency's own number and forwards them to the dashboard in Twilio webhook format |
| Next.js dashboard | Stores messages in Postgres, and is where staff review extracted passports |
| Agent service | Drains unprocessed messages, classifies each one, runs images through OCR, creates passport records and replies to the pilgrim on WhatsApp |
| OCR service | Reads passport images with an MRZ parse and a Claude vision pass |
| Bridge service | Picks up approved passports, builds a submission plan and stages it as a job in the operator's visa console |
- WhatsApp relay
- Next.js dashboard
- Agent and OCR
- Staff review
- Bridge
- Operator submits
The bridge only stages the job. A person runs the actual submission to the government portal.
Why an agent drain loop beats an inline webhook handler
The tempting design is to process each incoming webhook inline: the message arrives, OCR runs, the reply goes out. I built a drain loop instead. The dashboard just stores messages with processedAt = NULL, and the agent polls for unprocessed rows every few seconds.
That buys three things:
- Slow OCR never blocks the webhook. The webhook only stores the message.
- A crashed agent loses nothing. Unprocessed messages simply stay unprocessed.
- The agent can debounce. Pilgrims send passports as photo albums, so the loop waits for the album to finish arriving and treats it as one submission instead of six.
I cover the album problem and the rest of the intake in WhatsApp webhooks: debouncing albums and draining queues.
Passport OCR you can trust with visa data
Passport data is exactly the kind of data you cannot afford to hallucinate. The OCR service merges two independent reads: a deterministic MRZ (machine-readable zone) parse and a Claude vision pass, with OpenAI as a fallback.
| When the two reads | What it means |
|---|---|
| Agree | Confidence is high |
| Disagree | That is a signal for the human reviewer |
The service returns fields in the exact shape the dashboard's upload code expects, so extracted passports flow straight into the review screen. The full design is in Passport OCR with AI: combining MRZ parsing and Claude vision.
A human review step built as a state machine
Nothing goes from OCR to the government pipeline automatically. Staff see each passport in the dashboard with its extracted fields and the original photos side by side.
Only an explicit approval flips the passport's status to QUEUED. That status change is the entire interface between the review side and the submission side.
- OCR extracts fields
- Staff compare with photos
- Approval sets QUEUED
- Bridge leases queued rows
- Job staged in console
Staging Nusuk portal submissions, one step short
The bridge service turns queued passports into staged submission jobs. It builds each submission plan with the visa console's own plan builder, importing the client's existing code instead of reimplementing its logic. The staged job is exactly what the console would have produced by hand.
The final step, actually submitting to Nusuk, needs the operator to log in and run the submission command deliberately.
No pilgrim's visa rides on an unreviewed AI guess. I wrote more about this choice in When not to let the AI finish the job.
End-to-end smoke tests for an automation pipeline
A pipeline like this fails at the seams, not in the middle of a service. So the repo ships a smoke script that runs eleven end-to-end checks:
- Health checks Every service's health endpoint.
- A full agent turn A message goes in, a passport comes out, and a reply is sent.
- Bridge staging An approved passport is staged as a submission job.
Does a WhatsApp photo still become a staged visa job?
The one question the smoke script answers after any change
How the services and the smoke script are set up is in Building microservices to someone else's API contract.
Frequently asked questions
Can Umrah visa processing be automated?
Most of it can. In UmrahFlow, WhatsApp intake, passport reading and building the submission plan are automated. Staff still approve each passport, and an operator runs the final submission to the Nusuk portal by hand.
Does UmrahFlow submit visas to the Nusuk portal automatically?
No. The bridge stages a ready-to-submit job in the visa console, and the operator logs in and runs the submission command. Submitting to a government portal is irreversible, so it stays behind a human keystroke.
Why use a drain loop instead of processing WhatsApp webhooks directly?
Storing messages first and polling for unprocessed rows means slow OCR never blocks the webhook, a crashed agent loses nothing, and the agent can wait for a photo album to finish arriving before processing it as one submission.
How do you test a multi-service automation pipeline?
Test the seams. UmrahFlow has a smoke script with eleven end-to-end checks: every health endpoint, a full agent turn from message to passport to reply, and bridge staging.
Case study: UmrahFlow