Skip to main content

Data contracts

This page specifies the reference data Edge Portal expects your systems to supply, and the events it writes back — the answer to "what feed do you take, and what do we get out?". If your reservation system can provide these entities, everything described in the overview works on your real bookings, guests, and itineraries.

Two rules apply throughout:

  • This is the canonical baseline model. Field names below are the platform's canonical shapes; per-tenant mappings from your reservation system's payloads onto them are agreed in the interface contract during implementation workshops. The model is extendable per tenant — see Extending the model. Whatever you cannot supply is either entered on the portal or omitted where optional.
  • Conventions: dates are ISO YYYY-MM-DD and timestamps ISO 8601 with timezone, currency codes are ISO 4217, money is decimal in the booking currency, and identifiers are stable opaque strings from your system — the portal never interprets them.

Inbound: booking feed (read-only)

The feed from your reservation system into the portal. The portal renders from this feed and mutates nothing in it — all guest and agent actions flow back through write-back events. The feed can be pushed on change or pulled by the platform on a schedule; itinerary updates propagate to the live change feed either way.

Booking

The booking header — the unit everything else is scoped to.

FieldRequiredDescription
referenceYesStable booking reference the guest knows, e.g. MT-882401. It identifies the booking but is not an authentication credential — portal access requires the separately defined authentication flow
product.code / product.nameYesTour or cruise product, e.g. MERBOI-260812 / Best of Italy
product.destination_regionYesDrives rules-based variants — for example which pre-travel form applies
product.ship / product.duration_daysNoDisplay
departure_idYesDeparture identifier — itinerary variance is per departure
departure_date / return_dateYesTravel window; all readiness deadlines anchor to departure_date
channelYesdirect | agent — agent-booked guests get a read-only portal, and reminders target the agent until the configured handover point
statusYesconfirmed | cancelled | on_request
currencyYesISO 4217 booking currency, e.g. GBP
cabin_or_roomNoAssigned cabin or room, when applicable

Agent of record

Present when channel is agent. Powers the read-only trade mode and the agent-phase reminder audience.

FieldRequiredDescription
agency_nameYesDisplay and reminder addressing
agency_codeNoYour identifier for the agency
consultant_name / email / phoneNoThe consultant reminders are addressed to

Passengers

One record per traveler on the booking.

FieldRequiredDescription
passenger_idYesStable identifier — write-back events reference it
given_names / surnameYesIdentity as held in your system
leadNoMarks the lead passenger
date_of_birth / email / phoneNoContact and identity detail
passportNodocument_number, nationality, expiry_date — pre-fills the passport step; captured on the portal when absent
forms[]NoPre-travel form status per variant: variant_code, status (not_started | in_progress | complete), completed_at — the variant served is selected by destination rules
dietaryNoCurrent dietary requirements, editable on the portal

Itinerary

The per-departure itinerary, including departure-level variance. Supplying it on change keeps the live feed current.

FieldRequiredDescription
versionYesIncrements on every change — drives the change feed and "updated 2 minutes ago"
updated_atYesTimestamp of the last change
days[].day_number / days[].titleYesDay-by-day structure
days[].date / days[].descriptionNoDetail content
days[].releasedNoProgressive release flag — summary-only until true
days[].variance_noteNoDeparture-specific deviation from the brochure itinerary (mooring, venue, timing)
days[].choiceNoSelectable option set for the day: select_by date, options[], selected
change_events[]NoRecent changes for the live feed strip: occurred_at, day_number, summary, detail

Freshness. How quickly a reservation-system change appears on the portal follows from the feed mode: a feed pushed on change updates the live itinerary in near real time, while a pulled feed is as fresh as its pull interval. The freshness target — and the pull interval where pulling is chosen — is agreed per tenant in the interface contract. Either way the portal shows the honest updated_at ("updated 2 minutes ago"), never an implied freshness the feed does not have.

Flights

Advised or booked air segments. Availability lookups stay on your side — the feed carries the resulting segments only.

FieldRequiredDescription
flight_number / origin / destination / dateYesSegment identity
carrier / departure_time / arrival_timeNoDisplay
sourceYesoperator_booked | self_booked — self-booked flights are advised by the guest for transfer planning
transfer_confirmedNoWhether a transfer is arranged against this segment

Payments

Payment schedule and received payments. Receipts flowing through this feed are what let the portal regenerate the invoice instantly after every payment.

FieldRequiredDescription
gross_totalYesBooking total in the booking currency
balance_due_dateNoAnchors the final-payment readiness deadline
schedule[]YesInstalments: label, amount, due_date, status (due | paid | overdue)
received[]NoPayments received: received_at, amount, method, receipt_reference
card_surcharge_pctNoCard surcharge where applicable in your market
local_railNoReference details for a local payment rail where one is offered — for example a BPAY biller code and customer reference

Processing versus registration. This feed and the payment_registration write-back event carry payment records, not card transactions. When the guest pays on the portal with a method Edge Pay hosts, processing runs on the platform's payment stack: Edge Pay pages processed by the Kaptio Pay service, with per-currency merchant-account routing and per-currency 3D Secure policy (see Brands, currencies & 3DS). Card details stay on that path — captured in gateway-hosted fields — and do not transit your reservation system; see Payment security. Once Kaptio Pay has processed that payment, the portal emits payment_registration so your system records the result: your payment API is the write-back target, not the processing path. Local rails advertised via local_rail are reference details for payment outside the hosted card session; they are not processed by Kaptio Pay. Those receipts still arrive as received[] on this feed and as payment_registration when the portal is the system that learned of them.

