# Ready To Fly

# 1. Integration scheme

# 1.1. Overview

Zamna Client provides Ready To Fly API for airline applications and touch-points to interact with:

High-level architecture diagram

Clients can either build their own UI on top of the API (web check-in, native mobile apps), or use the Zamna WebView — a hosted frontend that implements the full passenger flow.

# 1.2. Zamna WebView

When the Zamna WebView (frontend application) is used, an additional component is deployed alongside the API:

High-level architecture diagram

Zamna ApiServers can be integrated by Zamna with your DCS and other internal/external systems for orchestration, supporting complex workflows and rich use cases.

After deployment of the Zamna Client stack, navigate a passenger to the /start2 endpoint (swagger (opens new window), redoc (opens new window)) with an encrypted booking id — the passenger is authenticated and redirected to the WebView with a session JWT. See WebView integration for browser and embedded setup.

# 1.3. Authentication model

From a high-level point of view, the basic authentication model relies on airline apps having a key (AES/RSA, etc.), by which they can encrypt a booking identifier and pass it to a mobile/web app, which in turn uses it to invoke Zamna Client API and obtain a session token for all other endpoints:

High-level API authentication model

The encrypted_booking_id query parameter value is:

url_encode(base64_encode(encrypted_booking_data))

URL-encoding is required because base64 output contains +, /, and = characters that are not safe in query strings.

Alternatively, an airline backend can retrieve a new session token from Zamna Client and pass it to a mobile/web app to directly interact with Zamna Client APIs:

Alternative API authentication model

Zamna Client's authentication server (shipped as part of the Zamna Client stack) can be extended with other authentication approaches adopted by airlines.

Optional index login (booking id + surname)

When WebView is deployed with REACT_APP_DISSALOW_INDEX_LOGIN=false, passengers can open the WebView directly and sign in with booking id and surname on the index login page. That flow calls POST /start-with-booking-id-and-surname and requires reCAPTCHA Enterprise on both WebView (REACT_APP_RECAPTCHA_SITE_KEY) and ApiServer (SERVER__RECAPTCHA_SECRET). This endpoint is not registered when SERVER__RECAPTCHA_SECRET is unset.

The default integration path keeps index login disabled (REACT_APP_DISSALOW_INDEX_LOGIN=true) and uses /start2 with an encrypted booking id instead — no reCAPTCHA setup required. See WebView — Configuration.

# 1.4. API docs

Zamna Ready To Fly API utilises OpenAPI standard: Zamna Ready To Fly OpenAPI specification (opens new window), which can be used to auto-generate native API clients across a variety of platforms (OpenAPI generator (opens new window)).

Swagger (opens new window) and redoc (opens new window) documentation is also available.

# 2. Flow

# 2.1. Overview

High-level API flow overview

The passenger flow is a wizard driven by paxSession.required_action. After each API call that changes session state, read the returned PaxSession and use required_action to determine the next step.

Stage Summary
Init Create session, obtain token
Consent Optional — set consent if not provided at init
Travel doc Scan, upload, or manually enter an allowed travel document
Questions Optional — HaveDocument, declaration, and pick-from-list questions
Resolve Resolve checklist items one by one
Ready to Fly All requirements satisfied

Steps Travel doc, Questions, and Resolve apply per passenger. In MultiPax bookings, repeat them for each passenger in the session.

Localisations — for UI

Zamna Client API provides all necessary localisations for names, titles and descriptions for supported languages (Accept-Language header is supported by all relevant endpoints)

TIP

Every endpoint that changes session state returns its updated version on success

# 2.2. Init, get token & session

Browser / WebView: call /start2 (swagger (opens new window), redoc (opens new window)). The backend creates a MultiPax session and responds with 302 redirect to the WebView with pax_check_token. See WebView — Browser integration for full parameter details.

Programmatic API clients: call /start (swagger (opens new window), redoc (opens new window)) to retrieve session_id and pax_check_token as JSON — no redirect.

Consent (true/false) may be set as part of session initialisation via the consented parameter, skipping the consent step in the UI.

At any point, the current MultiPax session state can be retrieved with GET /session/{sessionId} (swagger (opens new window), redoc (opens new window)).

Current Pax session state can be queried from GET /session/{sessionId}/pax-session/{paxSessionId} (swagger (opens new window), redoc (opens new window)).

When building your own UI, poll GET /session/{sessionId} after init and iterate through each passenger's PaxSession, using required_action to drive navigation.

