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

# Search flights across selected providers

> Available when enabled for the workspace. System-managed capability router. Locus plans eligible providers, executes them concurrently, normalizes and deduplicates itineraries, ranks offers, and returns aggregate billing. Use the preview route first when you need an estimate. A narrower request maxCredits or credential-level ceiling prevents dispatch when the aggregate estimate is too high. Retries must reuse the same Idempotency-Key and identical logical request; a 202 response means one or more child providers are still processing, so retry with the same key.



## OpenAPI

````yaml /api-reference/openapi.json post /wrapped/credits/locus-travel/flight-search
openapi: 3.1.0
info:
  title: Locus Pro API
  description: >-
    Production is live at https://api.paywithlocus.com/api. Stage remains
    available for evaluation and integration testing at
    https://api.stage.paywithlocus.com/api; credentials, balances, and tenant
    data are isolated by environment. Embedded prepaid credits over the Locus
    pay-per-use catalog. Money and top-up amounts use exact decimal strings (up
    to 6dp). Every burn requires an Idempotency-Key header. Management routes
    accept a tenant secret key or authorized dashboard session as shown per
    operation. Widget routes accept an end-user JWT alone; when a publishable
    key is present it must belong to the JWT's tenant. MCP uses OAuth 2.1
    Authorization Code with PKCE by default and also accepts the explicitly
    documented tenant secret key, end-user JWT, or scoped agent connection
    compatibility credentials. Burns accept the execution credentials shown per
    operation. Publishable keys never authorize management or burns by
    themselves.
  version: 0.6.0
servers:
  - url: https://api.paywithlocus.com/api
    description: Production
  - url: https://api.stage.paywithlocus.com/api
    description: Stage — evaluation and integration testing
security:
  - secretKey: []
tags:
  - name: Authentication
    description: Email-verified self-serve account creation and dashboard identity
  - name: Tenants
    description: Tenant profile, keys, and settings (dashboard session or secret key)
  - name: Workspace members
    description: Invite-only human workspace membership and role administration
  - name: Catalog
    description: Enable/disable APIs and set markups
  - name: Custom APIs
    description: >-
      Available when enabled for the workspace. Enterprise BYOK providers and
      schema-backed custom actions
  - name: End users
    description: End-user accounts, tokens, and allocations
  - name: Top-ups
    description: Locus-hosted checkout top-ups and quotes
  - name: Ledger
    description: Burn/top-up history and earnings
  - name: Webhooks
    description: Signed events, delivery inspection, and replay
  - name: Burn
    description: Metered pay-per-use calls
  - name: Travel routing
    description: >-
      Available when enabled for the workspace. Multi-provider flight search,
      no-dispatch planning, and feedback
  - name: MCP
    description: Stateless Streamable HTTP transport and MCP tool-result contracts
  - name: Okibi Identity
    description: >-
      Available when enabled for the workspace. Okibi identity verification and
      scoped native CLI credential bootstrap
  - name: Widget
    description: End-user JWT surface; a matching publishable key is optional
  - name: Agent-native onboarding
    description: >-
      Self-registration, human Stripe funding handoff, and restricted account
      setup for headless agents
  - name: Agent connections
    description: Scoped, expiring, revocable credentials for agent execution
  - name: Capability routing
    description: Outcome-level web search and research across eligible catalog providers
