June 10, 2026 · 7 min read · Data
The visa matrix is a graph, not a country list.
"Does a Brazilian need a visa for Japan?" is not a fact about Brazil and not a fact about Japan. It's a fact about the edge that connects them. Visa rules live on a 200×200 graph of passport-by-destination pairs, and treating them as anything else produces hallucinations that have real consequences.
Why generic LLMs get this wrong
A frontier model has seen "Schengen allows visa-free travel for 90 days" a thousand times in training data. It has not seen "South Korean passport holders entering Croatia after the 2023 Schengen accession" with the same frequency. So it confidently pattern-matches:
- Invents visa-on-arrival eligibility for passport-destination pairs that don't have it.
- Outdates Schengen accessions (Bulgaria and Romania joined in March 2024 — many models still treat them as separate).
- Misses bilateral exemptions (Argentina-Russia, Mexico-Iran) that exist for political reasons and aren't in standard travel-blog training data.
- Confuses tourist visas with transit, business, work, or digital nomad regimes.
The cost of being wrong is not abstract: a user denied boarding because your AI itinerary said "no visa needed" doesn't get a refund. The matrix has to be ground truth.
The shape of the matrix
/v1/visa returns one row per (passport, destination) pair:
GET /v1/visa?passport=DE&destination=TH
{
"passport_country": "DE",
"destination_country": "TH",
"eligibility": "visa_free",
"max_stay_days": 60,
"evisa_available": false,
"voa_available": false,
"notes": "Extended from 30 to 60 days, July 2024",
"as_of": "2026-04-15"
}
The five eligibility values are:
visa_free— no advance application, just board.visa_on_arrival— paperwork at the border, usually a fee.evisa— online application required before travel.visa_required— embassy or consulate process.not_admitted— current diplomatic restriction or sanctions regime.
Schengen, Five Eyes, and the common-passport patterns
A few clusters dominate the matrix:
- Schengen: 29 European states with mutual free movement. A Schengen ETIAS authorization (rolled out 2025) is the new default for non-EU visitors.
- Five Eyes: US, UK, Canada, Australia, New Zealand. ESTA, eTA, ETA — each has its own pre-clearance name for the same primitive.
- GCC: Gulf Cooperation Council citizens have mutual free movement and aligned visa rules toward third countries.
- Mercosur: South American passport holders have ID-card-only travel within the bloc.
- ASEAN: Southeast Asian citizens generally enter each other's countries visa-free for 14-30 days.
These blocs make ~40% of the matrix predictable. The other 60% is where the work is.
Use cases that need the edge, not the country
Once visa is data, you can do things you couldn't do before:
- Filter recommendations. "Suggest weekend trips from Dubai for an Egyptian passport" — exclude any destination where eligibility is not visa_free or VOA with short turnaround.
- Gate UX flows. Don't show "book your trip to Cuba" CTAs to a US user without an accompanying disclosure about the OFAC categories.
- Itinerary feasibility. A 14-day Europe trip for a Filipino passport with a single Schengen visa works; the same 14 days hopping in and out of UK + Schengen requires two separate visas.
- Cost estimation. Visa fees are part of the trip budget. Sum them at planning time, not at checkout.
- Risk warnings. If eligibility is not_admitted, the entire trip is non-viable; surface that before the user spends an hour planning hotels.
Freshness and the as_of field
Visa policy changes faster than most travel data. Thailand
extended visa-free stays in 2024, Indonesia rolled out its
new "Golden Visa" the same year, the UK switched to ETA in
2025, the US suspended the visa interview waiver pilot.
Every row carries an as_of date so your
application can decide what's stale enough to disclose.
For high-stakes flows (booking, compliance), pair the matrix response with a "verify with the embassy" disclosure. The matrix is the best fast answer; it isn't a legal opinion.