A MultiPax session may contain several Pax sessions (passengers). All actions (apart from consent) are performed at Pax session level.

MultipaxSession.paxs is the full list of passengers on the booking. If more than one passenger is loaded, present a passenger picker in the UI before continuing with individual steps:

Sample UI, multipax

If consent was not set during initialisation, required_action on each PaxSession will be PROVIDE_CONSENT_RESPONSE.

No questions or checklist items will be present until consent is captured.

Consent should be taken from the passenger in the UI and submitted with POST /session/{sessionId}/set-consent (swagger (opens new window), redoc (opens new window)):

{ "consent": true }

Returns the updated MultiPax session.

# 2.4. Travel document verification

This step is triggered when is_travel_document_verified = false or required_action = PROVIDE_NATIONALITY_OR_BIRTHDATE — meaning the travel document has not yet been provided or verified.

# Which document?

Read checklist.allowed_travel_documents_set — this lists all acceptable travel document types for this passenger and journey. The document is not always a passport; it may be a national ID card or another type depending on route, rules, and client configuration.

Each entry in allowed_documents is an AllowedDoc with type, title, provision_methods, and scanner configuration (sides_configuration, sides_expectation).

If allowed_travel_documents_set.force_document_type_required = true and multiple types are allowed, present a document-type picker before scanning or uploading (same pattern as checklist item resolution in §2.8).

Sample UI, travel document type picker

# Resolution methods

For each allowed travel document type, the passenger may choose from the available provision_methods:

Method Endpoint
SCAN POST .../recognise-documentPOST .../apply-document/recognised
UPLOAD POST .../recognise-documentPOST .../apply-document/recognised
MANUAL POST .../apply-document/travel-document

# Scan / upload flow (recognise → apply)

Document recognition is a two-step process:

Step 1 — Recognise: POST /session/{sessionId}/pax-session/{paxSessionId}/recognise-document (swagger (opens new window), redoc (opens new window))

Multipart form fields:

Field Description
method SCAN or UPLOAD
expected_document_types Comma-separated document type strings from allowed_travel_documents_set
page_index_to_process Page index for multi-page documents
files Binary file(s)

Configure the scanner from sides_configuration and sides_expectation on the selected AllowedDoc.

Response on success:

{
  "data": {
    "documents": [...],
    "signature": "...",
    "document_type": "PASSPORT"
  }
}

Step 2 — Apply: POST .../apply-document/recognised (swagger (opens new window), redoc (opens new window))

Re-submit the recognised payload with the signature:

{
  "documents": [...],
  "signature": "...",
  "document_type": "PASSPORT",
  "method": "SCAN",
  "is_travel_document": true
}

The signature ties the recognise response to the apply request — do not modify the documents payload between steps.

# Manual entry

For manual travel document entry, use POST .../apply-document/travel-document (swagger (opens new window), redoc (opens new window)):

{
  "travel_document": {
    "document_type": "PASSPORT",
    "number": "AD33344455",
    "expiry_date": "2030-01-01",
    "country_code": "GBR",
    "birthdate": "1980-01-01",
    "nationality": "GBR"
  },
  "ignore_mistakes": false
}

# Outcome

When successful, nationality and birthdate are typically derived from the verified document (or supplied via manual entry). There is no separate nationality/birthdate step in the wizard.

DCS updates

In the background, Zamna Client adds the travel document to the DCS and marks it as verified

# 2.5. HaveDocument questions

After travel document verification, present HaveDocument questions as a separate wizard step before declarations.

Filter checklist.questions where type = "have-document-question" and answer is not yet set.

Each question includes:

  • doc_category_title — document category (localised)
  • doc_title — specific document title (localised)
  • country — relevant country code
  • sample_image — optional specimen image

Submit answers via POST /session/{sessionId}/pax-session/{paxSessionId}/answers (swagger (opens new window), redoc (opens new window)):

{
  "answers": [
    { "type": "bool-answer", "question_id": "HelbxGxFg0gpdAdnumztVA==", "value": true }
  ]
}

Returns updated Pax session. Once all HaveDocument questions are answered, the checklist may expose further questions or begin forming items.

Sample images for questions

For key questions, API returns sample image URLs (eg document samples)

Sample UI, have-document questions

# 2.6. Declaration & pick-from-list questions

Present remaining questions where type = "declaration-item" or type = "pick-from-list-question".