paths:
  /wrapped/credits/locus-travel/flight-search:
    post:
      tags:
        - Travel routing
      summary: Search flights across selected providers
      description: >-
        Available when enabled for the workspace. System-managed capability
        router. Locus plans eligible providers, executes them concurrently,
        normalizes and deduplicates itineraries, ranks offers, and returns
        aggregate billing. Use the preview route first when you need an
        estimate. A narrower request maxCredits or credential-level ceiling
        prevents dispatch when the aggregate estimate is too high. Retries must
        reuse the same Idempotency-Key and identical logical request; a 202
        response means one or more child providers are still processing, so
        retry with the same key.
      parameters:
        - $ref: '#/components/parameters/SessionBindingHeader'
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
          description: >-
            One key per logical travel search. Reuse it with an identical
            request to replay or finish the run.
        - name: X-Locus-End-User
          in: header
          required: false
          schema:
            $ref: '#/components/schemas/ExternalUserId'
          description: >-
            Optional end-user identity for a tenant secret key. It must agree
            with body externalUserId when both are present.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TravelFlightSearchRequest'
      responses:
        '200':
          description: >-
            Normalized, ranked flight search with provider outcomes and
            aggregate billing
          headers:
            X-Locus-Router-Run-Id:
              schema:
                type: string
                format: uuid
            X-Locus-Router-Capability:
              schema:
                const: travel.flight_search
            X-Locus-Router-Dispatches:
              schema:
                type: integer
                minimum: 0
            X-Locus-Credits-Charged:
              schema:
                $ref: '#/components/schemas/DecimalString'
            X-Locus-Credits-Balance:
              schema:
                $ref: '#/components/schemas/DecimalString'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TravelFlightSearchResponse'
        '202':
          description: >-
            The durable run is still processing; retry with the same
            Idempotency-Key
          headers:
            Retry-After:
              schema:
                type: integer
                const: 2
            X-Locus-Router-Run-Id:
              schema:
                type: string
                format: uuid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TravelFlightSearchPending'
        '400':
          description: >-
            Invalid search, missing/invalid Idempotency-Key, or
            caller-correctable request error
        '401':
          description: Missing or invalid execution credential
        '403':
          description: >-
            Account, end-user, Agent Connection, catalog, or endpoint policy
            denied execution
        '409':
          description: >-
            Idempotency-Key belongs to a different request or the planned
            aggregate charge exceeds a ceiling
        '502':
          description: >-
            All selected travel providers failed; per-provider outcomes and any
            incurred child billing are returned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TravelFlightSearchResponse'
        '503':
          description: >-
            No eligible travel provider is currently available for this search.
            Pre-dispatch and retry-safe: nothing ran and no charge posts.
          headers:
            X-Locus-Retry-Safe:
              schema:
                type: string
              description: Always "true" for this pre-dispatch failure.
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
                  message:
                    type: string
      security:
        - secretKey: []
        - endUserToken: []
        - agentConnection: []
