> ## 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.

# Connect SDK

> The raw typed HTTP client for the Voyant Connect API: the operator and connection control plane plus the normalized data plane.

`@voyant-travel/connect-sdk` is the public TypeScript client for the Voyant Connect product. It wraps the operator and connection control plane plus the Connect-normalized data plane for inventory, bookings, and flights. Use it from non-Voyant apps and low-level tools. If you are building a Voyant operator app that should pull Connect inventory into the platform catalog, use [`@voyant-travel/connect-adapter`](/docs/connect/connect-adapter) instead.

## Install

```bash theme={null}
pnpm add @voyant-travel/connect-sdk
```

## Create a client

```ts theme={null}
import { createVoyantConnectClient } from "@voyant-travel/connect-sdk";

const client = createVoyantConnectClient({
  apiKey: process.env.VOYANT_API_KEY!,
  operatorId: "op_123",
});
```

The client-level `operatorId` is the default scope for operator-scoped calls. Any call accepts a per-call `{ operatorId }` override.

## Control plane

The control plane manages operators, connections, and everything around them:

```ts theme={null}
// Create an operator
const operator = await client.operators.create({
  slug: "alpine-tours",
  name: "Alpine Tours",
  contactEmail: "ops@alpine.example",
});

// Add a connection to a supplier
const connection = await client.connections.create(operator.id, {
  supplierName: "Alpine Adventures",
  providerKey: "tui",
});
```

The control-plane groups:

| Group                      | Responsibility                                                                                    |
| -------------------------- | ------------------------------------------------------------------------------------------------- |
| `oauth`                    | Exchange client credentials for a short-lived bearer token.                                       |
| `operators`                | CRUD plus per-operator usage and search projections.                                              |
| `connectorProviders`       | List providers, manage applications and per-operator registrations.                               |
| `connections`              | CRUD plus webhook secret rotation, projection syncs, webhook and health events, and request logs. |
| `links`                    | Partner relationships and per-link capability toggles.                                            |
| `oauthClients`             | Provision and revoke machine-to-machine client credentials.                                       |
| `grants`                   | Issue, update, revoke, and inspect access grants.                                                 |
| `auditLogs`                | Paginated organization-wide audit trail.                                                          |
| `inviteTokens`             | Create, revoke, look up, and redeem invite tokens.                                                |
| `webhookSubscriptions`     | Create, list, update, delete, test, and replay webhook deliveries.                                |
| `customConnectionRequests` | Capture inbound requests for new supplier integrations.                                           |

## Data plane

The data plane returns Connect-normalized inventory. Cross-connection reads aggregate across every connection in an operator's catalog:

```ts theme={null}
await client.products.list();                          // all connections
await client.products.list({ providerKey: "ventrata" }); // filter by provider
await client.products.list({ connectionId: ["conn_a", "conn_b"] }); // multiple

const onConn = await client.products.listOnConnection(connection.id);
```

`products.list`, `suppliers.list`, and `bookings.listAll` aggregate across connections. Both `connectionId` and `providerKey` accept a scalar or an array.

The data-plane groups:

| Group          | Methods                                                                           |
| -------------- | --------------------------------------------------------------------------------- |
| `products`     | `list`, `get`, `listOnConnection`, `getOnConnection`, `listOptions`, `listExtras` |
| `options`      | `listUnits`, `listExtraConfigs`                                                   |
| `suppliers`    | `list`, `listOnConnection`                                                        |
| `availability` | `list`, `calendar`                                                                |
| `bookings`     | `listAll`, `list`, `get`, `create`, `confirm`, `cancel`, `listActivities`         |
| `cruises`      | `listSailingPricing`, `listSailingPromotions`                                     |
| `health`       | `get` (per-connection sync status)                                                |

## Flights

The `flights` group covers the full air lifecycle: `search`, `searchStream`, `searchOnConnection`, `price`, `book`, `getOrder`, `cancelOrder`, `ticketOrder`, `getSeatMap`, `selectSeats`, `getAncillaries`, `addAncillary`, `checkIn`, `exchange`, `refund`, `voidOrder`, and `addServiceRequest`.

`flights.searchStream` returns the raw `Response` so you can stream Server-Sent Events yourself. Each `connection-result` event corresponds to one provider settling, and the `final` event carries the merged, paginated response.

## Authentication

* A static API key in `Authorization: Bearer <key>` is the default.
* For machine-to-machine flows, exchange OAuth client credentials for a short-lived bearer token with `client.oauth.issueToken({ ... })`. The response is the raw OAuth shape: `access_token`, `expires_in`, `scope`.
* Both flows hit the same scope-checked routes; the token's `scope` claim must include the scope a route declares.

## Idempotency

`bookings.create` accepts `{ idempotencyKey }`, sent as the `Idempotency-Key` header and replayed against the server-side dedupe table. Always pass one when creating bookings so retries do not double-book.

```ts theme={null}
await client.bookings.create(connection.id, input, {
  idempotencyKey: "booking-attempt-7f3a",
});
```

## Next steps

<CardGroup cols={2}>
  <Card title="Connect adapter" icon="puzzle-piece" href="/docs/connect/connect-adapter">
    Pull this inventory into a Voyant app's catalog.
  </Card>

  <Card title="Concepts" icon="sitemap" href="/docs/connect/concepts">
    Operators, connections, grants, and supply models.
  </Card>
</CardGroup>
