back to overview
02 — How it works

Submit once. Walk away.

The six stages every booking moves through, and what's happening inside each one. Written so engineers know we're not bluffing, and operators know where responsibility sits.
Start a booking
Pipeline

Every booking, stage by stage

step 01
< 2 min

Intake

Submit applicant details, passport, visa type, destination, preferred date window. Via the dashboard, a CSV upload, or a POST to /bookings.

We never ask for your portal password in chat. Credentials are entered once into the Identity Vault during setup; encrypted per-user with a rotating key. From then on, Opaige logs in on your behalf with your real email.

step 02
10–60 sec

Queue + warmup

The booking request enters the BullMQ orchestrator with an idempotency key. A worker is allocated and a per-booking lock taken. Browser session warms up on a residential IP.

Residential IPs are table stakes. VFS edge returns 403201 to every hosting-ASN egress. We run browser workers on residential networks with rotating fingerprints; Chrome launches with a cloned User Data dir per worker to dodge the default-profile security guard.

step 03
2–8 sec

Portal authentication

Adapter logs into the portal with your stored credentials. CAPTCHA/Turnstile handled. Session cookies persist across retries within the lock window.

Cloudflare Turnstile on VFS was a six-week problem. Fix: forge a MessageEvent from challenges.cloudflare.com and fire it at the captured handler. Turnstile completes, dashboard loads. All portal quirks live in the adapter, not the orchestrator — swapping portals doesn't rewrite the engine.

step 04
variable

Availability scan

The adapter watches the portal for your visa center + type. When a slot opens in your window, it's reserved within the portal's hold TTL (usually 60–120 seconds).

Scan cadence is learned per portal: some release on the hour, some trickle, some drop one at a time at unpredictable intervals. Every scan writes a SlotObservation row that feeds the predictor. If no slot appears in your date window, the booking waits — we don't burn attempts on nothing.

step 05
5–20 sec

OTP handoff + confirm

Most portals fire an OTP to your real email or phone. Opaige routes it to you in real time via the dashboard, Socket.io, or webhook. Submit the code; the adapter finalises booking; we capture screenshots + PDF.

The OTP never touches a shared inbox. The portal sends it to the applicant's real address. You see it as a push in the dashboard, or we fire a booking.otp_required webhook. Nothing is booked without a human (or your API) confirming.

step 06
instant

Evidence + refund

Booking reference, PDF, DOM snapshots, and screenshots written to the evidence bundle. Available via GET /bookings/:id/evidence with a 24h-TTL signed URL.

If we failed to book within your date window, the booking moves to FAILED with a reason (NO_AVAILABILITY, PORTAL_CLOSED, QUOTA_EXCEEDED, etc). Applicant charges are refunded; agency overages aren't counted. No quiet losses.

Commitments

What we promise — in writing

30-second operator SLA

Edge cases (portal DOM shift, unexpected CAPTCHA, ambiguous error) escalate to a trained operator with full session context. Median response: under 30 seconds.

Identity stays yours

Your real email, your real phone. Opaige stores credentials for the portal login only — we don't impersonate, we don't plus-alias, we don't operate a mailbox on your behalf.

No-slot, no-charge

Individuals: refund if we couldn't book. Agencies: overages only count for successful bookings — if nothing confirmed, nothing hits your quota.

Prereqs

What you need before you start

Individuals + applicants

  • → Valid passport, scanned
  • → Destination country + visa type
  • → Preferred date window (start + end)
  • → Either your existing portal account, or permission for us to register one in your name

Agencies + platforms

  • → Opaige account (Entry $299 or Pro $999)
  • → For API: one API key from /developer
  • → For bulk: CSV matching our schema (template in-app)
  • → Optional: webhook endpoint for real-time status