# Declaration items

declaration-item questions are yes/no assertions. Submit using confirm_declarations and refute_declarations arrays (not the answers array):

{
  "confirm_declarations": ["declaration_id_1"],
  "refute_declarations": ["declaration_id_2"]
}

Only include declaration IDs the passenger explicitly confirmed or refuted.

Sample UI, declaration items

# Pick-from-list questions

pick-from-list-question presents a single choice (eg passport type, onward flight). Submit via answers:

{
  "answers": [
    { "type": "from-list-answer", "question_id": "abc123", "value": "DIPLOMATIC" }
  ]
}

Sample UI, pick-from-list question

# 2.7. Address (US-bound)

If the passenger is travelling to the US and is not a US national, required_action will be PROVIDE_ADDRESS.

Submit via POST /session/{sessionId}/pax-session/{paxSessionId}/address (swagger (opens new window), redoc (opens new window)):

{
  "address": {
    "lineOne": "123 Main St",
    "city": "New York",
    "state": "NY",
    "postalCode": "10001",
    "countryCode": "US"
  }
}

# 2.8. Resolve checklist items one by one

Once all questions are answered, the checklist is formed and checklist.items lists document requirements. If any items are not yet RESOLVED, required_action will be RESOLVE_ITEMS.

Present unresolved items to the passenger and resolve them one at a time:

Sample UI, checklist items

# Allowed documents

Each checklist item includes allowed_documents_set:

Field Purpose
allowed_documents List of AllowedDoc entries that can satisfy this item — each with its own type, title, provision_methods, and scanner config
force_document_type_required When true, the passenger must pick a document type before scan/upload/manual if multiple types are allowed

