Quickstart

Five minutes, one endpoint. You need an API key with the check:read scope — the partner portal issues one, or a colleague can.

1. Set your key

shell
export HAAVISA_API_KEY="hv_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Keys go in a header, never a query string. A credential in a URL ends up in access logs, CDN logs and Referer headers, where an airline’s key should not be spending years.

2. Ask the question

curl
curl -sS -X POST https://api.haavisa.com/v1/check \
  -H "Authorization: Bearer $HAAVISA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "nationality_iso3": "SOM",
    "destination_iso3": "KEN",
    "transit_airside": false
  }'

nationality_iso3 and destination_iso3 are ISO 3166-1 alpha-3. Destinations are ETH, SOM, DJI and KEN.

3. Read the answer

response
{
  "verdict": "eta_required",
  "visa_required": true,
  "max_stay_days": null,
  "notes": [
    "Kenya requires an eTA from travellers who are not on the statutory exemption schedule.",
    "Not evaluated: Crew of any ship, aircraft, train, vehicle or carrier proceeding
     to a destination outside Kenya; ..."
  ],
  "products": [
    { "code": "KEN_ETA_TOURIST", "government_fee_cents": 3000, "service_fee_cents": 2900, "currency": "USD" }
  ],
  "citation": "Kenya Citizenship and Immigration (Amendment) Rules, 2025 (s.48, Act No. 12 of 2011)",
  "matched_rule_id": "ken.default.eta"
}

Branch on verdict. It is one of exempt, visa_on_arrival, eta_required, evisa_required, visa_required_embassy or unknown.

4. The same question about a connecting passenger

curl
curl -sS -X POST https://api.haavisa.com/v1/check \
  -H "Authorization: Bearer $HAAVISA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "nationality_iso3": "SOM",
    "destination_iso3": "KEN",
    "transit_airside": true
  }'

Same passport, exempt, because the traveller never leaves the airport. Omit transit_airside and those exemptions are not applied at all — the engine will not assume an exemption it was not told about.

Next