Skip to main content

journey.yaml reference

This page documents every field in journey.yaml — the configuration file that defines your booking experience. The Meridian Voyages examples preserve the cruise reference implementation; a separate group-touring example shows the same contract without a vessel or deck plan.

The file lives at journeys/journey.yaml in your tenant config repo (or tenants/{tenantId}/journeys/journey.yaml for internal tenants in edge-configs).


tenant_id / journey_id

tenant_id: meridian
journey_id: meridian-cruise
FieldRequiredDescription
tenant_idYesMust match the tenant identifier used in API calls and the config stub in edge-configs.
journey_idYesA unique identifier for this journey definition. Used in logging and diagnostics.

channels

Defines the available booking channels. At least one channel is required.

channels:
- id: b2c-direct
label: "Book Direct"
type: b2c
requires_advisor_id: false
- id: b2b-advisor
label: "Travel Advisor"
type: b2b
requires_advisor_id: true
FieldTypeDefaultDescription
idstringUnique channel identifier. Referenced in live.channel_map.
labelstringDisplay name shown in the channel picker UI.
typeb2c | b2bChannel type. B2B channels show advisor identification before the booking flow.
requires_advisor_idbooleanfalseWhen true, the guest must identify their travel advisor (IATA lookup) before proceeding.

When only one channel is defined, the channel picker is skipped and the flow starts immediately.


steps

An ordered list of step identifiers that defines the booking flow sequence.

steps:
- trip-select
- departure-travellers
- cabin-category
- cabin-pick
- activities-quote
- review-pay
- confirmation

Canonical step IDs

Step IDPurposeFramework behaviour
trip-selectBrowse and select a trip/package
departure-travellersChoose departure date, adults, children, soloSets basket occupancy context
cabin-categorySelect a room/cabin category tierAdvances to cabin-pick if present
cabin-pickPick a room option, or a specific cruise cabin from a deck planThe shared immersive renderer is cruise-specific; touring UIs normally render their own room-option step
room-selectChoose a touring room optionFirst-class neutral alias that advances through the same selection boundary without a cruise deck plan
activities-quoteChoose add-on activitiesOptionally triggers AI quote letter
review-payReview basket totals and complete paymentDeposit vs full payment based on schedule
confirmationShow booking reference and welcome content

Step ordering rules

  • Immersive cruise cabin selection (deck plan with live availability overlays) renders only when cabin-pick appears in the steps list AND comes after departure-travellers.
  • Steps after cabin-pick are gated — the guest cannot advance without choosing the required room or cabin option.
  • Touring room selection uses room-select; it is also gated and advances when the room option has been selected.
  • Custom step IDs are allowed for tenant-specific screens; the framework passes unrecognised IDs to the tenant's step renderer.

branding

Visual identity metadata available to the tenant UI.

branding:
logo_url: https://assets.example.com/meridian-voyages/logo.svg
primary_color: "#1B365D"
font_family: "Inter, system-ui, sans-serif"
FieldTypeDescription
logo_urlstringURL of the tenant logo, displayed in the journey chrome.
primary_colorstringHex color code for the primary brand accent.
font_familystringCSS font-family stack.

These values are available to tenant code via the /api/journeys/v1/config endpoint. Framework components use CSS custom properties for theming — see Tenant UI source.


behavior

Controls journey-wide behavioural switches.

behavior:
deposit_display: true
currency: USD
ai_quote_letter: true
default_occupancy: 2
FieldTypeDefaultDescription
deposit_displaybooleantrueWhether deposit amounts and balance-due dates are shown in the review step.
currencystringUSDDefault display currency (ISO 4217). The tenant UI may allow guests to switch currencies.
ai_quote_letterbooleanfalseEnables the AI-generated quote/welcome letter feature (Anthropic integration).
default_occupancyinteger2Default number of adults when occupancy is not specified. Minimum 1.

ui

Controls the HTML shell that wraps the tenant's bundled UI. These fields are injected at bundle time by the platform's esbuild pipeline.

