No passport matches your search.
Who needs a visa, and for how long? The Travel Buddy API answers it for 200 passports and 211 destinations, with stay lengths, passport-validity rules, mandatory arrival forms and links to official eVisa portals. Checked against government sources and updated daily.
Free plan with 120 requests a month. Paid plans from $4.99.
Send a passport and a destination as ISO alpha-2 codes. The response carries the primary and secondary visa rules with stay lengths, any exception, mandatory arrival registration, passport validity, an embassy link, and destination basics like capital, currency, phone code and time zone.
curl -X POST https://visa-requirement.p.rapidapi.com/v2/visa/check \
-H "Content-Type: application/json" \
-H "X-RapidAPI-Proxy-Secret: ${RAPIDAPI_SECRET}" \
-d '{"passport":"CN","destination":"ID"}'const res = await fetch("https://visa-requirement.p.rapidapi.com/v2/visa/check", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-RapidAPI-Proxy-Secret": process.env.RAPIDAPI_SECRET,
},
body: JSON.stringify({"passport": "CN", "destination": "ID"}),
});
const { data } = await res.json();import os, requests
res = requests.post(
"https://visa-requirement.p.rapidapi.com/v2/visa/check",
headers={"X-RapidAPI-Proxy-Secret": os.environ["RAPIDAPI_SECRET"]},
json={"passport": "CN", "destination": "ID"},
)
data = res.json()["data"]{
"data": {
"passport": {
"code": "CN",
"name": "China",
"currency_code": "CNY"
},
"destination": {
"code": "ID",
"name": "Indonesia",
"continent": "Asia",
"capital": "Jakarta",
"currency_code": "IDR",
"currency": "Indonesian Rupiah",
"exchange": "0.00425",
"passport_validity": "3 months beyond the period of stay",
"phone_code": "+62",
"timezone": "+08:00",
"population": 277329163,
"area_km2": 1916907,
"embassy_url": "https://www.embassypages.com/china#titlePlaceholder2"
},
"mandatory_registration": {
"name": "e-Arrival",
"color": "yellow",
"link": "https://link.travel-buddy.ai/?link=76E321T3"
},
"visa_rules": {
"primary_rule": {
"name": "Visa on arrival",
"duration": "30 days",
"color": "blue"
},
"secondary_rule": {
"name": "eVisa",
"duration": "30 days",
"color": "blue",
"link": "https://link.travel-buddy.ai/?link=76E323T2"
}
}
},
"meta": {
"version": "2.0",
"language": "en",
"generated_at": "2025-09-28T11:47:00+00:00"
}
}Use primary_rule as the authoritative color for the badge, and combine it with secondary_rule into one customer-facing line.
If neither rule has a duration, drop the days suffix: “Visa required / eTA”.
| Situation | Condition | Display | Days from |
|---|---|---|---|
| Only a primary rule | secondary_rule is absent | primary – XXX days | primary_rule.duration |
| Both have durations | Both duration fields are present | primary / secondary – XXX days | primary_rule.duration |
| Primary has no duration | Primary is null or empty, secondary has one | primary / secondary – XXX days | secondary_rule.duration |
exception_ruleAn exception applies to travelers who meet specific criteria, such as holding a valid visa or residence permit for another country, traveling on an organized tour, or meeting transit-waiver conditions. It comes with a name, an exception type, the full condition text, the related country codes and an official link.
Show it beneath the rule line. Keep the primary badge color unless your UI lets travelers confirm they meet the criteria.
mandatory_registrationSome destinations require a pre-arrival form online, like e-Arrival, pre-registration or an ED card. It is always free, mandatory for all or most travelers, and separate from any visa or eVisa.
Show it near the top of the result and link to mandatory_registration.link so travelers use the official form. It never replaces a visa requirement.
Send a passport code and get all 210 destinations grouped by color, ready for a passport-index style map. The map behind this card is the example response for a Chinese passport.
curl -X POST https://visa-requirement.p.rapidapi.com/v2/visa/map \
-H "Content-Type: application/json" \
-H "X-RapidAPI-Proxy-Secret: ${RAPIDAPI_SECRET}" \
-d '{"passport":"CN"}'const res = await fetch("https://visa-requirement.p.rapidapi.com/v2/visa/map", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-RapidAPI-Proxy-Secret": process.env.RAPIDAPI_SECRET,
},
body: JSON.stringify({"passport": "CN"}),
});
const { data } = await res.json();import os, requests
res = requests.post(
"https://visa-requirement.p.rapidapi.com/v2/visa/map",
headers={"X-RapidAPI-Proxy-Secret": os.environ["RAPIDAPI_SECRET"]},
json={"passport": "CN"},
)
data = res.json()["data"]{
"data": {
"passport": "CN",
"colors": {
"red": "AD,AF,AR,AT,AU,AW,BE,BG,…",
"green": "AE,AG,AL,AM,AO,AZ,BA,…",
"blue": "AI,BD,BF,BH,BI,BO,BT,…",
"yellow": "CI,KE,KN,LK,SC"
}
},
"meta": { "version": "2.0", "language": "en" }
}Give each visa category a weight: positive, zero or negative, integer or float. Every passport scores the sum of its count in each category times that category’s weight, and the list comes back ranked. Categories you leave out count as zero.
Counts are the sample values from the documentation. Live responses cover every passport.
curl -X POST https://visa-requirement.p.rapidapi.com/v2/passport/rank/custom \
-H "Content-Type: application/json" \
-H "X-RapidAPI-Proxy-Secret: ${RAPIDAPI_SECRET}" \
-d '{
"weights": {
"Visa-free": 2,
"Visa on arrival": 1,
"Visa required": 0,
"eVisa": 1,
"eTA": 1,
"Tourist card": 0,
"Freedom of movement": 3,
"Not admitted": -1
}
}'const res = await fetch("https://visa-requirement.p.rapidapi.com/v2/passport/rank/custom", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-RapidAPI-Proxy-Secret": process.env.RAPIDAPI_SECRET,
},
body: JSON.stringify({
"weights": {
"Visa-free": 2,
"Visa on arrival": 1,
"Visa required": 0,
"eVisa": 1,
"eTA": 1,
"Tourist card": 0,
"Freedom of movement": 3,
"Not admitted": -1
}
}),
});
const { data } = await res.json();import os, requests
res = requests.post(
"https://visa-requirement.p.rapidapi.com/v2/passport/rank/custom",
headers={"X-RapidAPI-Proxy-Secret": os.environ["RAPIDAPI_SECRET"]},
json={
"weights": {
"Visa-free": 2,
"Visa on arrival": 1,
"Visa required": 0,
"eVisa": 1,
"eTA": 1,
"Tourist card": 0,
"Freedom of movement": 3,
"Not admitted": -1
}
},
)
data = res.json()["data"]Ask for one passport and destination from a start date. The response says whether the primary rule has changed, lists every change with its date and the old and new rule, and gives you the rule in force today. Use it for visa-change alerts, mobility dashboards, booking engines and compliance research.
curl https://visa-requirement.p.rapidapi.com/v2/visa/check/history/KZ/ME/2024-01-01 \
-H "X-RapidAPI-Proxy-Secret: ${RAPIDAPI_SECRET}"const res = await fetch(
"https://visa-requirement.p.rapidapi.com/v2/visa/check/history/KZ/ME/2024-01-01",
{ headers: { "X-RapidAPI-Proxy-Secret": process.env.RAPIDAPI_SECRET } }
);
const { data } = await res.json();import os, requests
res = requests.get(
"https://visa-requirement.p.rapidapi.com/v2/visa/check/history/KZ/ME/2024-01-01",
headers={"X-RapidAPI-Proxy-Secret": os.environ["RAPIDAPI_SECRET"]},
)
changes = res.json()["data"]["changes"]passportdestinationfromDate"data_mode": "demo" and "is_demo": true.{
"data": {
"pcc": "KZ",
"dcc": "ME",
"from_date": "2024-01-01",
"has_changes_since_from_date": true,
"current_rule": {
"name": "Visa not required",
"duration": "30 days",
"duration_days": 30,
"color": "green"
},
"changes": [
{
"date": "2024-07-29",
"old_rule": { "name": "Visa required", "color": "red" },
"new_rule": { "name": "Visa not required", "color": "green" }
}
]
},
"meta": { "data_mode": "real", "is_demo": false }
}/v1/* to /v2/*.x-www-form-urlencoded. The fields stay passport and destination.data.* object and visa_rules with its primary, secondary and exception rules.Four public plans on RapidAPI take you from a free tier to millions of requests a month. For high-volume or custom needs there is a private enterprise plan for select partners.
Yes. The free plan includes 120 requests a month, so you can prototype and test at no cost.
Yes. The API returns up-to-date visa status, allowed stay duration, minimum passport-validity rules, and whether an eTA or eVisa is available, plus embassy links and other helpful fields when available.
Yes. We include links only to official government or authorized application websites. No third-party agency links.
Visa requirements are the baseline rules that decide whether a traveler needs a visa, eTA or eVisa and how long they may stay, for example visa-free for 90 days with a passport valid for 6 months. Travel restrictions are temporary or conditional measures that can change quickly, like health or vaccination rules, sudden policy updates, strikes or regional advisories. The API covers visa requirements and core entry rules. Always verify fast-changing restrictions with official sources before travel.
Our content team continuously monitors official government and consular sources and updates the data as soon as changes are verified. We prioritize ministries of foreign affairs, embassy and consulate sites, and official eVisa portals.
No. Travel Buddy is not a replacement for IATA Timatic and is not intended for airline check-in or boarding compliance. The API is for informational and pre-trip planning use in apps and websites. For operational compliance and final travel authorization, always check the airline’s requirements and official government guidance.
The support team answers API questions at [email protected].