components:
  parameters:
    SessionBindingHeader:
      name: X-Locus-Session-Id
      in: header
      required: false
      schema:
        type: string
        minLength: 16
        maxLength: 128
        pattern: ^[A-Za-z0-9][A-Za-z0-9._:-]{15,127}$
      description: >-
        Required only when the end-user JWT carries sid. Send the original
        high-entropy session value; sid is its SHA-256 fingerprint. Ignored for
        secret-key authentication.
  schemas:
    ExternalUserId:
      type: string
      minLength: 1
      maxLength: 200
      pattern: ^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,199}$
      description: >-
        Case-sensitive immutable ID in the tenant namespace. Prefer an
        identity-provider subject, not an email address.
    TravelFlightSearchRequest:
      type: object
      additionalProperties: false
      required:
        - origin
        - destination
        - departureDate
      properties:
        origin:
          type: string
          minLength: 2
          maxLength: 120
          description: >-
            IATA code or place name. Three-letter codes are normalized to
            uppercase.
        destination:
          type: string
          minLength: 2
          maxLength: 120
          description: Must differ from origin.
        departureDate:
          type: string
          format: date
          description: Real calendar date in YYYY-MM-DD form.
        returnDate:
          type: string
          format: date
          description: Optional return date on or after departureDate.
        adults:
          type: integer
          minimum: 1
          maximum: 9
          default: 1
        children:
          type: integer
          minimum: 0
          maximum: 8
          default: 0
        infants:
          type: integer
          minimum: 0
          maximum: 4
          default: 0
          description: Cannot exceed adults. Total travelers cannot exceed nine.
        cabinClass:
          type: string
          enum:
            - economy
            - premium_economy
            - business
            - first
          default: economy
        currency:
          type: string
          pattern: ^[A-Za-z]{3}$
          default: USD
        optimize:
          type: array
          maxItems: 3
          uniqueItems: true
          items:
            type: string
            enum:
              - cost
              - quality
              - context
          description: >-
            Cost favors fewer inexpensive sources, quality increases depth, and
            context favors compact agent-readable output.
        preferredAirlines:
          type: array
          maxItems: 20
          uniqueItems: true
          items:
            type: string
            minLength: 1
            maxLength: 100
        excludedAirlines:
          type: array
          maxItems: 20
          uniqueItems: true
          items:
            type: string
            minLength: 1
            maxLength: 100
        preferredAirports:
          type: array
          maxItems: 20
          uniqueItems: true
          items:
            type: string
            minLength: 1
            maxLength: 100
        excludedAirports:
          type: array
          maxItems: 20
          uniqueItems: true
          items:
            type: string
            minLength: 1
            maxLength: 100
        maxStops:
          type: integer
          minimum: 0
          maximum: 3
        minLayoverMinutes:
          type: integer
          minimum: 0
          maximum: 1440
        maxLayoverMinutes:
          type: integer
          minimum: 0
          maximum: 2880
        maxDurationMinutes:
          type: integer
          minimum: 30
          maximum: 10080
        maxPrice:
          type: number
          exclusiveMinimum: 0
          maximum: 10000000
          description: Maximum itinerary price in currency.
        departAfter:
          type: string
          pattern: ^(?:[01]\d|2[0-3]):[0-5]\d$
        departBefore:
          type: string
          pattern: ^(?:[01]\d|2[0-3]):[0-5]\d$
        arriveAfter:
          type: string
          pattern: ^(?:[01]\d|2[0-3]):[0-5]\d$
        arriveBefore:
          type: string
          pattern: ^(?:[01]\d|2[0-3]):[0-5]\d$
        maxResults:
          type: integer
          minimum: 1
          maximum: 50
        maxProviders:
          type: integer
          minimum: 1
          maximum: 11
        providers:
          type: array
          maxItems: 11
          uniqueItems: true
          items:
            type: string
            enum:
              - aircanada
              - duffel
              - stabletravel
              - almosafer
              - flightconnections
              - justfly
              - kayak_hk
              - skyscanner
              - skiplagged
              - trip
              - united
          description: >-
            Optional explicit provider selection, still narrowed by credential,
            catalog, availability, and request compatibility.
        maxCredits:
          oneOf:
            - type: string
              pattern: ^(?:0*[1-9]\d*)(?:\.\d{1,6})?$|^0*\.0*[1-9]\d{0,5}$
            - type: number
              exclusiveMinimum: 0
              maximum: 1000000000000
          description: >-
            Aggregate no-dispatch ceiling for all selected child calls, in
            account credits.
        externalUserId:
          $ref: '#/components/schemas/ExternalUserId'
        attribution:
          type: object
          additionalProperties: true
          description: Optional JSON attribution copied to child calls.
      description: >-
        Preferred and excluded values cannot overlap. minLayoverMinutes cannot
        exceed maxLayoverMinutes. Defaults are selected from optimize when
        optional depth controls are absent.
    DecimalString:
      type: string
      pattern: ^\d+(?:\.\d{1,6})?$
      description: >-
        Non-negative exact decimal string with at most six fractional digits.
        Endpoint-specific positivity and amount limits still apply.
    TravelFlightSearchResponse:
      type: object
      additionalProperties: false
      required:
        - object
        - capability
        - routerVersion
        - runId
        - search
        - appliedOptimizations
        - partial
        - warnings
        - providers
        - itineraries
        - itineraryCount
        - bookability
        - feedback
        - billing
      properties:
        object:
          const: locus.travel_flight_search
        capability:
          const: travel.flight_search
        routerVersion:
          type: string
        runId:
          type: string
          format: uuid
        search:
          $ref: '#/components/schemas/TravelFlightSearchRequest'
        appliedOptimizations:
          type: array
          items:
            type: string
            enum:
              - cost
              - quality
              - context
        partial:
          type: boolean
          description: >-
            True when at least one selected provider did not produce a complete
            successful result.
        warnings:
          type: array
          items:
            type: string
        providers:
          type: array
          items:
            $ref: '#/components/schemas/TravelProviderOutcome'
        itineraries:
          type: array
          items:
            $ref: '#/components/schemas/TravelItinerary'
        itineraryCount:
          type: integer
          minimum: 0
        bookability:
          type: object
          additionalProperties: false
          required:
            - bookableItineraryCount
            - bookingLinkOfferCount
            - offerCount
          properties:
            bookableItineraryCount:
              type: integer
              minimum: 0
            bookingLinkOfferCount:
              type: integer
              minimum: 0
            offerCount:
              type: integer
              minimum: 0
        feedback:
          type: object
          additionalProperties: false
          required:
            - method
            - route
            - runId
          properties:
            method:
              const: POST
            route:
              type: string
            runId:
              type: string
              format: uuid
        billing:
          type: object
          additionalProperties: false
          required:
            - chargedCredits
            - successfulProviders
            - attemptedProviders
          properties:
            chargedCredits:
              $ref: '#/components/schemas/DecimalString'
            successfulProviders:
              type: integer
              minimum: 0
            attemptedProviders:
              type: integer
              minimum: 0
    TravelFlightSearchPending:
      type: object
      additionalProperties: false
      required:
        - object
        - capability
        - runId
        - status
        - message
      properties:
        object:
          const: locus.travel_flight_search.pending
        capability:
          const: travel.flight_search
        runId:
          type: string
          format: uuid
        status:
          const: processing
        providers:
          type: array
          items:
            type: object
            additionalProperties: false
            required:
              - providerId
              - providerName
              - status
              - latencyMs
            properties:
              providerId:
                type: string
              providerName:
                type: string
              status:
                type: string
                enum:
                  - succeeded
                  - failed
                  - pending
              latencyMs:
                type: number
                minimum: 0
        billing:
          type: object
          additionalProperties: false
          required:
            - chargedCredits
          properties:
            chargedCredits:
              $ref: '#/components/schemas/DecimalString'
        message:
          type: string
    TravelProviderOutcome:
      type: object
      additionalProperties: false
      required:
        - providerId
        - providerName
        - status
        - latencyMs
        - itineraryCount
        - surfacedItineraryCount
        - uniqueSurfacedItineraryCount
        - tailLatencyContributionMs
      properties:
        providerId:
          type: string
        providerName:
          type: string
        status:
          type: string
          enum:
            - succeeded
            - failed
            - pending
        latencyMs:
          type: number
          minimum: 0
        itineraryCount:
          type: integer
          minimum: 0
        surfacedItineraryCount:
          type: integer
          minimum: 0
        uniqueSurfacedItineraryCount:
          type: integer
          minimum: 0
        tailLatencyContributionMs:
          type: number
          minimum: 0
        chargedCredits:
          $ref: '#/components/schemas/DecimalString'
        errorCode:
          type: string
        estimatedCostUsd:
          type: number
          minimum: 0
    TravelItinerary:
      type: object
      additionalProperties: false
      required:
        - id
        - score
        - legs
        - offers
        - tags
        - confidence
        - sources
        - sourceCount
        - bookability
      properties:
        id:
          type: string
        score:
          type: number
        providerItineraryId:
          type: string
          description: Provider-native itinerary ID when one canonical source supplies it.
        legs:
          type: array
          items:
            $ref: '#/components/schemas/TravelLeg'
        offers:
          type: array
          items:
            $ref: '#/components/schemas/TravelOffer'
        tags:
          type: array
          items:
            type: string
        selfTransfer:
          type: boolean
        baggage:
          type: string
        seatsRemaining:
          type: integer
          minimum: 0
        confidence:
          type: object
          additionalProperties: false
          required:
            - score
            - sourceCount
            - scheduleAgreement
          properties:
            score:
              type: number
            sourceCount:
              type: integer
              minimum: 1
            scheduleAgreement:
              type: string
              enum:
                - single_source
                - corroborated
            priceSpreadPercent:
              type: number
              minimum: 0
        sources:
          type: array
          items:
            type: object
            additionalProperties: false
            required:
              - providerId
              - providerName
              - rank
            properties:
              providerId:
                type: string
              providerName:
                type: string
              rank:
                type: integer
                minimum: 0
              providerItineraryId:
                type: string
        sourceCount:
          type: integer
          minimum: 1
        bookability:
          type: object
          additionalProperties: false
          required:
            - status
            - offerCount
            - bookingLinkOfferCount
            - currency
          properties:
            status:
              type: string
              enum:
                - booking_link_available
                - price_only
            offerCount:
              type: integer
              minimum: 0
            bookingLinkOfferCount:
              type: integer
              minimum: 0
            cheapestBookableAmount:
              type: number
              minimum: 0
            currency:
              type: string
    TravelLeg:
      type: object
      additionalProperties: false
      required:
        - origin
        - destination
        - departure
        - arrival
        - stopCount
        - segments
      properties:
        origin:
          $ref: '#/components/schemas/TravelPlace'
        destination:
          $ref: '#/components/schemas/TravelPlace'
        departure:
          type: string
        arrival:
          type: string
        durationMinutes:
          type: integer
          minimum: 0
        stopCount:
          type: integer
          minimum: 0
        segments:
          type: array
          items:
            $ref: '#/components/schemas/TravelSegment'
        intermediateAirports:
          type: array
          items:
            $ref: '#/components/schemas/TravelPlace'
        layoverDurationsMinutes:
          type: array
          items:
            type: integer
            minimum: 0
    TravelOffer:
      type: object
      additionalProperties: false
      required:
        - amount
        - currency
        - providerId
        - providerName
      properties:
        amount:
          type: number
          minimum: 0
        currency:
          type: string
        formatted:
          type: string
        bookingUrl:
          type: string
          format: uri
        seller:
          type: string
        cabinClass:
          type: string
          enum:
            - economy
            - premium_economy
            - business
            - first
        refundable:
          type: boolean
        providerId:
          type: string
        providerName:
          type: string
    TravelPlace:
      type: object
      additionalProperties: false
      required:
        - code
      properties:
        code:
          type: string
        name:
          type: string
        city:
          type: string
    TravelSegment:
      type: object
      additionalProperties: false
      required:
        - origin
        - destination
        - departure
        - arrival
      properties:
        origin:
          $ref: '#/components/schemas/TravelPlace'
        destination:
          $ref: '#/components/schemas/TravelPlace'
        departure:
          type: string
          description: Provider-normalized departure timestamp.
        arrival:
          type: string
          description: Provider-normalized arrival timestamp.
        durationMinutes:
          type: integer
          minimum: 0
        flightNumber:
          type: string
        marketingCarrier:
          type: object
          additionalProperties: false
          properties:
            code:
              type: string
            name:
              type: string
        operatingCarrier:
          type: object
          additionalProperties: false
          properties:
            code:
              type: string
            name:
              type: string
        aircraft:
          type: string
  securitySchemes:
    secretKey:
      type: http
      scheme: bearer
      description: Tenant secret key (lcr_…). Server-side only.
    endUserToken:
      type: http
      scheme: bearer
      description: >-
        60-3600 second end-user JWT minted via /credits/end-users/{id}/token. If
        the JWT has sid, send the original session value in X-Locus-Session-Id;
        sid contains only its SHA-256 fingerprint. Bearer tokens are replayable
        until expiry; use short TTLs, optional session binding, and
        Idempotency-Key on operations.
    agentConnection:
      type: http
      scheme: bearer
      description: >-
        Scoped lcac_ credential. Tenant-managed Agent Connections authorize only
        their bound MCP and wrapped execution surfaces. A bootstrap connection
        for a self-registered agent additionally authorizes the explicit
        /credits/agent/* self-service routes for its own account; neither form
        authorizes general tenant management.

````