ui:
title: "Meridian Voyages — Book Your Cruise"
favicon_url: "https://assets.example.com/meridian-voyages/favicon.ico"
meta:
description: "Book your expedition cruise with Meridian Voyages"
og:title: "Meridian Voyages Booking"
og:image: "https://assets.example.com/meridian-voyages/og-image.jpg"
dependencies:
framer-motion: "https://esm.sh/framer-motion@11"
zustand: "https://esm.sh/zustand@4"
FieldTypeDefaultDescription
titlestring"{tenantId} — Journey"The HTML <title> tag.
favicon_urlstringnoneURL for the page favicon (<link rel="icon">).
metaRecord<string, string>noneKey-value pairs rendered as <meta> tags. Keys starting with og: use property attribute; others use name.
dependenciesRecord<string, string>noneAdditional entries added to the ESM import map beyond React. Keys are bare module specifiers; values are CDN URLs.

Import map

The platform provides React 18 in the import map by default:

{
"imports": {
"react": "https://esm.sh/react@18.3.1",
"react-dom": "https://esm.sh/react-dom@18.3.1",
"react-dom/client": "https://esm.sh/react-dom@18.3.1/client",
"react/jsx-runtime": "https://esm.sh/react@18.3.1/jsx-runtime"
}
}

Entries from ui.dependencies are merged into this map. Your tenant UI can then import those packages by bare specifier without bundling them — they load from CDN at runtime.


catalog

Optional metadata that groups room/cabin options and, for cruise journeys, supplies vessel deck plans.

catalog:
category_tiers:
- name: Balcony Staterooms
codes: [balcony-sup, balcony-a, balcony-b, balcony-c]
sort_order: 1
- name: Horizon Staterooms
codes: [horizon-sup, horizon-sup-s, horizon-s, horizon-tw, horizon-tr]
sort_order: 2
- name: Suites
codes: [captain, junior]
sort_order: 3
vessels:
- code: meridian-explorer
name: Meridian Explorer
deck_plan: "https://assets.example.com/deck-plans/meridian-explorer.svg"
- code: meridian-voyager
name: Meridian Voyager

category_tiers

Groups room or cabin categories into display tiers for the category selection step.

FieldTypeDefaultDescription
namestringDisplay name for the tier group (e.g. "Balcony Staterooms").
codesstring[]List of category slugs or names belonging to this tier. Mapped to room/cabin categories from the catalog API.
sort_ordernumber0Display order of the tier (ascending).

vessels

Optional cruise vessel reference data for deck plan rendering. Omit this block for group touring.

FieldTypeDescription
codestringVessel identifier (matched against catalog trip shipName or code).
namestringDisplay name.
deck_planstringOptional URL to a deck plan asset (SVG or image). Used by the framework's DeckPlan component.

provider

provider: live
ValueDescription
mockUses fixture data for the catalog and simulated basket operations. No external dependencies. Ideal for local development and UI iteration.
liveConnects to KTAPI (catalog), Basket Service (commercial operations), and Keycloak (auth). Requires the live: block.

Default: mock.


live

Required when provider: live. Contains the per-tenant commercial identifiers the live provider needs to create baskets and read the catalog from your Salesforce org.

live:
catalog_model: cruise
package_filter:
package_ids:
- a299j000002M59ZAAS
tax_profile_id: a477F0000000YtgQAE
default_account_id: 001On00000fUpVLIA0
service_level_id: null
channel_map:
b2c-direct: a1K7F000001lZ6WUAU
from_price_currencies:
- USD
- AUD
sf_environment: null

Catalog model

catalog_model controls how live catalog inventory is interpreted:

ValueDefaultBehaviour
cruiseYesUses cruise details, cabin types, physical cabin inventory, and optional vessel/deck-plan metadata.
touringNoUses active package departures and required PriceCategories package options as room configurations. From-prices and room availability come from package option pricing; no vessel or physical cabin is required.

The neutral routes /catalog/trips and /catalog/rooms work for both values. The original /catalog/voyages and /catalog/cabins paths remain aliases, and their established response field names remain unchanged.

Package filter

Determines which packages from your org appear in the journey catalog.

