Registry entry

Kenya Electronic Travel Authorisation (eTA) Application

The Directorate of Immigration Services' (Ministry of Interior and National Administration, State Department for Immigration and Citizen Services) Electronic Travel Authorisation (eTA), required of all foreign visitors except citizens of East African Community member states before travelling to the Republic of Kenya. Applied for live and unauthenticated at etakenya.go.ke — no account creation or login is required at any point walked in producing this schema. This schema models the individual (non-group), tourist/visitor pathway: the pre-wizard application setup (traveller category, country of residence, individual-vs-group application type), the Passport Information step (a passport bio-data-page upload that is OCR-processed live into structured fields the applicant then confirms), the Selfie or Photo step (a live-verified biometric face-match check against the passport photo, with an explicit override when the match fails), the Contact Information step (phone, email, address, occupation, and an emergency contact), the Trip Information step (travel reason), and the Arrival Details sub-step of Travel Information (arrival date and mode of arrival). It does not model the remainder of the Travel Information step (e.g. departure/accommodation details, not reached this session), nor the Customs Declaration, Required Documents, or Confirm and Proceed steps that follow in the live wizard's own step navigation — these are disclosed as an accepted scope boundary rather than silently omitted; no eTA fee was paid and no application was actually submitted in producing this schema. Filing this application is a traveller action performed directly with the Directorate of Immigration Services through etakenya.go.ke; this schema does not file the application itself, and the live source is always authoritative. GovSchema is independent and is not affiliated with, endorsed by, or operated by the Republic of Kenya or its Directorate of Immigration Services.

Registry entry

ke/immigration/eta-visa-application

Jurisdiction
Kenya · national
Version
1.0.0
Verification
draft

Authoritative source The live etaKenya Electronic Travel Authorisation wizard, individual/tourist pathway, from application setup through the Arrival Details sub-step of Travel Information.

Machine access

Registry catalog
registry/index.jsonone record per schema id

Field reference

19 fields across 6 steps, read from the published schema.json, with names, types, requiredness, and validation as the document states them. The live government form remains the authoritative source.

Apply / Country of Residence / Select Type

  • applicationCategory enum required

    The category of traveller applying. "Tourists & Visitors" covers tourism, business, or any other reason necessitating a visit to Kenya; "Diplomats" is for holders of Diplomat/Service/Official passports. This schema models the Tourists & Visitors pathway.

    enum: TOURIST_VISITOR | DIPLOMAT
  • residenceCountry string required

    The applicant's country of residence — "the country where you live and pay taxes," per the page's own guidance (a resident Diplomat of Kenya is instructed to select Kenya). Selected from the live portal's own complete country picker (confirmed to include entries such as UNITED STATES OF AMERICA, ITALY, POLAND, UNITED KINGDOM under "Frequently Selected," plus a full A–Z list; not reproduced in full here — see VERIFICATION.md).

  • applicationType enum required

    Whether this is an individual application, or a group application (up to 6 people meeting certain eligibility requirements, e.g. a family, couple, or company submitting on behalf of employees). This schema models the individual pathway.

    enum: INDIVIDUAL | GROUP

Passport Information

  • passportFullName string required

    The applicant's full name, extracted live by the portal's own OCR from the uploaded passport bio-data page (see the `passportBioDataPage` document below) and presented back to the applicant for review before the `passportDeclarationConfirmed` checkbox can be ticked.

    length: 0–200classification: pii
  • passportDateOfBirth date required

    The applicant's date of birth, OCR-extracted from the passport.

    patternclassification: pii
  • passportNationality string required

    The applicant's nationality, OCR-extracted from the passport's MRZ nationality code (e.g. the single-letter code "D" for Germany was returned from the specimen document tested this cycle — ICAO Doc 9303 uses non-3-letter exceptions for a small number of states).

  • passportIssuer string required

    The issuing state/authority code from the passport's MRZ, OCR-extracted (the specimen document tested this cycle returned "D", the same code as its nationality field).

  • passportDocumentNumber string required

    The passport's document number, OCR-extracted.

    length: 0–20classification: sensitive-pii
  • passportExpiryDate date required

    The passport's expiry date, OCR-extracted (labelled "Validity" on the live page).

    pattern
  • passportDeclarationConfirmed boolean required

    The applicant's confirmation that the OCR-extracted passport details above are correct. The live "Continue" button is genuinely disabled (confirmed via its `disabled`/`opacity-50 cursor-not-allowed` state) until this box is checked.

