latestOpenAPI 3.0.3Commercial — see Terms2026-08-223053119.7 KB

024933fc5445

Visa data

Itinerary decision — answers a trip, not a pair

Post a whole trip — passport, ordered stops with dates, transit stops, passport expiry — and get a per-step decision plus the blockers that only a full itinerary reveals:

  • days accumulated across repeat visits to the same country (two 20-day stops in one country are not two independent stays);
  • passport validity measured against each arrival date;
  • a passport that expires before the last exit.

Every field states its granularity (pair or destination), and every gap comes back as status: "unknown" with a reason — never as a default value. verdict is no_blocker_found or blocked: it reports what the data supports, it is not legal advice.

Known gaps, by design

  • Transit: a transit rule exists for 44 of 238 destinations and is recorded per transited country, not per nationality — so even where it exists it never decides whether this passport may transit. The other 158 return status: "unknown". Confirm with the carrier.
  • residence and purpose are accepted and echoed back but not modelled: the dataset has no residence dimension and covers short-stay tourism only. Supplying either adds an entry to unknowns.
  • Length of stay is computed only where visa_free_days holds a number; where the stay depends on the permit issued, max_stay is unknown rather than a parsed guess.

Billing

One request per distinct country resolved (stops + transit), like /bulk. A 3-country trip costs 3. meta.pairs_charged reports exactly what was billed. Maximum 12 itinerary steps and 12 transit countries per call.

post/api/v1/visa/decision

Request body

passportstring required

ISO 3166-1 alpha-3 country code.

transitISO3[]

Countries transited without entering. Deduplicated, and billed like a stop.

passport_expirystring date nullable

Omit it and every passport-validity check is skipped and reported in unknowns.

residencestring nullable

Accepted and echoed back, not modelled — adds an entry to unknowns.

purposestring nullable

Accepted and echoed back. Anything other than tourism adds an entry to unknowns.

Example request

{
  "passport": "FRA",
  "itinerary": [
    {
      "country": "FRA",
      "from": "2026-09-01",
      "to": "2026-09-20"
    }
  ],
  "transit": [
    "FRA"
  ],
  "passport_expiry": "2027-03-01",
  "purpose": "tourism"
}

Response

Per-step decision, blockers and unknowns.

Example response

{
  "data": {
    "passport_country": "FRA",
    "steps": [
      {
        "country": "FRA",
        "days": 20,
        "regime": {
          "value": "visa_free"
        },
        "max_stay": {
          "basis": "visa_free_days"
        }
      }
    ],
    "transit": [
      {
        "country": "FRA"
      }
    ],
    "passport": {
      "per_destination": [
        {
          "country": "FRA"
        }
      ]
    },
    "blockers": [
      {
        "country": "FRA"
      }
    ],
    "unknowns": [
      {
        "field": "transit",
        "country": "FRA"
      }
    ]
  },
  "meta": {
    "api_version": "1.0",
    "pairs_charged": 3,
    "max_steps": 12
  }
}