How to use it in your UI:

  1. Find the next item where status != RESOLVED.
  2. Read item.allowed_documents_set.allowed_documents.
  3. If force_document_type_required = true, or more than one document is allowed, show a document-type picker (use each entry's title).
  4. After the passenger selects a document, show only that entry's provision_methods — do not offer scan if the selected doc only supports upload, etc.
  5. Update action labels to match the selection (eg "Scan US visa in passport").
  6. Call recognise-document with expected_document_types set to the selected AllowedDoc.type.
  7. Call apply-document/recognised with the matching document — the API returns document-kind-mismatch if the provided document does not match the selected or expected type.

If only one document is allowed and force_document_type_required = false, skip the picker and proceed directly to resolution methods for that document.

Sample UI, checklist document type picker

Example: a US Visa or BCC item allows either a US visa in passport or a Border Crossing Card. The passenger selects one option first; scan/upload actions then apply only to that choice.

# Resolution methods

Present available provision_methods (SCAN / UPLOAD / MANUAL) for the selected document type:

Sample UI, resolution methods

# Scan / upload

Same two-step recognise → apply flow as §2.4, but with is_travel_document: false (unless resolving a travel document checklist item):

  1. POST .../recognise-document — pass expected_document_types from the selected AllowedDoc.type
  2. POST .../apply-document/recognised — include is_travel_document matching the checklist item

# Manual entry

For non-travel documents (eg onward ticket), use POST .../apply-document/manual (swagger (opens new window), redoc (opens new window)).

On success, the item becomes RESOLVED and the updated Pax session is returned:

Sample UI, checklist item resolved

DCS updates

In the background, Zamna Client adds required documents to the DCS and marks them as verified

# Error handling

Apply and recognise endpoints return error.operationError with a type discriminator. Common errors:

Type Description
document-kind-mismatch Wrong document type scanned or uploaded
not-all-sides-scanned Required document sides not provided
no-mrz-side-scanned MRZ side of document not scanned
mrz-validation-failed MRZ checksum verification failed
mrz-to-viz-mismatch MRZ data does not match visual inspection zone
file-too-large Uploaded file exceeds size limit
file-type-not-supported File format not supported
id-mismatches Document data does not match booking (name, birthdate, etc.)
rules-mismatches Document fails entry rules (eg expiry date)
signals-mismatches Document fails signals validation
provide-passport Travel document required before this document can be applied
no-items-to-apply-document-to No matching checklist item for the document provided

Sample UI, resolution error

Some checklist items can be resolved by different document types (eg US visa in passport vs Border Crossing Card, or Indian embassy visa sticker vs Indian E-Visa PDF). Always require an explicit document-type selection when force_document_type_required = true before calling recognise/apply endpoints — see Allowed documents above.

# 2.9. Ready To Fly

Once all checklist items are RESOLVED, checklist.resolution_status becomes READY_TO_FLY and required_action is null:

Sample UI, passenger is Ready to Fly

Browser mode: redirect to return_url?ready_to_fly=true.

Embedded mode: WebView emits closeFlow { reason: "ready_to_fly" } via the native bridge — see WebView — Embedded integration.

DCS updates

In the background, Zamna Client sets/removes any required inhibitors, flags and/or SSRs

# 3. Main models and statuses

# 3.1. MultiPax session

Booking level

  • id — MultiPax session id
  • journey — journey details (departure, transit, arrival)
  • paxs — collection of Pax sessions

# 3.2. Pax session

Passenger level

  • pax_session_id — Pax session id, starts with pax_
  • required_action — next action for this passenger (see table below)
  • consented — consent response (true/false), or null if not yet provided
  • pax — basic passenger details from booking (first name, last name, birthdate)
  • checklist — Checklist (questions and items)
  • is_travel_document_verified — whether the travel document has been verified
  • is_visa_verified — whether visa document is saved in DCS
  • is_rp_verified — whether residence permit document is saved in DCS
RequiredAction Description
null No action required — present current Checklist status to passenger
PROVIDE_CONSENT_RESPONSE Consent response is required
PROVIDE_NATIONALITY_OR_BIRTHDATE Travel document not yet provided — proceed to travel document verification (§2.4)
ANSWER_QUESTIONS Unanswered questions remain — look at checklist.questions
PROVIDE_ADDRESS US destination address required for non-US nationals
RESOLVE_ITEMS Unresolved checklist items remain — look at checklist.items

# 3.3. Checklist

  • id — checklist id

  • status — checklist status

    Status Description
    ON_HOLD Checklist is on hold — temporary status, usually during rules updates
    FINALIZED Checklist is finalised (usually 4 hours post departure), no more edits allowed
    ACTIVE Checklist is active — look at resolution_status
  • resolution_status — checklist resolution status

    Resolution status Description
    UNKNOWN Temporary status — usually during rules updates
    ENTRY_NOT_ALLOWED Entry not allowed with current answers — passenger may change answers to proceed
    NOT_ELIGIBLE Passenger not eligible for online document verification
    ACTION_REQUIRED Questions or items require action
    READY_TO_FLY All requirements satisfied — passenger is Ready to Fly

    DCS updates

    In the background, Zamna Client sets/removes any required inhibitors, flags and/or SSRs

  • nationality — passenger nationality (ISO alpha-3), or null if not yet known

  • has_nationality_questiontrue if nationality affects rules and has not yet been provided

  • birthdate — passenger birthdate, or null if not yet known

  • has_birthdate_questiontrue if birthdate affects rules and has not yet been provided

  • allowed_travel_documents_set — all acceptable travel document types for the travel document step; available early, before items are formed (see §2.4)

  • questions — list of questions to present to passenger; null until nationality/birthdate are collected

  • items — list of checklist items; null until all questions are answered and checklist is formed

# 3.4. Question types

Questions use a type discriminator. Three subtypes:

# have-document-question

Boolean "I have {document}" question, shown as a separate wizard step (§2.5).

Field Description
id Question id
type "have-document-question"
is_relevant Whether question applies given current answers
answer Previously provided answer, or null
doc_category_title Document category title (localised)
doc_title Document title (localised)
country Relevant country code
sample_image Optional specimen image

# declaration-item

Yes/no declaration, shown in the declarations step (§2.6).

Field Description
id Declaration id
type "declaration-item"
is_relevant Whether declaration applies given current answers
answer Previously provided answer, or null
question_title Declaration title (localised)
default_value Default answer value
sample_image Optional specimen image

# pick-from-list-question

Single choice from a list (eg passport type, onward flight).

Field Description
id Question id
type "pick-from-list-question"
is_relevant Whether question applies given current answers
answer Previously selected option id, or null
question_title Question title (localised)
options Array of { id, title } choices

Localisations — for UI

All titles and descriptions are localised and returned by Zamna Client API (Accept-Language header is supported by all relevant endpoints)

# 3.5. Answer types

Answers are submitted via POST .../answers in a SetAnswersRequest:

{
  "nationality": "GBR",
  "birthdate": "1980-01-01",
  "answers": [...],
  "confirm_declarations": ["declaration_id"],
  "refute_declarations": ["declaration_id"]
}

Two answer subtypes (inside answers array):

# bool-answer

For have-document-question questions:

{ "type": "bool-answer", "question_id": "abc123", "value": true }

# from-list-answer

For pick-from-list-question questions:

{ "type": "from-list-answer", "question_id": "abc123", "value": "DIPLOMATIC" }

confirm_declarations and refute_declarations are top-level arrays of declaration id strings — not inside answers. Use these for declaration-item questions.

# 3.6. Checklist item

Checklist items use a type discriminator:

  • document-requirement — a document the passenger must provide and verify
  • info-item — informational only (is_info = true), cannot be resolved (eg USA ESTA notice)

For document-requirement items:

  • id — checklist item id

  • item_type — item type string (eg PASSPORT, VISA)

  • item_territory — territory suffix when applicable (eg USA → displayed as VISA/USA)

  • title — title (localised)

  • description — description (localised)

  • status — item status

    Status Description
    NOT_YET_RESOLVED Item not resolved
    VERIFICATION_REQUIRED Verification (scan/upload) required to resolve item
    RESOLVED Item resolved
  • allowed_documents_set — set of documents which can be used to resolve this item (AllowedDocumentsSet)

Localisations — for UI

All titles and descriptions are localised and returned by Zamna Client API (Accept-Language header is supported by all relevant endpoints)

# 3.7. AllowedDocumentsSet

  • allowed_documents — list of AllowedDoc entries
  • force_document_type_required — if true, passenger must pick a document type from allowed_documents before resolving

# 3.8. AllowedDoc

  • type — document type string (eg USA_GREEN_CARD, PASSPORT)

  • title — title (localised)

  • description — description (localised)

  • provision_methods — ways to resolve

    Provision method Description
    MANUAL Document can be typed in manually
    SCAN Document can be scanned with camera
    UPLOAD Document can be uploaded as file
  • sides_configuration — what the document physically is

    Sides configuration Description
    SINGLE_SIDE_OR_FILE One side (eg passport MRZ page) or one file (eg PDF E-Visa)
    MULTIPLE_SIDES_OR_FILES Multiple sides (eg US Green Card front and back) or multiple files
  • sides_expectation — what is expected from the passenger

    Sides expectation Description
    SINGLE_SIDE_OR_FILE Single side expected (usually MRZ side), or one file
    MULTIPLE_SIDES_OR_FILES Multiple sides or files expected

# 3.9. Document recognition

Document scan and upload use a two-step recognise → apply flow.

# Step 1: Recognise

POST /session/{sessionId}/pax-session/{paxSessionId}/recognise-document

Multipart form:

Field Description
method SCAN or UPLOAD
expected_document_types Comma-separated document type strings
page_index_to_process Page index for multi-page capture
files Binary file(s)

Response:

{
  "data": {
    "documents": [...],
    "signature": "...",
    "document_type": "PASSPORT"
  }
}

# Step 2: Apply recognised

POST /session/{sessionId}/pax-session/{paxSessionId}/apply-document/recognised

{
  "documents": [...],
  "signature": "...",
  "document_type": "PASSPORT",
  "method": "SCAN",
  "is_travel_document": true,
  "additional_pax_ids": []
}
  • signature — must match the value from the recognise response; do not modify documents between steps
  • is_travel_documenttrue when applying a travel document (§2.4), false for checklist items (§2.8)
  • additional_pax_ids — optional list of other pax session ids to apply the same document to

# Recognition errors

Returned in error.operationError with type discriminator:

Type Description
document-kind-mismatch Scanned document does not match expected types
not-all-sides-scanned Not all required sides provided
no-mrz-side-scanned MRZ side not scanned
no-barcode-scanned Barcode not present
mrz-validation-failed MRZ checksum failed
mrz-to-viz-mismatch MRZ does not match visual zone
barcode-to-doc-mismatch Barcode data does not match document
file-type-not-supported File format not supported
document-type-not-supported Document type not supported
file-too-large File exceeds size limit
unknown-error Unexpected processing error

# 4. Platform stats

Zamna Client stack collects operational stats in the local PostgreSQL database, deployed with an Airline.

Each entry is marked with external identifiers (booking_id / session_id), thus stats database can be used as a data source for any modern BI tools and platforms.

Please refer to the detailed reference

High-level overview of stats database