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

# Issue an access token

> OAuth2 client-credentials flow. Exchanges a `clientId`/`clientSecret` for a short-lived bearer token. The returned `scope` reflects the granted `connect:*` scopes. This endpoint does not require a bearer; it authenticates the client credentials in the body.



## OpenAPI

````yaml /api-specs/connect.json post /connect/v1/oauth/token
openapi: 3.1.0
info:
  title: Voyant Connect API
  version: v1
  summary: Public REST API for Voyant Connect.
  description: >-
    Voyant Connect is the travel-supply integration layer. It exposes a control
    plane (operators, connections, links, grants, OAuth clients, invite tokens,
    webhook subscriptions, connector providers, audit logs, custom connection
    requests) and a data plane (Connect-normalized products, options, suppliers,
    availability, bookings, cruises, and a full flights lifecycle).


    Base URL for all operations is `https://api.voyant.travel` and every path is
    mounted under `/connect/v1`. The gateway authenticates the request, enforces
    scopes, and forwards to the private connect-api worker.


    ## Authentication

    Two flows are supported, both presented as an HTTP `Authorization: Bearer
    <token>` header:

    1. **Static API key** — a long-lived platform API token. Its `connect:*`
    scopes (e.g. `connect:bookings:write`) gate which operations succeed. Write
    methods (POST/PUT/PATCH) need a `*:write` scope; DELETE needs a `*:delete`
    scope.

    2. **OAuth2 client credentials** — `POST /connect/v1/oauth/token` exchanges
    a `clientId`/`clientSecret` for a short-lived bearer (`access_token`,
    `expires_in`, `scope`).


    ## Conventions

    - **Money** is expressed as integer minor units (`amountMinor`) paired with
    an ISO 4217 `currency` (and a `currencyPrecision`).

    - **Connect-normalized reads** carry provenance fields: `sourceRef`,
    `projection`, `projectionSchemaVersion`, `lastSourcedAt`, `market`, and
    `currency`. These let consumers index the canonical projection into their
    own search engine and trace freshness.

    - **List envelopes** wrap rows in `{ "data": [...] }`; cursor-paginated
    reads add `{ "pagination": { "nextCursor": string | null } }`.

    - Cross-connection (org-wide) reads accept repeated `connectionId` and
    `providerKey` query parameters.
servers:
  - url: https://api.voyant.travel
    description: Production
security:
  - bearerAuth: []
tags:
  - name: OAuth
    description: Token issuance via client-credentials.
  - name: Operators
    description: Connect operators (the supply-side tenant within an organization).
  - name: Connector Providers
    description: Provider catalog, manifests, applications, and per-operator registrations.
  - name: Connections
    description: Per-operator supplier connections and their operational telemetry.
  - name: Links
    description: Cross-organization supply links and their capabilities.
  - name: OAuth Clients
    description: Machine-to-machine OAuth clients scoped to an operator.
  - name: Grants
    description: Cross-org access grants over an operator's data.
  - name: Audit Logs
    description: Organization-scoped API audit trail.
  - name: Invite Tokens
    description: Operator invite tokens (issue, redeem, public lookup).
  - name: Webhook Subscriptions
    description: Event subscriptions, deliveries, test events, and replays.
  - name: Custom Connection Requests
    description: Requests for suppliers not yet in the provider catalog.
  - name: Products
    description: Connect-normalized products on a connection or aggregated per operator.
  - name: Options
    description: Product options, units, and extra-configs.
  - name: Suppliers
    description: Connect-normalized suppliers.
  - name: Availability
    description: Connect-normalized availability and availability calendar.
  - name: Bookings
    description: >-
      Connect-normalized bookings lifecycle (create, confirm, cancel,
      activities).
  - name: Cruises
    description: Connect-normalized cruise catalog, sailings, pricing, and promotions.
  - name: Flights
    description: 'Full flight lifecycle: search/stream, price, book, manage orders.'
  - name: Health
    description: Per-connection channel health.