FieldTypeDescription
package_filter.package_idsstring[]Explicit allow-list of KTAPI package Salesforce IDs. Environment-specific — prefer package_codes for cross-environment configs.
package_filter.package_codesstring[]Cross-environment package external codes. Resolved to IDs at runtime.
package_filter.active_onlytrueInclude every active package returned by KTAPI for the tenant.

You must provide either package_ids / package_codes or active_only — not both. The deprecated top-level live.package_ids field is accepted for backward compatibility but package_filter is preferred.

Commercial IDs

Each field has an _id variant (Salesforce record ID, environment-specific) and a _code variant (cross-environment external code, resolved at runtime). You must provide at least one variant for required fields.

FieldRequiredDescription
tax_profile_id / tax_profile_codeYes (one)The Salesforce tax profile applied to basket pricing.
default_account_id / default_account_codeYes (one)Fallback Salesforce account for B2C guest bookings (when no account is identified).
service_level_id / service_level_codeNoPackage service level. null uses the package default.

Channel map

Maps journey channel IDs (from channels[].id) to Salesforce channel record IDs or codes.

channel_map:
b2c-direct: a1K7F000001lZ6WUAU
b2b-advisor: a1K7F000001lZ6XIAU

Values that look like Salesforce IDs (15 or 18 characters starting with a known prefix) are used directly. Other values are treated as external codes and resolved at runtime.

Catalog pricing

FieldTypeDefaultDescription
from_price_currenciesstring[]["USD"]ISO currency codes for which catalog "from prices" are computed. Each currency costs a KTAPI call per departure — keep the list to currencies your guests actually use.

Salesforce environment

FieldTypeDefaultDescription
sf_environmentstring | nullnullThe salesforce_environments key from blueprint.yaml where live bookings land. Used by enrichment lookups to skip per-environment itinerary searches. Set to null when not configured.

external_ancillaries

Optional configuration for tenant-owned third-party service providers. The UI only exposes this feature when the block is present.

external_ancillaries:
providers:
- id: insurance
quote_url: https://insurance.example.com/v1/quotes
timeout_ms: 10000
auth:
credential_env: INSURANCE_API_TOKEN
header: Authorization
scheme: Bearer
persistence:
type: edge_composite
sf_environment: uat
apex_path: /services/apexrest/journeys/external-ancillaries
FieldRequiredDescription
providers[].idYesLowercase provider identifier used in the Journeys API path.
providers[].quote_urlYesHTTPS endpoint called server-to-server for quotes.
providers[].timeout_msNoProvider timeout from 500 to 30,000 ms. Default: 10,000 ms.
providers[].auth.credential_envNoName of the runtime environment variable containing the credential. Never store the credential in YAML.
providers[].auth.headerNoAuthentication header. Default: Authorization.
providers[].auth.schemeNoPrefix applied to the credential. Default: Bearer.
persistence.typeFor checkout write-throughMust be edge_composite.
persistence.sf_environmentNoSalesforce environment; falls back to live.sf_environment.
persistence.apex_pathFor checkout write-throughExisting Apex REST endpoint that accepts the verified selection contract.

Production write-through also requires JOURNEYS_EDGE_COMPOSITE_URL and COMPOSITE_API_KEY in the Journeys runtime. When persistence is not fully configured, booking fails explicitly before KTAPI booking creation rather than dropping the external service.

See Third-party services for the complete trust and persistence flow.


Environment overrides

For per-environment configuration (e.g. different package IDs in staging vs production), create an overlay file:

journeys/
journey.yaml # Base configuration
journey.staging.yaml # Overrides for EDGE_ENVIRONMENT=staging
journey.production.yaml # Overrides for EDGE_ENVIRONMENT=production

The platform deep-merges the environment file into the base configuration. Arrays and primitives in the override replace base values; objects are recursively merged.

# journey.staging.yaml — only override what differs
live:
package_filter:
package_ids:
- a299j000002STAGING_ID
tax_profile_id: a477F000STAGING_TAX
default_account_id: 001On000STAGING_ACC
channel_map:
b2c-direct: a1K7F000STAGING_CH

