back to overview
For developers·8 min read

The developer's guide to VFS Global automation

No-fluff walkthrough of what actually breaks on VFS — Cloudflare Turnstile, Angular mat-selects, queue pages, and the 403201 ASN block — in the order it breaks.
The setup

What VFS looks like from the outside

VFS Global hosts ~140 country-pair visa portals under the umbrella domains visa.vfsglobal.com and www.vfsglobal.com. The URL pattern is predictable — /{origin}/{lang}/{destination}/book-appointment — but that's where predictability ends. Every corridor can have its own flavour of the Angular booking app underneath.

Architecturally you're hitting three layers: Cloudflare edge (bot wall), the Angular SPA (booking UI + OTP state), and the VFS backend (slot assignment). Any one of them can say no.

Hurdle 1

Cloudflare edge rule 403201

Every request to visa.vfsglobal.com from a hosting-provider IP (AWS, GCP, Railway, DigitalOcean, etc.) hits a Cloudflare edge rule and comes back as a canned 46-byte JSON:

{"code":"403201","description":""}

There's no challenge page — it's a hard block. The fingerprint Cloudflare is scoring combines ASN, TLS signature, and passive header heuristics. Solving it means egress from a residential IP in the origin country and a browser that doesn't emit headless-Chrome tells. Anti-detection init scripts (navigator patches, plugin arrays, WebGL fingerprint) are table stakes.

Hurdle 2

Turnstile on login

In 2026, VFS wrapped its login form in Cloudflare Turnstile. A standard CapSolver integration does not work here — Turnstile's verification happens via a postMessage from challenges.cloudflare.com to the parent window, and VFS's Angular app registers its own message handler that rejects anything it considers an injected token.

The working technique: capture the Turnstile handler at load time, then forge a MessageEvent with origin: "https://challenges.cloudflare.com" and fire it directly at the captured handler. The Angular FormControl receives the token as if it came from the real widget and the login submit goes through. We refer to this internally as "Probe H" — it's the output of an A→H probe matrix that burned two weeks.

Hurdle 3

Angular mat-selects and the queue page

The booking form is Angular Material. Dropdowns are <mat-select> elements with overlay panels rendered in a cdk-overlay-container at the body root. Clicking the visible trigger works; typing into it does not.

Two gotchas:

  • Some corridors pre-populate center or visa type. If you select again you clear downstream selections. Guard for the existing value before issuing a click.
  • A cdk-overlay-backdrop can intercept clicks on the next dropdown after a selection — the previous overlay hasn't fully unmounted. Wait for the backdrop to detach, or click through it with a coordinate-space click, before the next selection.

VFS also queues you on high-load days. You'll hit a waiting-room page with a rotating spinner that eventually kicks you through. Detect the queue selector, wait up to 5 minutes, then resume — don't hammer.

Hurdle 4

Availability reads without accidental form state

The safest way to check slot availability is read-only: dashboard → Start New Booking → select center + visa category, then scrape the availability banner ("Earliest available DD-MM-YYYY") without filling /your-details or clicking Save. Full booking flow is destructive — it can hold a slot and fail the confirm, which applicants get emailed about.

VFS surfaces one banner per applicant-count once the dropdowns are populated. Parse all banners; the lowest count + earliest date combo is your best move. Inline calendars appear on some corridors — read those with a cell selector and cross-reference with the banner.

Hurdle 5

OTPs at two steps

VFS sends an OTP during login (sometimes — varies by corridor and account age) and always during final confirmation. The login OTP is recoverable; the confirm OTP is not. See the dedicated OTP latency guide for how to architect the round trip.

Build vs buy

The honest cost

None of the above is undoable. But cumulatively it's six weeks of engineering work plus ongoing maintenance as VFS ships tweaks (recent ones: the SHORTY STAY sub-type typo, the cdk-overlay-backdrop interception behaviour, the Turnstile upgrade). Residential proxy spend is ~$2–6/GB with negligible per-booking cost once provisioned.

If you're an agency doing <20 bookings/month, automate the easy parts and lean on humans for the rest. If you're a platform handling volume, the maths flips fast — slot success rate dominates cost.