Optional extras

Catalog references for extras and upsell offers applicable to the departure. Purchases register back through the write-back events, typically onto your existing upsell API.

FieldRequiredDescription
extra_code / name / priceYesOffer identity and unit price
category / descriptionNoDisplay
price_basisNoper_person | per_booking | per_item
selectedNoAlready purchased on this booking

Pricing sources. An extra is priced in one of two ways, selected per extra in the interface contract — not inferred from a missing price:

  • Catalog / rate-table. The offered unit price is the price on this feed. Rate-table products derive that figure from ingested tables (age bands, trip value, duration) before the feed is supplied.
  • Live quote. At selection time the portal calls the provider quoting API configured for that extra. The catalog row still identifies the extra (extra_code, name, price_basis); price on the feed is indicative or omitted only where the interface contract says the quote is authoritative. The bound quote amount is what extras_registration writes back.

Travel insurance is the canonical example and works both ways. In both cases selection and purchase follow the standard extras flow, registering back through extras_registration.

Outbound: portal write-back events

Everything a guest or agent does on the portal is written back to your systems as an event. Delivery is at-least-once: consumers must deduplicate by event_id before applying side effects, so receiving the same event more than once never repeats the mutation — this matters most for payment and extras registrations.

Delivery semantics. Delivery targets and transport are agreed per tenant in the interface contract — typically HTTPS POSTs onto your existing endpoints (payment registration and upsell registration are the common cases), authenticated with per-tenant credentials held in the platform's secret vault, never in configuration. A delivery counts as acknowledged on a 2xx response received within the timeout agreed in that contract (the Journeys webhook default of 10 seconds is the reference starting point). Non-2xx responses and timeouts are retried with exponential backoff until the retry window in the contract elapses; whether permanent client errors (4xx) stop retries early is also fixed in that contract. Because retries can reorder arrivals, consumers should not assume events arrive in order: order by occurred_at where sequence matters, and persist and check event_id before applying side effects.

Event envelope

FieldRequiredDescription
event_idYesGlobally unique — the idempotency key for at-least-once delivery
booking_referenceYesThe booking the event belongs to
passenger_idNoSet when the event concerns one passenger; null for booking-level events
occurred_atYesWhen the action happened on the portal
actor.roleYesguest | agent | system — agent-booked guests are read-only in the trade model, so guest-actor mutation events only occur on direct bookings or after handover
actor.identifierNoPseudonymous portal session subject (e.g. a hashed email address or an agent code) — never a raw credential or plain email
eventYesExactly one typed payload, discriminated by event.type

Event types

TypePayload highlightsNotes
passport_captureParsed document fields plus a check-digit validation resultCapture is on-device: the document image never leaves the guest's device — only the parsed fields are written back
form_submissionvariant_code plus the answer set (question_code, answer)The variant code identifies the destination-rules form variant served, so the answer set always matches the form your system expects
dietary_updateThe updated dietary stringPer passenger
transfers_acknowledgmentAcknowledgment flag plus any self-booked flights advised for transfer planning
payment_registrationAmount, currency, method, gateway reference, instalment labelTypically maps onto your existing payment registration API; triggers instant invoice regeneration on the portal
extras_registrationextra_code, quantity, amount, added | removedTypically maps onto your existing upsell registration API
reminder_acknowledgmentReminder id, acknowledged by guest | agent, resolution (completed_on_portal | will_action | disputed)Feeds the readiness dashboard history and stops repeat sends
disruption_read_receiptNotice id and read timestampConfirms a guest saw a pushed disruption notice, closing the loop without outbound calls

Example: passport capture event

{
"event_id": "evt_01J9YB2K7Q4C",
"booking_reference": "MT-882401",
"passenger_id": "pax_02",
"occurred_at": "2026-05-04T09:12:44+01:00",
"actor": { "role": "guest", "identifier": "sha256:9f2c…" },
"event": {
"type": "passport_capture",
"document_number": "553902147",
"surname": "CARTER",
"given_names": "ELENA MARIE",
"nationality": "GBR",
"date_of_birth": "1987-03-22",
"expiry_date": "2031-11-05",
"check_digits_valid": true
}
}

PII posture

The portal persists operational state only — readiness progress, acknowledgment history, delivery tracking. Booking and passenger data renders from the feed, and sensitive capture flows are designed to keep PII in transit rather than at rest on the portal side: the passport document image never leaves the guest's device (parsing happens on-device), and the parsed fields travel to your reservation system as a passport_capture event rather than accumulating in a portal-side document store. Where your regulatory environment requires a stricter split between what the platform may cache and what must be fetched in transit at request time, that split is agreed per tenant in the interface contract. Platform-wide residency and encryption are summarised under Data handling (that page currently describes Salesforce-hosted Edge products); card-data scope is under Payment security.

Extending the model

The baseline above is where every implementation starts; it is not where implementations end. Agreed in the interface contract during implementation workshops, per tenant:

  • Tenant-specific fields on any inbound entity — additional booking attributes, passenger flags, or payment metadata your operation relies on.
  • Form variants by destination rules — the variant catalog and the rules that select which form a passenger sees are tenant configuration.
  • Additional event types — write-back surface beyond the eight baseline events, for actions specific to your operation.
  • Mapping onto your existing APIs — where your platform already exposes endpoints (payment registration and upsell registration are common), the corresponding events map onto them rather than requiring new receivers.

For what the portal does with this data, see the Edge Portal overview. For how Edge is hosted and secured, see Architecture & Security.