> ## Documentation Index
> Fetch the complete documentation index at: https://voyant.travel/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Use Voyant Connect in a deployment

> Wire Voyant Connect supplier inventory into a deployment as catalog source adapters: set the env, build the source-adapter registry, populate the catalog with the discovery sync, and let sourced products flow through search, quote, and reserve back to the originating connection.

[Voyant Connect](/docs/connect/overview) is the supplier and inventory connectivity
layer. The Connect product is the **control plane** where you manage operators,
connections, supplier credentials, provider registrations, grants, and webhooks.
Your deployment is a **consumer**: it enumerates an operator's active
connections, reads catalog and search documents, searches live availability, and
forwards reserve, cancel, and status calls back to Connect.

This guide covers the deployment side. You connect a deployment to Connect by
registering each connection as a catalog
[`SourceAdapter`](/docs/connect/connect-adapter), so sourced inventory appears in
catalog search next to owned inventory and routes its bookings back to the
connection that produced it. The wiring lives in the operator application at
`src/api/lib/booking-engine-runtime.ts`.

<Note>
  There is no admin UI or route in the deployment for creating or editing
  Connect connections. Connections, credentials, and grants are managed in the
  Connect product. See [where connection management lives](#where-connection-management-lives)
  at the end.
</Note>

## Wire Connect into a deployment

<Steps>
  <Step title="Get an API key and operator id, then set the env">
    Connect authenticates with a Voyant API token, scoped to one operator. From
    the Connect control plane, obtain a Voyant API key and the `operatorId` of
    the operator whose connections you want to sell.

    Set them in the deployment env. The plugin reads `VOYANT_API_KEY` and
    `VOYANT_CONNECT_OPERATOR_ID`; the rest are optional:

    ```bash theme={null}
    VOYANT_API_KEY=voyant_…              # a Voyant API token
    VOYANT_CONNECT_OPERATOR_ID=op_…      # the operator whose connections you source

    # Optional
    VOYANT_CONNECT_API_URL=…             # override the Connect API base URL
    VOYANT_CONNECT_MARKET=…              # market filter passed to the adapter
    VOYANT_CONNECT_SYNC_LIMIT=…          # per-adapter discover limit (positive integer)
    VOYANT_CLOUD_API_URL=…               # Voyant base, for geo/destination labels
    ```

    Connect is optional. When **neither** `VOYANT_API_KEY` nor
    `VOYANT_CONNECT_OPERATOR_ID` is set, the plugin is silently disabled. When
    **one but not both** is set, `resolveVoyantConnectEnv` logs an
    incomplete-config warning and disables Connect rather than booting in a
    half-configured state.

    <Note>
      `VOYANT_CONNECT_API_KEY` and `VOYANT_CLOUD_API_KEY` are accepted as legacy
      aliases for `VOYANT_API_KEY`, in that fallback order. Prefer
      `VOYANT_API_KEY`.
    </Note>
  </Step>

  <Step title="Build the registry and register Connect sources">
    The catalog booking engine resolves sourced inventory through a
    `SourceAdapterRegistry`. Create one with `createSourceAdapterRegistry` from
    `@voyant-travel/catalog/booking-engine`, then register the Connect sources on
    it with the `@voyant-travel/voyant-connect-adapter` helpers.

    There are two registration paths, and the starter uses both. The synchronous
    **fallback** registers a single un-scoped Connect adapter pair so sourced
    bookings can dispatch by `source_kind` during a cold isolate:

    ```ts theme={null}
    import { createSourceAdapterRegistry } from "@voyant-travel/catalog/booking-engine"
    import {
      createVoyantConnectSources,
      registerVoyantConnectSources,
      resolveVoyantConnectEnv,
    } from "@voyant-travel/voyant-connect-adapter"

    const registry = createSourceAdapterRegistry()

    // Synchronous fallback: the un-scoped default adapter pair.
    const config = resolveVoyantConnectEnv(env, {
      warn: (message) => console.warn(`[booking-engine] ${message}`),
    })
    if (config) {
      registerVoyantConnectSources(registry, createVoyantConnectSources(config))
    }
    ```

    The **per-connection warm** enumerates the operator's active connections and
    registers one connection-scoped adapter set per connection, keyed by
    `connection.id`. This is what lets the live book path route by
    `source_connection_id`. It is async because it enumerates over the network:

    ```ts theme={null}
    import {
      prepareVoyantConnectSources,
      registerVoyantConnectSources,
    } from "@voyant-travel/voyant-connect-adapter"

    // Per-connection warm: enumerate active connections, register one adapter
    // set per connection (keyed by connection.id). `enumerate: true` is the key.
    const sources = await prepareVoyantConnectSources(env, {
      enumerate: true,
      warn: (message) => console.warn(`[booking-engine] ${message}`),
    })
    registerVoyantConnectSources(registry, sources)
    ```

    Both helpers no-op cleanly when Connect is unconfigured:
    `resolveVoyantConnectEnv` returns `null` and `prepareVoyantConnectSources`
    returns `[]`, so nothing is registered and no network call is made.

    <Note>
      In the operator application, this is already wired in
      `src/api/lib/booking-engine-runtime.ts`. The fallback runs in
      `ensureRegistry` (once per isolate); `warmBookingEngineConnectSources` runs
      the per-connection warm in the background, and route handlers tie it to the
      request through `getBookingEngineRegistryFromContext`. You set the env and
      the registry does the rest.
    </Note>
  </Step>

  <Step title="Populate the catalog with the discovery sync">
    Live search resolves adapters from the registry, but the catalog index also
    needs sourced rows so Connect inventory shows up in browse and discovery. The
    operator application ships a discovery-sync CLI at `scripts/sync-sources.ts` that
    builds the same registry with `enumerate: true`, so synced rows are keyed by
    the same connection ids the live engine routes by, and indexes every
    projection into the catalog.

    ```bash theme={null}
    # from starters/operator
    pnpm sync:sources
    ```

    The CLI requires `TYPESENSE_HOST`, `TYPESENSE_ADMIN_API_KEY` (or
    `TYPESENSE_API_KEY`), and `DATABASE_URL`, plus the `VOYANT_CONNECT_*` env from
    step 1 to include Connect sources. It upserts a `catalog_sourced_entries` row
    per projection alongside the index write, so sourced detail and snapshot paths
    can resolve each entity by its catalog-side id. Run it on a schedule to keep
    sourced inventory fresh.
  </Step>

  <Step title="Follow a sourced product through search, quote, and reserve">
    Once sources are registered and the catalog is populated, Connect inventory
    behaves like any other catalog inventory, with provenance attached.

    * **Search.** Sourced products appear in catalog search alongside owned
      inventory. Each carries provenance: `source_kind: "voyant-connect"`,
      `source_connection_id`, and `source_ref` (cross-connection reads also carry
      `source_provider`). Your code does not branch on which supplier produced a
      result.
    * **Quote and reserve.** When a customer quotes or reserves a sourced
      product, the booking engine routes the call back to the originating
      connection by `source_connection_id`. The per-connection adapter registered
      in step 2 handles the dispatch; if the per-connection warm has not landed
      yet, the un-scoped fallback dispatches by `source_kind` so the booking still
      proceeds.
    * **Cancel and status.** Cancellation and status calls route back to Connect
      the same way, by `source_connection_id`, so the originating connection
      stays the system of record for the booking.

    Because provenance travels with every projection, a sourced record can always
    be refreshed or re-routed back to its connection.
  </Step>
</Steps>

## Where connection management lives

Creating connections, supplying supplier credentials, registering providers,
issuing grants, and configuring webhooks all happen in the **Connect control
plane**, not in your deployment. Your deployment only consumes an operator's
active connections through the env and the source adapters above. To add a
supplier, configure a new connection in Connect against your operator id; it then
appears to the deployment on the next per-connection warm or discovery sync.

See [Voyant Connect](/docs/connect/overview) and
[Connect concepts](/docs/connect/concepts) for operators, connections, credentials,
and grants.

## Advanced: cruises across two registries

Cruises reach the deployment through **two** planes, and Connect is one optional
contributor to both:

* The **vertical cruise registry** (`registerCruiseAdapter` from
  `@voyant-travel/cruises`), resolved by the cruises module's admin and public
  routes for external detail, refresh, detach, and the external booking commit.
* The **catalog `SourceAdapterRegistry`**, fed cruise shims through
  `cruiseAdapterToSourceAdapter`, used by catalog content, discovery sync,
  snapshot capture, and booking-engine sourced inventory.

The operator application wires both from one place,
`src/api/lib/cruise-adapters-runtime.ts`. A deployment that builds its own cruise
connector adds its `CruiseAdapter` to `configuredCruiseAdapters` there, with no
Connect dependency required. Connect's cruise adapters arrive through the catalog
plane (registered by `registerVoyantConnectSources`) and are back-filled into the
vertical registry by `syncVerticalRegistryFromCatalog`, so external cruise reads
resolve them too. With no custom adapter and Connect unconfigured, both planes
stay empty and external cruise reads return a clean `adapter_not_registered`
rather than failing the boot.

## Next steps

<CardGroup cols={2}>
  <Card title="Connect adapter" icon="puzzle-piece" href="/docs/connect/connect-adapter">
    The deployment-side adapter that turns Connect inventory into a catalog SourceAdapter.
  </Card>

  <Card title="Voyant Connect" icon="sitemap" href="/docs/connect/overview">
    The control plane: operators, connections, credentials, grants, and webhooks.
  </Card>

  <Card title="Distribution" icon="share-nodes" href="/docs/platform/modules/distribution">
    Resell catalog inventory, owned and sourced, across channels.
  </Card>

  <Card title="Cruises" icon="ship" href="/docs/platform/modules/cruises">
    The cruises module and its two-plane external adapter wiring.
  </Card>
</CardGroup>