paths:
  /connect/v1/oauth/token:
    post:
      tags:
        - OAuth
      summary: Issue an access token
      description: >-
        OAuth2 client-credentials flow. Exchanges a `clientId`/`clientSecret`
        for a short-lived bearer token. The returned `scope` reflects the
        granted `connect:*` scopes. This endpoint does not require a bearer; it
        authenticates the client credentials in the body.
      operationId: issueToken
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IssueTokenInput'
      responses:
        '200':
          description: Access token issued.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuthTokenResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/ServerError'
      security: []
      x-codeSamples:
        - lang: typescript
          label: SDK
          source: >-
            import { createVoyantConnectClient } from
            "@voyant-travel/connect-sdk";


            const connect = createVoyantConnectClient({ apiKey:
            process.env.VOYANT_API_KEY });


            const result = await connect.oauth.issueToken({
              "clientId": "<string>",
              "clientSecret": "<string>",
              "grantType": "client_credentials",
              "scope": "connect:flights:read connect:bookings:write"
            });
        - lang: bash
          label: cURL
          source: |-
            curl --request POST \
              --url https://api.voyant.travel/connect/v1/oauth/token \
              --header 'Content-Type: application/json' \
              --data '{
              "clientId": "<string>",
              "clientSecret": "<string>",
              "grantType": "client_credentials",
              "scope": "connect:flights:read connect:bookings:write"
            }'
        - lang: javascript
          label: Node
          source: >-
            const response = await
            fetch("https://api.voyant.travel/connect/v1/oauth/token", {
              method: "POST",
              headers: {
                "Content-Type": "application/json"
              },
              body: JSON.stringify({
                "clientId": "<string>",
                "clientSecret": "<string>",
                "grantType": "client_credentials",
                "scope": "connect:flights:read connect:bookings:write"
              }),
            });


            const data = await response.json();
        - lang: python
          label: Python
          source: |-
            import requests

            response = requests.post(
                "https://api.voyant.travel/connect/v1/oauth/token",
                json={
                    "clientId": "<string>",
                    "clientSecret": "<string>",
                    "grantType": "client_credentials",
                    "scope": "connect:flights:read connect:bookings:write"
                }
            )

            data = response.json()
components:
  schemas:
    IssueTokenInput:
      type: object
      required:
        - clientId
        - clientSecret
      properties:
        clientId:
          type: string
        clientSecret:
          type: string
        grantType:
          type: string
          enum:
            - client_credentials
          default: client_credentials
        scope:
          type: string
          description: Space-separated scopes to request.
          example: connect:flights:read connect:bookings:write
    OAuthTokenResponse:
      type: object
      required:
        - access_token
        - token_type
        - expires_in
        - scope
      properties:
        access_token:
          type: string
        token_type:
          type: string
          enum:
            - Bearer
        expires_in:
          type: integer
          description: Token lifetime in seconds.
          example: 3600
        scope:
          type: string
          example: connect:flights:read connect:bookings:write
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          description: Human-readable error message.
        code:
          type: string
          description: >-
            Stable, machine-readable error code. Populated on 5xx and
            upstream-connector failures (e.g. PROVIDER_TIMEOUT,
            UPSTREAM_UNAVAILABLE).
        requestId:
          type: string
          description: >-
            Correlation id for this request. Also returned in the X-Request-Id
            response header.
        details:
          type: object
          additionalProperties: true
          description: Optional structured context.
  responses:
    BadRequest:
      description: The request was malformed or failed validation.
      headers:
        X-Request-Id:
          description: Correlation id, echoed on every response including errors.
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Authentication is missing or invalid.
      headers:
        X-Request-Id:
          description: Correlation id, echoed on every response including errors.
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: >-
        The token lacks the required connect:* scope, or there is no active
        organization context.
      headers:
        X-Request-Id:
          description: Correlation id, echoed on every response including errors.
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    TooManyRequests:
      description: Rate limit exceeded. Retry after the period in the Retry-After header.
      headers:
        X-Request-Id:
          description: Correlation id, echoed on every response including errors.
          schema:
            type: string
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    ServerError:
      description: >-
        An unexpected error occurred. The X-Request-Id header identifies the
        failed request.
      headers:
        X-Request-Id:
          description: Correlation id, echoed on every response including errors.
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key or OAuth2 access token
      description: >-
        Provide either a static platform API key or an OAuth2 access token (from
        `/connect/v1/oauth/token`) as `Authorization: Bearer <token>`. Scopes
        are `connect:*` (e.g. `connect:bookings:write`).

````