The active environment is determined by the EDGE_ENVIRONMENT variable on the platform service.


Complete examples

Group touring (live provider)

This fictional example models a dated escorted tour with Twin and Single room choices. It contains no customer-specific identifiers:

tenant_id: example-touring
journey_id: example-group-tour
channels:
- id: b2c-direct
label: Book Direct
type: b2c
requires_advisor_id: false
- id: b2b-advisor
label: Travel Advisor
type: b2b
requires_advisor_id: true
steps:
- trip-select
- departure-travellers
- cabin-category
- cabin-pick
- activities-quote
- review-pay
- confirmation
branding:
logo_url: https://assets.example.com/example-touring/logo.svg
primary_color: "#174B45"
font_family: "Inter, system-ui, sans-serif"
behavior:
deposit_display: true
currency: AUD
ai_quote_letter: false
default_occupancy: 2
ui:
title: "Example Touring — Book Your Trip"
meta:
description: "Choose a departure and room configuration"
catalog:
category_tiers:
- name: Shared rooms
codes: [twin room]
sort_order: 1
- name: Single rooms
codes: [single room]
sort_order: 2
provider: live
live:
catalog_model: touring
package_filter:
package_codes:
- SOUTHERN-HIGHLANDS-12D
tax_profile_id: a47000000000001AAA
default_account_id: 001000000000001AAA
channel_map:
b2c-direct: a1K000000000001AAA
b2b-advisor: a1K000000000002AAA
from_price_currencies:
- AUD

The corresponding catalog exposes dated trips such as “Southern Highlands Explorer” and room rows such as “Twin Room” and “Single Room”. The room rows are required package options with live price and inventory context, not physical hotel-room assignments.

Mock provider (local development)

tenant_id: meridian
journey_id: meridian-cruise
channels:
- id: b2c-direct
label: "Book Direct"
type: b2c
requires_advisor_id: false
- id: b2b-advisor
label: "Travel Advisor"
type: b2b
requires_advisor_id: true
steps:
- trip-select
- departure-travellers
- cabin-category
- cabin-pick
- activities-quote
- review-pay
- confirmation
branding:
logo_url: https://assets.example.com/meridian-voyages/logo.svg
primary_color: "#1B365D"
font_family: "Inter, system-ui, sans-serif"
behavior:
deposit_display: true
currency: USD
ai_quote_letter: true
provider: mock

Live provider (staging/production)

tenant_id: meridian
journey_id: meridian-cruise
channels:
- id: b2c-direct
label: Book Direct
type: b2c
requires_advisor_id: false
steps:
- trip-select
- departure-travellers
- cabin-category
- cabin-pick
- activities-quote
- review-pay
- confirmation
branding:
logo_url: https://assets.example.com/meridian-voyages/logo.svg
primary_color: "#1B365D"
font_family: "Inter, system-ui, sans-serif"
behavior:
deposit_display: true
currency: USD
ai_quote_letter: true
default_occupancy: 2
ui:
title: "Meridian Voyages — Book Your Cruise"
favicon_url: "https://assets.example.com/meridian-voyages/favicon.ico"
meta:
description: "Book your expedition cruise with Meridian Voyages"
catalog:
category_tiers:
- name: Balcony Staterooms
codes: [balcony-sup, balcony-a, balcony-b, balcony-c]
sort_order: 1
- name: Horizon Staterooms
codes: [horizon-sup, horizon-sup-s, horizon-s, horizon-tw, horizon-tr]
sort_order: 2
- name: Suites
codes: [captain, junior]
sort_order: 3
vessels:
- code: meridian-explorer
name: Meridian Explorer
- code: meridian-voyager
name: Meridian Voyager
provider: live
live:
catalog_model: cruise
package_filter:
package_ids:
- a299j000002M59ZAAS
tax_profile_id: a477F0000000YtgQAE
default_account_id: 001On00000fUpVLIA0
service_level_id: null
channel_map:
b2c-direct: a1K7F000001lZ6WUAU
from_price_currencies:
- USD
- AUD
sf_environment: null