Contact Information

  • phoneNumber string required

    The traveller's own contact phone number. The live page's own guidance states that by law only a valid email and phone number of the traveller may be provided — travel agents, visa/concierge services, and other agencies must supply the traveller's own details, or the application will be denied without refund.

    length: 0–20classification: pii
  • email string required

    The traveller's own email address.

    patternclassification: pii
  • physicalAddress string required

    The traveller's physical address.

    length: 0–300classification: pii
  • occupation enum required

    The traveller's occupation, selected from a closed 57-option list read directly from the live `` element's 12 real options.

    enum: 12 values

Travel Information (Arrival Details)

  • arrivalDate date required

    The traveller's planned date of arrival in Kenya.

    pattern
  • arrivalMode enum required

    The traveller's mode of arrival into Kenya.

    enum: AIR | SEA | LAND

Verification record

Candidate selection

GOV-3288 ("GovSchema Standard Research", 2026-07-16) scouted Kenya's Visa vertical (Kenya was at 3/6: Business Formation, Taxes, National ID modelled; Passport, DMV, Visa open) and left this candidate as a disclosed, ready-to-author backlog item (GOV-3294), which this cycle (GOV-3298) picked up and completed. Kenya's Passport and DMV verticals were confirmed dead ends the same cycle GOV-3294 was scouted (both eCitizen-SSO-gated, no unauthenticated field-level content) and were not re-screened this cycle.

Reaching and walking the live wizard

Walked live with Playwright + Chromium (executablePath pointed at the locally cached Chromium build, LD_LIBRARY_PATH set for the sysroot's libglib-2.0.so.0, waitUntil: 'domcontentloaded' plus explicit settle delays):

  1. https://www.etakenya.go.ke/ → "Apply Now" → /form/apply/start.
  2. "Tourists & Visitors" (vs. "Diplomats") → /form/apply/how-to-apply?type=tourist, an information-only page listing required documents and eligibility/exemption rules — no fields to model.
  3. "Continue" → /form/apply/declaration?type=tourist, "Declaration of Consent" — a required #form_terms_and_conditions checkbox ("I have read and agreed to the above") plus an optional promotional-opt-in checkbox (not modelled — no asterisk, no bearing on the application itself).
  4. "Continue" → /form/apply/residence-country?draft_id=... — the first point a draft_id session identifier is assigned. A full country picker (confirmed values include a "Frequently Selected" shortlist — Italy, Poland, United Kingdom, United States of America — plus a complete A–Z list from Afghanistan through Zimbabwe).
  5. "Continue" → /form/apply/application-type?draft_id=..., "Select Type" — Individual vs. Group application.
  6. Selecting "Individual Application" → /form/apply/individual/passport-information?application_type=individual&draft_id=..., the first step of the numbered wizard shown in the page's own left-hand step navigation: Passport information → Selfie or Photo → Contact Information → Trip Information → Travel Information → Customs Declaration → Required Documents → Confirm and Proceed.

Two genuine biometric/document gates, defeated live

Passport OCR. The Passport Information step accepts a passport bio-data-page upload and runs real server-side OCR against it — not just a file-type/size check. A synthetic solid-colour JPEG (generated via the sharp npm package, the same technique used for rw/irembo/nida-diaspora-application's photo gate) was rejected outright: "Document processing unsuccessful... The document you have provided is not clear enough for us to process." The live "Continue" button remained genuinely disabled (confirmed via its opacity-50 cursor-not-allowed class) throughout. To proceed honestly rather than fabricate a passing OCR result, a real, public-domain specimen passport bio-data-page image was substituted — Bio_data_page_of_German_Passport.png from Wikimedia Commons (a widely used specimen/training image, not a real person's document) — which the live OCR correctly read into six structured fields, each cross-checked against the specimen image's own printed values:

| Field | OCR-extracted value | | --- | --- | | Full Name | ERIKA MUSTERMANN | | Date of Birth | 1964-08-12 | | Nationality | D | | Issuer | D | | Document number | C01X00T47 | | Validity | 2027-02-28 |

A checkbox — "I have reviewed the details as scanned from this identity document and confirm that they are correct." (#passport_declaration) — must be ticked before "Continue" enables; confirmed live.

Selfie/passport biometric face-match. The Selfie or Photo step accepts a selfie upload (or in-browser webcam capture, not exercised this session) and runs live facial-recognition matching against the passport photo. A real, different-person public-domain portrait photo — Face_portrait_(Unsplash).jpg.jpg) from Wikimedia Commons — correctly triggered a "Photo Mismatch" warning ("The photo you have uploaded does not match the photo on the provided ID document"), displaying both photos side by side. Rather than a hard block, the live UI offers an explicit "Use this photo" override button, which was used here solely to continue exercising the wizard for schema-fidelity purposes — not to represent or claim a genuine identity match. This is the same class of finding as this registry's tz/immigration/passport-application and rw/irembo/nida-diaspora-application photo-upload gates, but materially deeper: full document OCR plus live biometric face-matching, not merely an image-quality/content check.

Phoenix LiveView mechanics

The site is built on Phoenix LiveView (data-phx-id attributes, DOM patches streamed over a persistent websocket rather than page reloads). Its "Continue" buttons render with a genuine disabled (opacity-50 cursor-not-allowed) state until every required field on the current step validates. This was live-confirmed to require real keyboard input events, not merely setting an <input>'s .value programmatically (Playwright's .fill() silently failed to register changes with the LiveView socket on this site; switching to .click() + page.keyboard.type() fixed it) — used throughout as corroborating evidence that every field modelled required: true below is genuinely enforced by the live application, not merely asterisked in the markup.

