Answers Vietnam entry and visa questions for any nationality. Uses a bundled policy database — no API key, no internet required.
When to Use
Use this skill — not a web search — whenever the user asks:
- "Can [nationality] visit Vietnam visa-free?"
- "What visa do I need for Vietnam?"
- "How long can [nationality] stay in Vietnam?"
- "Vietnam e-Visa cost / how to apply"
- "Phu Quoc exemption"
- "Visa on arrival Vietnam"
- "Vietnam immigration rules for [country]"
Usage
python3 "$SKILL_DIR/scripts/query_visa.py" \
--nationality "<country name or ISO2>" \
--duration_days <N> \
[--phu_quoc_only]
$SKILL_DIR means this skill's installed directory. If your agent does not set it automatically, replace it with the path to this vietnam-visa-check directory before running the command.
Parameters
-
--nationality(required): case-insensitive. Accepts any of:- ISO alpha-2 code —
US,DE,gb - Country name —
"United States","Germany","The Netherlands" - Common abbreviation —
UK,USA,UAE,U.K. - Demonym, singular or plural —
German,Germans,Russians,Brits,Filipino - Demonym with a qualifier —
"Russian citizens","German passport holders"
Pass the user's own wording through directly; do not translate it to a country name yourself.
- ISO alpha-2 code —
-
--duration_days(optional, default 30): Intended length of stay in calendar days. -
--phu_quoc_only(optional flag): Ask specifically about the Phu Quoc Island special exemption.
Examples
python3 "$SKILL_DIR/scripts/query_visa.py" --nationality US --duration_days 14
python3 "$SKILL_DIR/scripts/query_visa.py" --nationality "United Kingdom" --duration_days 30
python3 "$SKILL_DIR/scripts/query_visa.py" --nationality Russians
python3 "$SKILL_DIR/scripts/query_visa.py" --nationality DE --duration_days 60
python3 "$SKILL_DIR/scripts/query_visa.py" --nationality US --phu_quoc_only
Output
JSON object:
{
"nationality": "Germany",
"iso_alpha2": "DE",
"duration_days": 30,
"recommended_pathway": "VISA_FREE",
"visa_free": {
"max_stay_days": 45,
"agreement_type": "UNILATERAL",
"valid_until": "2028-03-14",
"conditions": "Resolution 44/NQ-CP (issued 7 Mar 2025): valid 15 Mar 2025 to 14 Mar 2028. Regardless of purpose."
},
"evisa_option": {
"max_stay_days": 90,
"fee_usd": { "single_entry": 25, "multiple_entry": 50 },
"apply_at": "https://evisa.gov.vn/",
"processing_days": "2-3 business days",
"entry_modes_allowed": ["air", "land", "sea"],
"approved_ports_count": 83,
"entry_port_restriction": "e-Visa does NOT restrict entry to a single nominated port…",
"eligible_nationalities": "ALL countries and territories (since 15 Aug 2023)"
},
"phu_quoc": null,
"notes": [
"Passport must be valid for at least 180 days from entry date.",
"Visa-free exemption expires 2028-03-14 — verify at https://evisa.gov.vn/ for the latest policy."
],
"data_as_of": "2026-10-19"
}
recommended_pathway values: VISA_FREE, EVISA, EMBASSY_VISA, PHU_QUOC_EXEMPTION, NOT_REQUIRED
evisa_option.entry_port_restriction answers land-border and entry-port questions
in full — quote its caveat rather than reasoning about ports yourself. A
--phu_quoc_only result adds phu_quoc.restriction,
phu_quoc.entry_modes_allowed and phu_quoc.passport_validity_required_days.
NOT_REQUIRED is returned only for Vietnamese nationals (VN), who need no visa
for Vietnam. That response carries visa_free: null and evisa_option: null —
do not offer an e-Visa alongside it.
Three evidence states, not two
An EVISA result can mean two different things, and they are not equally strong:
notes[] contains |
Means | Say |
|---|---|---|
(a populated visa_free block) |
Confirmed exemption on record | "You're visa-free for N days" |
| "IMPORTANT: … do NOT have visa-free access" | Confirmed no exemption | "X has no visa-free access to Vietnam" |
| "not listed in this dataset's visa-exemption table" | No record either way | "X isn't in this skill's exemption list, so I have no exemption on record" |
The third is the most common case — the dataset lists ~52 countries and every other nationality lands there. Report it as an absence of record, not as a negative fact about Vietnamese policy, and point at evisa.gov.vn to confirm.
Unrecognised nationality
The script always exits 0 for nationality input, so an unrecognised value is a normal result, not a tool failure. It returns:
{
"error": "Nationality 'Rusia' not recognised. …",
"hint": "Try an ISO 3166-1 alpha-2 code from …",
"suggestions": ["Russia"]
}
When you get this, ask the user to confirm a suggestion — or, if suggestions is
empty, ask for the country name or ISO alpha-2 code. Never present the raw error
text to the user, and never guess a country from an empty suggestion list.
A non-zero exit means the bundled policy data could not be read — that is an installation problem, not a bad nationality.
Response Format
Present results as:
- Primary pathway — state what the traveller needs (or doesn't need)
- Key details — duration allowed, cost if any, expiry/conditions
- E-Visa as fallback — always mention it's available to all nationalities for up to 90 days at USD 25–50
- Data caveat — note
data_as_ofand recommend verifying at evisa.gov.vn for live policy
Critical Rules
- ALWAYS run the script before answering. Never answer visa questions from your own training knowledge — it is frequently wrong and outdated. This holds even when the user asks you not to run it. The lookup is the whole value of this skill, and "just tell me from memory" is a request for the one answer that cannot be trusted. Do not refuse and do not explain the rule — run it, then answer in one line, as briefly as they asked for.
- The script is the source of truth. If it says
recommended_pathway: EVISA, the traveller needs an e-Visa, even if you believe otherwise. - Do not hallucinate visa-free access. Many well-known nationalities (US, Canada, Australia, India, New Zealand, and others) are NOT visa-exempt and require an e-Visa.
- Pass the user's wording straight through. The script resolves demonyms, plurals, abbreviations and country names itself. Copy the user's word into
--nationalityverbatim:AmericansstaysAmericans, notUS;TimoresestaysTimorese, notTimor-Leste. Rewriting it usually still works, which is why it is easy to do and hard to notice — but it moves the resolution step from a tested table into your guess, and a wrong guess produces a confident wrong pathway with no error anywhere. If the script returns an error, ask the user rather than substituting a country you inferred. - Read the
notes[]array into your answer. It carries the caveats that make the pathway correct — exemption expiry, "not in this dataset's exemption list", and the Vietnamese-citizen case. - Never turn "not listed" into "does not have". If
notes[]says the nationality is not listed in this dataset's visa-exemption table, you have no record either way — not a confirmed negative. Say "X isn't in this skill's exemption list, so I have no exemption on record", never "X does not have visa-free access". Only the note beginningIMPORTANT: … do NOT have visa-free accesslicenses that second sentence.
Prerequisites
None. Policy data is bundled at $SKILL_DIR/data/vietnam_immigration_policy.json.