Fields captured (through Travel Information's Arrival Details sub-step)

  • Application setup (before the numbered wizard): applicationCategory (Tourist/Visitor vs. Diplomat), residenceCountry, applicationType (Individual vs. Group).
  • Passport Information: the six OCR-extracted fields plus passportDeclarationConfirmed.
  • Selfie or Photo: no applicant-entered fields beyond the selfiePhoto document itself (see documents[]).
  • Contact Information: phoneNumber, email, physicalAddress, occupation (a closed 57-option list read directly from the live <select id="contact_info_occupation_id">), and an "Emergency Contact" block (emergencyContactName, emergencyContactPhone).
  • Trip Information: travelReason (a closed 12-option list read directly from the live <select id="travel_reason_id">).
  • Travel Information, Arrival Details sub-step: arrivalDate and arrivalMode (a 3-option radio group: air/sea/land).

Disclosed scope boundary

This schema stops at the Arrival Details sub-step of Travel Information. Not reached/modelled this session:

  • The remainder of Travel Information (e.g. departure details, accommodation booking confirmation — both listed as required documents on the "How to Apply" info page but not yet seen as live form fields).
  • Customs Declaration.
  • Required Documents (a checklist step; the "How to Apply" page's own prose lists several conditionally-required documents — e.g. invitation letters for business/family travel, employment contracts, vaccination certificates — depending on purpose of visit, none of which were observed as live form fields this session).
  • Confirm and Proceed (the review/payment step).

This is an accepted scope boundary, consistent with this registry's precedent for tz/immigration/passport-application (stopped at Attachments, before Declaration/Payment/Complete) and rw/irembo/nida-diaspora-application (stopped at step 1 of 3). No eTA fee was paid and no application was actually submitted in producing this schema.

Disclosed judgment calls

  • emergencyContactName/emergencyContactPhone model only the first emergency-contact entry. The live page's own "Add Another" control allows adding further contacts; GovSchema's field.type enum has no repeating/array type, so only the first (required) slot is modelled, consistent with this registry's established convention for such cases.
  • occupation and travelReason are modelled as closed enum types (not free-text string, unlike e.g. residenceCountry) because both were confirmed to be short, complete, directly-enumerable lists (57 and 12 options respectively) read straight from the live <select> elements — unlike the much larger country pickers elsewhere in this schema and this registry, which remain free-text string per established convention.
  • passportNationality/passportIssuer are modelled as free-text string, not a strict ISO-3166 pattern, since the live OCR returned a single-letter code ("D") for the German specimen tested — ICAO Doc 9303 permits non-3-letter exceptions for certain states, so a rigid 3-character pattern would have rejected a genuine, live-observed value.
  • arrivalMode's three options (air/sea/land) were read directly from the three live radio inputs' id attributes (arriving_by_air/arriving_by_sea/arriving_by_land).

Validation

  • node tools/validate.mjs / node tools/validate-ajv.mjs — see the commit history for exact before/after totals (baseline 503 documents prior to this schema, per the registry state at the time of writing).
  • node tools/verify-sources.mjs --base origin/main — confirms the cited source URL.
  • Conformance fixtures under conformance/ke/immigration/eta-visa-application/1.0.0/: valid fixtures plus mutation-control fixtures each raising exactly one error.

GovSchema is independent and is not affiliated with, endorsed by, or operated by the Republic of Kenya or its Directorate of Immigration Services. This schema does not file the application itself; the live source (etakenya.go.ke) is always authoritative.

View the raw record (VERIFICATION.md)

Version history

  • 1.0.0 draft latest this page has verification record schema.json

Independent and non-affiliated

GovSchema is an independent, open-source project. This reference is not produced, reviewed, or endorsed by Directorate of Immigration Services (Ministry of Interior and National Administration, State Department for Immigration and Citizen Services) or any government. The authoritative source is always the live government form and its official instructions.