components:
  schemas:
    CheckoutHandoffOut:
      description: 'A hosted-checkout continuation. Not a booking, not a payment, not a hold.


        Carries no Stripe identifier, client secret, publishable key or

        PaymentIntent. The traveler pays on Swiss Touristy; the caller''s only role

        is to deliver them to ``checkout_url``.'
      properties:
        checkout_url:
          title: Checkout Url
          type: string
        currency:
          title: Currency
          type: string
        expires_at:
          anyOf:
          - format: date-time
            type: string
          - type: 'null'
          title: Expires At
        fleet_id:
          title: Fleet Id
          type: integer
        non_binding:
          default: true
          title: Non Binding
          type: boolean
        quote_id:
          title: Quote Id
          type: string
        request_id:
          anyOf:
          - type: string
          - type: 'null'
          title: Request Id
        reservation_status:
          default: not_reserved
          title: Reservation Status
          type: string
        status:
          default: open
          title: Status
          type: string
        total_price:
          title: Total Price
          type: number
      required:
      - checkout_url
      - quote_id
      - fleet_id
      - total_price
      - currency
      title: CheckoutHandoffOut
      type: object
    CheckoutHandoffRequest:
      additionalProperties: false
      description: 'POST /checkout-sessions — hands off to Swiss Touristy''s hosted checkout.


        ``traveler_approval`` has no default. An agent calling a tool is not a

        traveler consenting to a purchase, so consent must be asserted explicitly

        and can never be inferred from the call itself.'
      properties:
        fleet_id:
          exclusiveMinimum: 0.0
          title: Fleet Id
          type: integer
        quote_id:
          maxLength: 64
          minLength: 1
          title: Quote Id
          type: string
        traveler_approval:
          title: Traveler Approval
          type: boolean
      required:
      - quote_id
      - fleet_id
      - traveler_approval
      title: CheckoutHandoffRequest
      type: object
    CreateQuoteRequest:
      additionalProperties: false
      description: 'POST /quotes — protected, persisted, owner-scoped.


        Note the fields that are absent: no ``distance_km``, no ``duration_min``, no

        price, no currency override, no fleet selection. Those are not oversights.

        A field that does not exist cannot be smuggled past a validator, and §C

        requires that nothing a caller sends can control an authoritative amount.'
      properties:
        adults:
          anyOf:
          - maximum: 50.0
            minimum: 0.0
            type: integer
          - type: 'null'
          title: Adults
        booking_type:
          default: point_to_point
          maxLength: 32
          title: Booking Type
          type: string
        children:
          default: 0
          maximum: 50.0
          minimum: 0.0
          title: Children
          type: integer
        destination:
          maxLength: 512
          minLength: 1
          title: Destination
          type: string
        duration_hours:
          anyOf:
          - maximum: 240.0
            minimum: 0.0
            type: number
          - type: 'null'
          title: Duration Hours
        infants:
          default: 0
          maximum: 50.0
          minimum: 0.0
          title: Infants
          type: integer
        luggage:
          default: 0
          maximum: 50.0
          minimum: 0.0
          title: Luggage
          type: integer
        origin:
          maxLength: 512
          minLength: 1
          title: Origin
          type: string
        passengers:
          default: 1
          maximum: 50.0
          minimum: 1.0
          title: Passengers
          type: integer
        pickup_datetime:
          format: date-time
          title: Pickup Datetime
          type: string
        return_datetime:
          anyOf:
          - format: date-time
            type: string
          - type: 'null'
          title: Return Datetime
        waiting_minutes:
          default: 0
          maximum: 1440.0
          minimum: 0.0
          title: Waiting Minutes
          type: integer
        waypoints:
          anyOf:
          - items:
              $ref: '#/components/schemas/WaypointIn'
            maxItems: 10
            type: array
          - type: 'null'
          title: Waypoints
      required:
      - origin
      - destination
      - pickup_datetime
      title: CreateQuoteRequest
      type: object
    FieldErrorOut:
      description: One field-level complaint inside a problem document.
      properties:
        field:
          description: Dotted path to the offending field, e.g. `pickup_datetime`.
          title: Field
          type: string
        message:
          description: What is wrong with it, in a sentence.
          title: Message
          type: string
      required:
      - field
      - message
      title: FieldErrorOut
      type: object
    LuggageDefinitionOut:
      description: 'What one luggage unit actually is.


        Published with the counts because a count on its own is not machine-

        readable: "2 large" only constrains a booking if both sides agree what large

        means. Oversized items -- skis, golf bags, wheelchairs, strollers -- are

        declared separately and are never converted into these units.'
      properties:
        counts_as:
          title: Counts As
          type: integer
        description:
          title: Description
          type: string
        label:
          title: Label
          type: string
        max_dimensions_cm:
          items:
            type: integer
          title: Max Dimensions Cm
          type: array
        typical_weight_kg:
          items:
            type: integer
          title: Typical Weight Kg
          type: array
      required:
      - label
      - description
      - max_dimensions_cm
      - typical_weight_kg
      - counts_as
      title: LuggageDefinitionOut
      type: object
    PolicyOut:
      description: 'Versioned published policy. Sourced from app.services.commercial_rules —

        never hardcoded here, in swissmcp, or in frontend copy.'
      properties:
        full_refund_cutoff_hours:
          title: Full Refund Cutoff Hours
          type: number
        policy_key:
          title: Policy Key
          type: string
        policy_text:
          title: Policy Text
          type: string
        policy_version:
          title: Policy Version
          type: string
      required:
      - policy_key
      - policy_version
      - full_refund_cutoff_hours
      - policy_text
      title: PolicyOut
      type: object
    ProblemOut:
      additionalProperties: false
      description: 'RFC 7807 `application/problem+json`, as this surface renders it.


        `code` is the stable contract: it is UPPER_SNAKE, it is the thing an

        integration branches on, and it never changes meaning. `detail` is prose

        for a human reading a log and may be reworded at any time — do not parse it.'
      example:
        code: QUOTE_EXPIRED
        detail: This quote is no longer valid.
        field_errors: []
        instance: /api/public/v1/checkout-sessions
        next_action: Create a new quote; pricing snapshots last 30 minutes.
        request_id: req_9f2c1b7ae4d84c6f9b2e10a3
        retryable: false
        status: 409
        title: Quote expired
        type: https://swisstouristy.com/developers/errors/quote_expired
      properties:
        code:
          $ref: '#/components/schemas/PublicErrorCode'
          description: Stable machine-readable code. Branch on this, never on `detail` or `status`.
        detail:
          description: Prose for a human reading a log. Never parse this.
          title: Detail
          type: string
        field_errors:
          description: Field-level detail, present for validation failures.
          items:
            $ref: '#/components/schemas/FieldErrorOut'
          title: Field Errors
          type: array
        instance:
          anyOf:
          - type: string
          - type: 'null'
          default: null
          description: Path of the request that failed.
          title: Instance
        next_action:
          anyOf:
          - type: string
          - type: 'null'
          default: null
          description: Short, machine-actionable remediation for this code.
          title: Next Action
        request_id:
          anyOf:
          - type: string
          - type: 'null'
          default: null
          description: Quote this when contacting support; it identifies the exact request.
          title: Request Id
        retry_after_seconds:
          anyOf:
          - type: integer
          - type: 'null'
          default: null
          description: Present only on RATE_LIMITED, mirroring the `Retry-After` response header.
          title: Retry After Seconds
        retryable:
          description: Whether the identical request may succeed on retry. False means the request must
            change first — a 422 is never retryable.
          title: Retryable
          type: boolean
        status:
          description: HTTP status, repeated in the body per RFC 7807.
          title: Status
          type: integer
        title:
          description: Short human-readable summary of the code.
          title: Title
          type: string
        type:
          description: Dereferenceable documentation for this error code. Stable per code; the last path
            segment is the lowercased `code`.
          title: Type
          type: string
      required:
      - type
      - title
      - status
      - code
      - detail
      - retryable
      title: ProblemOut
      type: object
    PublicErrorCode:
      description: 'The public error catalogue. Values are stable API surface — never

        rename one to tidy it up; callers branch on these strings.'
      enum:
      - INVALID_REQUEST
      - INVALID_LOCATION
      - ROUTE_UNAVAILABLE
      - UNSUPPORTED_ROUTE
      - INVALID_DATETIME
      - NO_ELIGIBLE_VEHICLE
      - QUOTE_UNAVAILABLE
      - MANUAL_CONFIRMATION_REQUIRED
      - QUOTE_EXPIRED
      - AUTHENTICATION_REQUIRED
      - FORBIDDEN
      - QUOTE_NOT_FOUND
      - RATE_LIMITED
      - UPSTREAM_UNAVAILABLE
      - PAST_DATETIME
      - LEAD_TIME_NOT_SUPPORTED
      - RETURN_TIME_INVALID
      title: PublicErrorCode
      type: string
    QuoteEstimateRequest:
      additionalProperties: false
      description: 'POST /quote-intents — anonymous, rate-limited, nothing persisted.


        This is the one operation where caller-supplied ``distance_km`` and

        ``duration_min`` are honoured, and it is safe because no payable amount is

        reachable from it: no snapshot is written, no quote id is issued, and

        checkout will not accept its output. Task 4 §E permits client metrics to

        describe a request; it forbids them controlling an automated payable

        amount.'
      properties:
        adults:
          anyOf:
          - maximum: 50.0
            minimum: 0.0
            type: integer
          - type: 'null'
          title: Adults
        booking_type:
          default: point_to_point
          maxLength: 32
          title: Booking Type
          type: string
        children:
          default: 0
          maximum: 50.0
          minimum: 0.0
          title: Children
          type: integer
        destination:
          maxLength: 512
          minLength: 1
          title: Destination
          type: string
        distance_km:
          anyOf:
          - maximum: 5000.0
            minimum: 0.0
            type: number
          - type: 'null'
          title: Distance Km
        duration_hours:
          anyOf:
          - maximum: 240.0
            minimum: 0.0
            type: number
          - type: 'null'
          title: Duration Hours
        duration_min:
          anyOf:
          - maximum: 100000.0
            minimum: 0.0
            type: integer
          - type: 'null'
          title: Duration Min
        infants:
          default: 0
          maximum: 50.0
          minimum: 0.0
          title: Infants
          type: integer
        luggage:
          default: 0
          maximum: 50.0
          minimum: 0.0
          title: Luggage
          type: integer
        origin:
          maxLength: 512
          minLength: 1
          title: Origin
          type: string
        passengers:
          default: 1
          maximum: 50.0
          minimum: 1.0
          title: Passengers
          type: integer
        pickup_datetime:
          format: date-time
          title: Pickup Datetime
          type: string
        waiting_minutes:
          default: 0
          maximum: 1440.0
          minimum: 0.0
          title: Waiting Minutes
          type: integer
        waypoints:
          anyOf:
          - items:
              $ref: '#/components/schemas/WaypointIn'
            maxItems: 10
            type: array
          - type: 'null'
          title: Waypoints
      required:
      - origin
      - destination
      - pickup_datetime
      title: QuoteEstimateRequest
      type: object
    QuoteOptionOut:
      properties:
        currency:
          title: Currency
          type: string
        fleet_id:
          title: Fleet Id
          type: integer
        large_luggage_capacity:
          anyOf:
          - type: integer
          - type: 'null'
          title: Large Luggage Capacity
        luggage_capacity:
          anyOf:
          - type: integer
          - type: 'null'
          title: Luggage Capacity
        on_request:
          default: false
          title: On Request
          type: boolean
        passenger_capacity:
          title: Passenger Capacity
          type: integer
        requires_manual_confirmation:
          default: false
          title: Requires Manual Confirmation
          type: boolean
        small_luggage_capacity:
          anyOf:
          - type: integer
          - type: 'null'
          title: Small Luggage Capacity
        total_price:
          title: Total Price
          type: number
        vehicle_class:
          title: Vehicle Class
          type: string
        vehicle_type:
          title: Vehicle Type
          type: string
      required:
      - fleet_id
      - vehicle_class
      - vehicle_type
      - passenger_capacity
      - total_price
      - currency
      title: QuoteOptionOut
      type: object
    QuoteOut:
      description: 'A quote (§H). Not a booking, not a reservation, not a capacity hold.


        ``reservation_status`` is ``"not_reserved"`` on every quote this system can

        issue, and no code path sets it otherwise. It is present so that a caller

        rendering this object to a traveler cannot omit the fact by accident.'
      properties:
        adults:
          title: Adults
          type: integer
        children:
          default: 0
          title: Children
          type: integer
        currency:
          default: CHF
          title: Currency
          type: string
        destination:
          title: Destination
          type: string
        expires_at:
          anyOf:
          - format: date-time
            type: string
          - type: 'null'
          title: Expires At
        infants:
          default: 0
          title: Infants
          type: integer
        limitations:
          items:
            type: string
          title: Limitations
          type: array
        luggage:
          title: Luggage
          type: integer
        non_binding:
          default: true
          title: Non Binding
          type: boolean
        options:
          items:
            $ref: '#/components/schemas/QuoteOptionOut'
          title: Options
          type: array
        origin:
          title: Origin
          type: string
        passengers:
          title: Passengers
          type: integer
        pickup_datetime:
          anyOf:
          - format: date-time
            type: string
          - type: 'null'
          title: Pickup Datetime
        quote_id:
          anyOf:
          - type: string
          - type: 'null'
          title: Quote Id
        request_id:
          anyOf:
          - type: string
          - type: 'null'
          title: Request Id
        requires_manual_confirmation:
          default: false
          title: Requires Manual Confirmation
          type: boolean
        reservation_status:
          default: not_reserved
          title: Reservation Status
          type: string
        return_datetime:
          anyOf:
          - format: date-time
            type: string
          - type: 'null'
          title: Return Datetime
        route_basis:
          $ref: '#/components/schemas/RouteBasisOut'
        status:
          title: Status
          type: string
        waypoints:
          items:
            $ref: '#/components/schemas/WaypointOut'
          title: Waypoints
          type: array
      required:
      - status
      - origin
      - destination
      - passengers
      - luggage
      - adults
      - route_basis
      title: QuoteOut
      type: object
    QuoteRequirementField:
      properties:
        description:
          title: Description
          type: string
        name:
          title: Name
          type: string
        required:
          title: Required
          type: boolean
        type:
          title: Type
          type: string
      required:
      - name
      - required
      - type
      - description
      title: QuoteRequirementField
      type: object
    QuoteRequirementsOut:
      description: 'Describes the request contract the quote operations implement. Static

        reference data; documents semantics, does not validate a live request.'
      properties:
        bookability_states:
          items:
            type: string
          title: Bookability States
          type: array
        fields:
          items:
            $ref: '#/components/schemas/QuoteRequirementField'
          title: Fields
          type: array
        notes:
          title: Notes
          type: string
      required:
      - notes
      title: QuoteRequirementsOut
      type: object
    RouteBasisOut:
      description: 'Where the distance and duration behind a price came from (§C, §G).


        ``automatically_payable`` is the single field that answers "can this be

        charged without a human looking at it?". It is computed from

        ``authority`` by ``route_metric_authority.is_automatically_payable`` — only

        a server-verified measurement qualifies.'
      properties:
        authority:
          anyOf:
          - type: string
          - type: 'null'
          title: Authority
        automatically_payable:
          default: false
          title: Automatically Payable
          type: boolean
        distance_km:
          anyOf:
          - type: number
          - type: 'null'
          title: Distance Km
        duration_min:
          anyOf:
          - type: integer
          - type: 'null'
          title: Duration Min
        measured_at:
          anyOf:
          - format: date-time
            type: string
          - type: 'null'
          title: Measured At
        route_contract_version:
          anyOf:
          - type: string
          - type: 'null'
          title: Route Contract Version
        route_fingerprint:
          anyOf:
          - type: string
          - type: 'null'
          title: Route Fingerprint
        routing_basis:
          anyOf:
          - type: string
          - type: 'null'
          title: Routing Basis
      title: RouteBasisOut
      type: object
    RouteOut:
      description: 'Published route facts, with their provenance.


        ``verification_state`` is the field that keeps a caller honest about what it

        is holding: ``PUBLISHED_BASELINE`` means this distance came from Swiss

        Touristy''s published corridor catalogue, not from a live measurement of the

        caller''s specific journey. The quote operations re-measure. A caller must

        never present a baseline distance as the basis of a price.'
      properties:
        destination:
          title: Destination
          type: string
        distance_km:
          anyOf:
          - type: number
          - type: 'null'
          title: Distance Km
        duration_min:
          anyOf:
          - type: integer
          - type: 'null'
          title: Duration Min
        live_context:
          anyOf:
          - additionalProperties: true
            type: object
          - type: 'null'
          title: Live Context
        normalized_destination:
          default: ''
          title: Normalized Destination
          type: string
        normalized_origin:
          default: ''
          title: Normalized Origin
          type: string
        origin:
          title: Origin
          type: string
        quotable:
          default: true
          title: Quotable
          type: boolean
        route_contract_version:
          anyOf:
          - type: string
          - type: 'null'
          title: Route Contract Version
        route_key:
          title: Route Key
          type: string
        routing_basis:
          anyOf:
          - type: string
          - type: 'null'
          title: Routing Basis
        transfer_type:
          title: Transfer Type
          type: string
        verification_state:
          title: Verification State
          type: string
        waypoints:
          items:
            $ref: '#/components/schemas/WaypointOut'
          title: Waypoints
          type: array
      required:
      - route_key
      - origin
      - destination
      - transfer_type
      - verification_state
      title: RouteOut
      type: object
    TransferServiceListOut:
      properties:
        services:
          items:
            $ref: '#/components/schemas/TransferServiceOut'
          title: Services
          type: array
      title: TransferServiceListOut
      type: object
    TransferServiceOut:
      description: 'One published transfer corridor. Carries no price by design — §A puts

        price behind the quote operations.'
      properties:
        destination:
          title: Destination
          type: string
        distance_km:
          anyOf:
          - type: number
          - type: 'null'
          title: Distance Km
        duration_min:
          anyOf:
          - type: integer
          - type: 'null'
          title: Duration Min
        origin:
          title: Origin
          type: string
        route_key:
          title: Route Key
          type: string
        transfer_type:
          title: Transfer Type
          type: string
      required:
      - route_key
      - origin
      - destination
      - transfer_type
      title: TransferServiceOut
      type: object
    VehicleClassListOut:
      properties:
        luggage_definitions:
          additionalProperties:
            $ref: '#/components/schemas/LuggageDefinitionOut'
          title: Luggage Definitions
          type: object
        special_item_kinds:
          items:
            type: string
          title: Special Item Kinds
          type: array
        vehicle_classes:
          items:
            $ref: '#/components/schemas/VehicleClassOut'
          title: Vehicle Classes
          type: array
      title: VehicleClassListOut
      type: object
    VehicleClassOut:
      description: 'Public capacity descriptor. No rates, no internal pricing category, no

        supplier, no cost basis.


        ``instant_bookable`` is deliberately not called ``available``. Swiss

        Touristy holds no capacity at discovery time, so availability is not a fact

        this endpoint can state. What it can state is whether the class is

        self-servable or must route to confirmation.'
      properties:
        instant_bookable:
          default: false
          title: Instant Bookable
          type: boolean
        large_luggage_capacity:
          anyOf:
          - type: integer
          - type: 'null'
          title: Large Luggage Capacity
        luggage_capacity:
          anyOf:
          - type: integer
          - type: 'null'
          title: Luggage Capacity
        passenger_capacity:
          title: Passenger Capacity
          type: integer
        small_luggage_capacity:
          anyOf:
          - type: integer
          - type: 'null'
          title: Small Luggage Capacity
        vehicle_class:
          title: Vehicle Class
          type: string
        vehicle_type:
          anyOf:
          - type: string
          - type: 'null'
          title: Vehicle Type
      required:
      - vehicle_class
      - passenger_capacity
      title: VehicleClassOut
      type: object
    WaypointIn:
      additionalProperties: false
      description: 'One intermediate stop on the journey (§C, §G).


        ``stop_duration_min`` is the declared dwell time at this stop. Founder F4

        (2026-08-18) makes it part of route identity: the customer is asked how long

        they want at each stop and the answer must be captured before the quote and

        before payment, so A→C(30min)→B and A→C(90min)→B are different journeys with

        different fingerprints.


        ``None`` and ``0`` are deliberately different answers and stay different —

        ``None`` means nobody asked, ``0`` means drive through without waiting. Only

        the second is a commercial statement.'
      properties:
        lat:
          anyOf:
          - maximum: 90.0
            minimum: -90.0
            type: number
          - type: 'null'
          title: Lat
        lng:
          anyOf:
          - maximum: 180.0
            minimum: -180.0
            type: number
          - type: 'null'
          title: Lng
        name:
          maxLength: 512
          minLength: 1
          title: Name
          type: string
        place_id:
          anyOf:
          - maxLength: 256
            type: string
          - type: 'null'
          title: Place Id
        stop_duration_min:
          anyOf:
          - maximum: 720.0
            minimum: 0.0
            type: integer
          - type: 'null'
          title: Stop Duration Min
      required:
      - name
      title: WaypointIn
      type: object
    WaypointOut:
      description: 'A stop as the quote records it. Echoed back because the declared dwell is

        part of what was priced and what a booking is checked against.'
      properties:
        name:
          title: Name
          type: string
        stop_duration_min:
          anyOf:
          - type: integer
          - type: 'null'
          title: Stop Duration Min
      required:
      - name
      title: WaypointOut
      type: object
  securitySchemes:
    Auth0:
      description: 'Auth0 client-credentials flow. Request a token from the token URL with audience "https://api.swisstouristy.com/public/v1"
        and the scope the operation names; a broader scope is never accepted as a substitute for the right
        one. The audience is an identifier, not an address — do not try to call it. Credentials are issued
        on request: there is no self-service signup, and dynamic client registration is disabled on the
        tenant.'
      flows:
        clientCredentials:
          scopes:
            checkout:prepare: Hand a traveler to Swiss Touristy's hosted checkout for a live quote of
              your own. Creates no booking and takes no payment.
            discovery: Connect to the MCP server. Required by the MCP transport on every connection; no
              REST operation requires it, and the REST discovery endpoints are anonymous.
            quote:create: Create a quote of your own.
            quote:read-own: Read a quote you created. Never another caller's.
          tokenUrl: https://swisstouristy.eu.auth0.com/oauth/token
      type: oauth2
info:
  description: 'Swiss Touristy''s public commercial interface for AI agents and machine clients.


    **This document is generated from the running routes** (see

    `scripts/generate_public_openapi.py`). It is not maintained by hand, and a route

    that is not described here does not exist.


    ## What this API is for


    Discover Swiss Touristy''s transfer services, obtain an authoritative price for a

    specific journey, read that quote back, and hand the traveler to Swiss Touristy''s

    hosted checkout to complete a booking and pay.


    ## What it will not do


    There is no booking creation, payment, refund, cancellation, amendment, dispatch,

    supplier, reseller, pricing-override or fleet-administration operation on this

    surface, and none is planned for v1.


    ## The commercial contract


    The caller describes the journey; Swiss Touristy determines the quote. There is

    no field on `POST /quotes` for a distance, a duration, a price, a currency or a

    vehicle selection — the route is measured on Swiss Touristy''s servers and the

    price is derived from that measurement.


    `POST /quote-intents` is the one operation that accepts caller-supplied

    `distance_km` and `duration_min`. It is anonymous, persists nothing, issues no

    quote id, and its output cannot be continued to checkout. Its `route_basis` is

    labelled `CLIENT_PROVIDED` when caller metrics were used.


    ## What a quote is


    A 30-minute price snapshot. It is **not a booking, not a reservation and not a

    capacity hold** — no vehicle or driver is held when a quote is issued, and

    `reservation_status` is always `not_reserved`. Availability is confirmed by

    Swiss Touristy at booking time, not here.


    ## Errors


    Every failure is `application/problem+json` (RFC 7807) carrying a stable

    `UPPER_SNAKE` `code`, a `retryable` flag, a `next_action` describing how to

    recover, and a `request_id` to quote when reporting a problem.


    ## Rate limits


    Tiered by what an operation costs. Each operation names its tier in the

    `x-rate-limit-tier` extension, and the full table is in `x-ratelimit-tiers` on

    this document. A `429` carries `Retry-After` in seconds.


    | Tier | Requests | Window |

    | --- | --- | --- |

    | `discovery` | 120 | 1 min |

    | `routing` | 60 | 1 min |

    | `quote_estimate` | 20 | 1 min |

    | `quote_authoritative` | 10 | 1 min |

    | `quote_read` | 60 | 1 min |

    | `checkout` | 5 | 1 min |

    | `auth_failure` | 10 | 300s |


    ## Idempotency


    `Idempotency-Key` is honoured on `POST /quotes` and `POST /checkout-sessions`.

    The same key with an identical body replays the original response; the same key

    with a different body is rejected.'
  title: Swiss Touristy Public API
  version: 1.0.0
openapi: 3.1.2
paths:
  /api/public/v1/checkout-sessions:
    post:
      description: 'Hand the traveler off to Swiss Touristy''s hosted checkout.


        Creates no booking, no PaymentIntent and no capacity hold, and returns no

        Stripe identifier or secret. Payment happens on Swiss Touristy.


        Gated by PUBLIC_CHECKOUT_ENABLED, shared with the internal surface so there

        is one answer to "is public checkout live anywhere".'
      operationId: createCheckoutHandoff
      parameters:
      - in: header
        name: Idempotency-Key
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          title: Idempotency-Key
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CheckoutHandoffRequest'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CheckoutHandoffOut'
          description: Successful Response
        '401':
          content:
            application/problem+json:
              examples:
                AUTHENTICATION_REQUIRED:
                  description: Present a bearer token for the required scope.
                  summary: Authentication required
                  value:
                    code: AUTHENTICATION_REQUIRED
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Present a bearer token for the required scope.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 401
                    title: Authentication required
                    type: https://swisstouristy.com/developers/errors/authentication_required
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Authentication required
        '403':
          content:
            application/problem+json:
              examples:
                FORBIDDEN:
                  description: This token lacks the scope for this operation.
                  summary: Forbidden
                  value:
                    code: FORBIDDEN
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: This token lacks the scope for this operation.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 403
                    title: Forbidden
                    type: https://swisstouristy.com/developers/errors/forbidden
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Forbidden
        '404':
          content:
            application/problem+json:
              examples:
                QUOTE_NOT_FOUND:
                  description: No quote with this id is visible to this caller.
                  summary: Quote not found
                  value:
                    code: QUOTE_NOT_FOUND
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: No quote with this id is visible to this caller.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 404
                    title: Quote not found
                    type: https://swisstouristy.com/developers/errors/quote_not_found
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Quote not found
        '409':
          content:
            application/problem+json:
              examples:
                MANUAL_CONFIRMATION_REQUIRED:
                  description: This journey needs Swiss Touristy confirmation and cannot be self-served.
                  summary: Manual confirmation required
                  value:
                    code: MANUAL_CONFIRMATION_REQUIRED
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: This journey needs Swiss Touristy confirmation and cannot be self-served.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 409
                    title: Manual confirmation required
                    type: https://swisstouristy.com/developers/errors/manual_confirmation_required
                QUOTE_EXPIRED:
                  description: Create a new quote; pricing snapshots last 30 minutes.
                  summary: Quote expired
                  value:
                    code: QUOTE_EXPIRED
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Create a new quote; pricing snapshots last 30 minutes.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 409
                    title: Quote expired
                    type: https://swisstouristy.com/developers/errors/quote_expired
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Quote expired, Manual confirmation required
        '422':
          content:
            application/problem+json:
              examples:
                INVALID_REQUEST:
                  description: Correct the named fields and resubmit.
                  summary: Invalid request
                  value:
                    code: INVALID_REQUEST
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Correct the named fields and resubmit.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Invalid request
                    type: https://swisstouristy.com/developers/errors/invalid_request
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Invalid request
        '429':
          content:
            application/problem+json:
              examples:
                RATE_LIMITED:
                  description: Wait for the interval in retry_after_seconds, then retry.
                  summary: Rate limit exceeded
                  value:
                    code: RATE_LIMITED
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Wait for the interval in retry_after_seconds, then retry.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retry_after_seconds: 30
                    retryable: true
                    status: 429
                    title: Rate limit exceeded
                    type: https://swisstouristy.com/developers/errors/rate_limited
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Rate limit exceeded
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
        '503':
          content:
            application/problem+json:
              examples:
                QUOTE_UNAVAILABLE:
                  description: Retry shortly; no quote could be produced.
                  summary: Quote unavailable
                  value:
                    code: QUOTE_UNAVAILABLE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Retry shortly; no quote could be produced.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: true
                    status: 503
                    title: Quote unavailable
                    type: https://swisstouristy.com/developers/errors/quote_unavailable
                UPSTREAM_UNAVAILABLE:
                  description: Retry shortly; a dependency was unavailable.
                  summary: Upstream unavailable
                  value:
                    code: UPSTREAM_UNAVAILABLE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Retry shortly; a dependency was unavailable.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: true
                    status: 503
                    title: Upstream unavailable
                    type: https://swisstouristy.com/developers/errors/upstream_unavailable
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Upstream unavailable, Quote unavailable
      security:
      - Auth0:
        - checkout:prepare
      summary: Create Checkout Handoff
      x-rate-limit-tier: checkout
  /api/public/v1/checkout-sessions/{quote_id}:
    get:
      description: 'Read the quote behind a continuation link.


        Anonymous by necessity: the traveler following the link is not the agent

        that created the quote, so no OAuth identity can be required. The

        continuation signature is the credential — it is keyed with SECRET_KEY,

        covers the quote id, the vehicle and the expiry, and grants nothing except

        reading this one quote''s commercial terms.


        Without this the handoff cannot preserve quote identity: the receiving page

        would have to re-price the journey, and the traveler could be shown one

        amount by the agent and charged another.'
      operationId: resolveCheckoutHandoff
      parameters:
      - in: path
        name: quote_id
        required: true
        schema:
          title: Quote Id
          type: string
      - in: query
        name: fleet_id
        required: true
        schema:
          title: Fleet Id
          type: integer
      - in: query
        name: sig
        required: true
        schema:
          title: Sig
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CheckoutHandoffOut'
          description: Successful Response
        '404':
          content:
            application/problem+json:
              examples:
                QUOTE_NOT_FOUND:
                  description: No quote with this id is visible to this caller.
                  summary: Quote not found
                  value:
                    code: QUOTE_NOT_FOUND
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: No quote with this id is visible to this caller.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 404
                    title: Quote not found
                    type: https://swisstouristy.com/developers/errors/quote_not_found
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Quote not found
        '409':
          content:
            application/problem+json:
              examples:
                QUOTE_EXPIRED:
                  description: Create a new quote; pricing snapshots last 30 minutes.
                  summary: Quote expired
                  value:
                    code: QUOTE_EXPIRED
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Create a new quote; pricing snapshots last 30 minutes.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 409
                    title: Quote expired
                    type: https://swisstouristy.com/developers/errors/quote_expired
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Quote expired
        '422':
          content:
            application/problem+json:
              examples:
                INVALID_REQUEST:
                  description: Correct the named fields and resubmit.
                  summary: Invalid request
                  value:
                    code: INVALID_REQUEST
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Correct the named fields and resubmit.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Invalid request
                    type: https://swisstouristy.com/developers/errors/invalid_request
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Invalid request
        '429':
          content:
            application/problem+json:
              examples:
                RATE_LIMITED:
                  description: Wait for the interval in retry_after_seconds, then retry.
                  summary: Rate limit exceeded
                  value:
                    code: RATE_LIMITED
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Wait for the interval in retry_after_seconds, then retry.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retry_after_seconds: 30
                    retryable: true
                    status: 429
                    title: Rate limit exceeded
                    type: https://swisstouristy.com/developers/errors/rate_limited
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Rate limit exceeded
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
        '503':
          content:
            application/problem+json:
              examples:
                UPSTREAM_UNAVAILABLE:
                  description: Retry shortly; a dependency was unavailable.
                  summary: Upstream unavailable
                  value:
                    code: UPSTREAM_UNAVAILABLE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Retry shortly; a dependency was unavailable.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: true
                    status: 503
                    title: Upstream unavailable
                    type: https://swisstouristy.com/developers/errors/upstream_unavailable
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Upstream unavailable
      summary: Resolve Checkout Handoff
      x-rate-limit-tier: quote_read
  /api/public/v1/policies/{policy_key}:
    get:
      operationId: getPolicy
      parameters:
      - in: path
        name: policy_key
        required: true
        schema:
          title: Policy Key
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PolicyOut'
          description: Successful Response
        '404':
          content:
            application/problem+json:
              examples:
                QUOTE_NOT_FOUND:
                  description: No quote with this id is visible to this caller.
                  summary: Quote not found
                  value:
                    code: QUOTE_NOT_FOUND
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: No quote with this id is visible to this caller.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 404
                    title: Quote not found
                    type: https://swisstouristy.com/developers/errors/quote_not_found
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Quote not found
        '422':
          content:
            application/problem+json:
              examples:
                INVALID_REQUEST:
                  description: Correct the named fields and resubmit.
                  summary: Invalid request
                  value:
                    code: INVALID_REQUEST
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Correct the named fields and resubmit.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Invalid request
                    type: https://swisstouristy.com/developers/errors/invalid_request
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Invalid request
        '429':
          content:
            application/problem+json:
              examples:
                RATE_LIMITED:
                  description: Wait for the interval in retry_after_seconds, then retry.
                  summary: Rate limit exceeded
                  value:
                    code: RATE_LIMITED
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Wait for the interval in retry_after_seconds, then retry.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retry_after_seconds: 30
                    retryable: true
                    status: 429
                    title: Rate limit exceeded
                    type: https://swisstouristy.com/developers/errors/rate_limited
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Rate limit exceeded
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
        '503':
          content:
            application/problem+json:
              examples:
                UPSTREAM_UNAVAILABLE:
                  description: Retry shortly; a dependency was unavailable.
                  summary: Upstream unavailable
                  value:
                    code: UPSTREAM_UNAVAILABLE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Retry shortly; a dependency was unavailable.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: true
                    status: 503
                    title: Upstream unavailable
                    type: https://swisstouristy.com/developers/errors/upstream_unavailable
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Upstream unavailable
      summary: Get Policy
      x-rate-limit-tier: discovery
  /api/public/v1/quote-intents:
    post:
      description: 'Anonymous, rate-limited, non-binding estimate. Nothing is persisted, no

        quote id is issued, and no contact is created.'
      operationId: createQuoteEstimate
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QuoteEstimateRequest'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuoteOut'
          description: Successful Response
        '422':
          content:
            application/problem+json:
              examples:
                INVALID_DATETIME:
                  description: Send pickup_datetime as an ISO 8601 instant with an offset.
                  summary: Invalid pickup datetime
                  value:
                    code: INVALID_DATETIME
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Send pickup_datetime as an ISO 8601 instant with an offset.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Invalid pickup datetime
                    type: https://swisstouristy.com/developers/errors/invalid_datetime
                INVALID_LOCATION:
                  description: Supply a more specific pickup or drop-off location.
                  summary: Invalid location
                  value:
                    code: INVALID_LOCATION
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Supply a more specific pickup or drop-off location.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Invalid location
                    type: https://swisstouristy.com/developers/errors/invalid_location
                INVALID_REQUEST:
                  description: Correct the named fields and resubmit.
                  summary: Invalid request
                  value:
                    code: INVALID_REQUEST
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Correct the named fields and resubmit.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Invalid request
                    type: https://swisstouristy.com/developers/errors/invalid_request
                LEAD_TIME_NOT_SUPPORTED:
                  description: Choose a later pickup_datetime that meets the minimum notice.
                  summary: Insufficient notice
                  value:
                    code: LEAD_TIME_NOT_SUPPORTED
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Choose a later pickup_datetime that meets the minimum notice.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Insufficient notice
                    type: https://swisstouristy.com/developers/errors/lead_time_not_supported
                NO_ELIGIBLE_VEHICLE:
                  description: Reduce passengers or luggage, or split the party.
                  summary: No eligible vehicle
                  value:
                    code: NO_ELIGIBLE_VEHICLE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Reduce passengers or luggage, or split the party.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: No eligible vehicle
                    type: https://swisstouristy.com/developers/errors/no_eligible_vehicle
                PAST_DATETIME:
                  description: Send a pickup_datetime in the future.
                  summary: Pickup datetime is in the past
                  value:
                    code: PAST_DATETIME
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Send a pickup_datetime in the future.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Pickup datetime is in the past
                    type: https://swisstouristy.com/developers/errors/past_datetime
                RETURN_TIME_INVALID:
                  description: Set the return pickup after the outbound arrival.
                  summary: Invalid return time
                  value:
                    code: RETURN_TIME_INVALID
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Set the return pickup after the outbound arrival.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Invalid return time
                    type: https://swisstouristy.com/developers/errors/return_time_invalid
                UNSUPPORTED_ROUTE:
                  description: This journey is outside the served area. Do not retry unchanged.
                  summary: Route not served
                  value:
                    code: UNSUPPORTED_ROUTE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: This journey is outside the served area. Do not retry unchanged.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Route not served
                    type: https://swisstouristy.com/developers/errors/unsupported_route
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Invalid request, Invalid location, Route not served, Invalid pickup datetime, Pickup
            datetime is in the past, Insufficient notice, Invalid return time, No eligible vehicle
        '429':
          content:
            application/problem+json:
              examples:
                RATE_LIMITED:
                  description: Wait for the interval in retry_after_seconds, then retry.
                  summary: Rate limit exceeded
                  value:
                    code: RATE_LIMITED
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Wait for the interval in retry_after_seconds, then retry.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retry_after_seconds: 30
                    retryable: true
                    status: 429
                    title: Rate limit exceeded
                    type: https://swisstouristy.com/developers/errors/rate_limited
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Rate limit exceeded
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
        '503':
          content:
            application/problem+json:
              examples:
                ROUTE_UNAVAILABLE:
                  description: Retry shortly; the routing provider did not answer.
                  summary: Route unavailable
                  value:
                    code: ROUTE_UNAVAILABLE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Retry shortly; the routing provider did not answer.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: true
                    status: 503
                    title: Route unavailable
                    type: https://swisstouristy.com/developers/errors/route_unavailable
                UPSTREAM_UNAVAILABLE:
                  description: Retry shortly; a dependency was unavailable.
                  summary: Upstream unavailable
                  value:
                    code: UPSTREAM_UNAVAILABLE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Retry shortly; a dependency was unavailable.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: true
                    status: 503
                    title: Upstream unavailable
                    type: https://swisstouristy.com/developers/errors/upstream_unavailable
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Upstream unavailable, Route unavailable
      summary: Create Quote Intent
      x-rate-limit-tier: quote_estimate
  /api/public/v1/quote-requirements:
    get:
      operationId: getQuoteRequirements
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuoteRequirementsOut'
          description: Successful Response
        '422':
          content:
            application/problem+json:
              examples:
                INVALID_REQUEST:
                  description: Correct the named fields and resubmit.
                  summary: Invalid request
                  value:
                    code: INVALID_REQUEST
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Correct the named fields and resubmit.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Invalid request
                    type: https://swisstouristy.com/developers/errors/invalid_request
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Invalid request
        '429':
          content:
            application/problem+json:
              examples:
                RATE_LIMITED:
                  description: Wait for the interval in retry_after_seconds, then retry.
                  summary: Rate limit exceeded
                  value:
                    code: RATE_LIMITED
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Wait for the interval in retry_after_seconds, then retry.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retry_after_seconds: 30
                    retryable: true
                    status: 429
                    title: Rate limit exceeded
                    type: https://swisstouristy.com/developers/errors/rate_limited
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Rate limit exceeded
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
        '503':
          content:
            application/problem+json:
              examples:
                UPSTREAM_UNAVAILABLE:
                  description: Retry shortly; a dependency was unavailable.
                  summary: Upstream unavailable
                  value:
                    code: UPSTREAM_UNAVAILABLE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Retry shortly; a dependency was unavailable.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: true
                    status: 503
                    title: Upstream unavailable
                    type: https://swisstouristy.com/developers/errors/upstream_unavailable
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Upstream unavailable
      summary: Get Quote Requirements
      x-rate-limit-tier: discovery
  /api/public/v1/quotes:
    post:
      description: 'Create an authoritative, owned, persisted quote.


        The route is measured on the server and the snapshot carries full route

        provenance, so the resulting quote id is one the booking path will accept.

        Still not a booking and not a capacity hold.'
      operationId: createQuote
      parameters:
      - in: header
        name: Idempotency-Key
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          title: Idempotency-Key
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateQuoteRequest'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuoteOut'
          description: Successful Response
        '401':
          content:
            application/problem+json:
              examples:
                AUTHENTICATION_REQUIRED:
                  description: Present a bearer token for the required scope.
                  summary: Authentication required
                  value:
                    code: AUTHENTICATION_REQUIRED
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Present a bearer token for the required scope.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 401
                    title: Authentication required
                    type: https://swisstouristy.com/developers/errors/authentication_required
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Authentication required
        '403':
          content:
            application/problem+json:
              examples:
                FORBIDDEN:
                  description: This token lacks the scope for this operation.
                  summary: Forbidden
                  value:
                    code: FORBIDDEN
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: This token lacks the scope for this operation.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 403
                    title: Forbidden
                    type: https://swisstouristy.com/developers/errors/forbidden
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Forbidden
        '422':
          content:
            application/problem+json:
              examples:
                INVALID_DATETIME:
                  description: Send pickup_datetime as an ISO 8601 instant with an offset.
                  summary: Invalid pickup datetime
                  value:
                    code: INVALID_DATETIME
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Send pickup_datetime as an ISO 8601 instant with an offset.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Invalid pickup datetime
                    type: https://swisstouristy.com/developers/errors/invalid_datetime
                INVALID_LOCATION:
                  description: Supply a more specific pickup or drop-off location.
                  summary: Invalid location
                  value:
                    code: INVALID_LOCATION
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Supply a more specific pickup or drop-off location.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Invalid location
                    type: https://swisstouristy.com/developers/errors/invalid_location
                INVALID_REQUEST:
                  description: Correct the named fields and resubmit.
                  summary: Invalid request
                  value:
                    code: INVALID_REQUEST
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Correct the named fields and resubmit.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Invalid request
                    type: https://swisstouristy.com/developers/errors/invalid_request
                LEAD_TIME_NOT_SUPPORTED:
                  description: Choose a later pickup_datetime that meets the minimum notice.
                  summary: Insufficient notice
                  value:
                    code: LEAD_TIME_NOT_SUPPORTED
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Choose a later pickup_datetime that meets the minimum notice.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Insufficient notice
                    type: https://swisstouristy.com/developers/errors/lead_time_not_supported
                NO_ELIGIBLE_VEHICLE:
                  description: Reduce passengers or luggage, or split the party.
                  summary: No eligible vehicle
                  value:
                    code: NO_ELIGIBLE_VEHICLE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Reduce passengers or luggage, or split the party.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: No eligible vehicle
                    type: https://swisstouristy.com/developers/errors/no_eligible_vehicle
                PAST_DATETIME:
                  description: Send a pickup_datetime in the future.
                  summary: Pickup datetime is in the past
                  value:
                    code: PAST_DATETIME
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Send a pickup_datetime in the future.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Pickup datetime is in the past
                    type: https://swisstouristy.com/developers/errors/past_datetime
                RETURN_TIME_INVALID:
                  description: Set the return pickup after the outbound arrival.
                  summary: Invalid return time
                  value:
                    code: RETURN_TIME_INVALID
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Set the return pickup after the outbound arrival.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Invalid return time
                    type: https://swisstouristy.com/developers/errors/return_time_invalid
                UNSUPPORTED_ROUTE:
                  description: This journey is outside the served area. Do not retry unchanged.
                  summary: Route not served
                  value:
                    code: UNSUPPORTED_ROUTE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: This journey is outside the served area. Do not retry unchanged.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Route not served
                    type: https://swisstouristy.com/developers/errors/unsupported_route
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Invalid request, Invalid location, Route not served, Invalid pickup datetime, Pickup
            datetime is in the past, Insufficient notice, Invalid return time, No eligible vehicle
        '429':
          content:
            application/problem+json:
              examples:
                RATE_LIMITED:
                  description: Wait for the interval in retry_after_seconds, then retry.
                  summary: Rate limit exceeded
                  value:
                    code: RATE_LIMITED
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Wait for the interval in retry_after_seconds, then retry.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retry_after_seconds: 30
                    retryable: true
                    status: 429
                    title: Rate limit exceeded
                    type: https://swisstouristy.com/developers/errors/rate_limited
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Rate limit exceeded
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
        '503':
          content:
            application/problem+json:
              examples:
                QUOTE_UNAVAILABLE:
                  description: Retry shortly; no quote could be produced.
                  summary: Quote unavailable
                  value:
                    code: QUOTE_UNAVAILABLE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Retry shortly; no quote could be produced.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: true
                    status: 503
                    title: Quote unavailable
                    type: https://swisstouristy.com/developers/errors/quote_unavailable
                ROUTE_UNAVAILABLE:
                  description: Retry shortly; the routing provider did not answer.
                  summary: Route unavailable
                  value:
                    code: ROUTE_UNAVAILABLE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Retry shortly; the routing provider did not answer.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: true
                    status: 503
                    title: Route unavailable
                    type: https://swisstouristy.com/developers/errors/route_unavailable
                UPSTREAM_UNAVAILABLE:
                  description: Retry shortly; a dependency was unavailable.
                  summary: Upstream unavailable
                  value:
                    code: UPSTREAM_UNAVAILABLE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Retry shortly; a dependency was unavailable.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: true
                    status: 503
                    title: Upstream unavailable
                    type: https://swisstouristy.com/developers/errors/upstream_unavailable
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Upstream unavailable, Route unavailable, Quote unavailable
      security:
      - Auth0:
        - quote:create
      summary: Create Quote
      x-rate-limit-tier: quote_authoritative
  /api/public/v1/quotes/{quote_id}:
    get:
      description: 'Owner-only. A quote belonging to another caller and a quote that does not

        exist are answered identically — see quoting.get_own_quote for why.'
      operationId: getOwnQuote
      parameters:
      - in: path
        name: quote_id
        required: true
        schema:
          title: Quote Id
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuoteOut'
          description: Successful Response
        '401':
          content:
            application/problem+json:
              examples:
                AUTHENTICATION_REQUIRED:
                  description: Present a bearer token for the required scope.
                  summary: Authentication required
                  value:
                    code: AUTHENTICATION_REQUIRED
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Present a bearer token for the required scope.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 401
                    title: Authentication required
                    type: https://swisstouristy.com/developers/errors/authentication_required
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Authentication required
        '403':
          content:
            application/problem+json:
              examples:
                FORBIDDEN:
                  description: This token lacks the scope for this operation.
                  summary: Forbidden
                  value:
                    code: FORBIDDEN
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: This token lacks the scope for this operation.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 403
                    title: Forbidden
                    type: https://swisstouristy.com/developers/errors/forbidden
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Forbidden
        '404':
          content:
            application/problem+json:
              examples:
                QUOTE_NOT_FOUND:
                  description: No quote with this id is visible to this caller.
                  summary: Quote not found
                  value:
                    code: QUOTE_NOT_FOUND
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: No quote with this id is visible to this caller.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 404
                    title: Quote not found
                    type: https://swisstouristy.com/developers/errors/quote_not_found
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Quote not found
        '422':
          content:
            application/problem+json:
              examples:
                INVALID_REQUEST:
                  description: Correct the named fields and resubmit.
                  summary: Invalid request
                  value:
                    code: INVALID_REQUEST
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Correct the named fields and resubmit.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Invalid request
                    type: https://swisstouristy.com/developers/errors/invalid_request
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Invalid request
        '429':
          content:
            application/problem+json:
              examples:
                RATE_LIMITED:
                  description: Wait for the interval in retry_after_seconds, then retry.
                  summary: Rate limit exceeded
                  value:
                    code: RATE_LIMITED
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Wait for the interval in retry_after_seconds, then retry.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retry_after_seconds: 30
                    retryable: true
                    status: 429
                    title: Rate limit exceeded
                    type: https://swisstouristy.com/developers/errors/rate_limited
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Rate limit exceeded
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
        '503':
          content:
            application/problem+json:
              examples:
                UPSTREAM_UNAVAILABLE:
                  description: Retry shortly; a dependency was unavailable.
                  summary: Upstream unavailable
                  value:
                    code: UPSTREAM_UNAVAILABLE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Retry shortly; a dependency was unavailable.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: true
                    status: 503
                    title: Upstream unavailable
                    type: https://swisstouristy.com/developers/errors/upstream_unavailable
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Upstream unavailable
      security:
      - Auth0:
        - quote:read-own
      summary: Get Own Quote
      x-rate-limit-tier: quote_read
  /api/public/v1/routes:
    get:
      description: 'Origin/destination form. Exists so this surface and the MCP surface

        accept the same address forms — §B: one contract, not two dialects.'
      operationId: getRouteByPair
      parameters:
      - in: query
        name: origin
        required: true
        schema:
          title: Origin
          type: string
      - in: query
        name: destination
        required: true
        schema:
          title: Destination
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RouteOut'
          description: Successful Response
        '422':
          content:
            application/problem+json:
              examples:
                INVALID_REQUEST:
                  description: Correct the named fields and resubmit.
                  summary: Invalid request
                  value:
                    code: INVALID_REQUEST
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Correct the named fields and resubmit.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Invalid request
                    type: https://swisstouristy.com/developers/errors/invalid_request
                UNSUPPORTED_ROUTE:
                  description: This journey is outside the served area. Do not retry unchanged.
                  summary: Route not served
                  value:
                    code: UNSUPPORTED_ROUTE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: This journey is outside the served area. Do not retry unchanged.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Route not served
                    type: https://swisstouristy.com/developers/errors/unsupported_route
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Invalid request, Route not served
        '429':
          content:
            application/problem+json:
              examples:
                RATE_LIMITED:
                  description: Wait for the interval in retry_after_seconds, then retry.
                  summary: Rate limit exceeded
                  value:
                    code: RATE_LIMITED
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Wait for the interval in retry_after_seconds, then retry.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retry_after_seconds: 30
                    retryable: true
                    status: 429
                    title: Rate limit exceeded
                    type: https://swisstouristy.com/developers/errors/rate_limited
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Rate limit exceeded
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
        '503':
          content:
            application/problem+json:
              examples:
                UPSTREAM_UNAVAILABLE:
                  description: Retry shortly; a dependency was unavailable.
                  summary: Upstream unavailable
                  value:
                    code: UPSTREAM_UNAVAILABLE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Retry shortly; a dependency was unavailable.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: true
                    status: 503
                    title: Upstream unavailable
                    type: https://swisstouristy.com/developers/errors/upstream_unavailable
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Upstream unavailable
      summary: Get Route By Pair
      x-rate-limit-tier: routing
  /api/public/v1/routes/{route_key}:
    get:
      operationId: getRoute
      parameters:
      - in: path
        name: route_key
        required: true
        schema:
          title: Route Key
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RouteOut'
          description: Successful Response
        '422':
          content:
            application/problem+json:
              examples:
                INVALID_REQUEST:
                  description: Correct the named fields and resubmit.
                  summary: Invalid request
                  value:
                    code: INVALID_REQUEST
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Correct the named fields and resubmit.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Invalid request
                    type: https://swisstouristy.com/developers/errors/invalid_request
                UNSUPPORTED_ROUTE:
                  description: This journey is outside the served area. Do not retry unchanged.
                  summary: Route not served
                  value:
                    code: UNSUPPORTED_ROUTE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: This journey is outside the served area. Do not retry unchanged.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Route not served
                    type: https://swisstouristy.com/developers/errors/unsupported_route
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Invalid request, Route not served
        '429':
          content:
            application/problem+json:
              examples:
                RATE_LIMITED:
                  description: Wait for the interval in retry_after_seconds, then retry.
                  summary: Rate limit exceeded
                  value:
                    code: RATE_LIMITED
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Wait for the interval in retry_after_seconds, then retry.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retry_after_seconds: 30
                    retryable: true
                    status: 429
                    title: Rate limit exceeded
                    type: https://swisstouristy.com/developers/errors/rate_limited
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Rate limit exceeded
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
        '503':
          content:
            application/problem+json:
              examples:
                UPSTREAM_UNAVAILABLE:
                  description: Retry shortly; a dependency was unavailable.
                  summary: Upstream unavailable
                  value:
                    code: UPSTREAM_UNAVAILABLE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Retry shortly; a dependency was unavailable.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: true
                    status: 503
                    title: Upstream unavailable
                    type: https://swisstouristy.com/developers/errors/upstream_unavailable
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Upstream unavailable
      summary: Get Route
      x-rate-limit-tier: routing
  /api/public/v1/services/transfers:
    get:
      operationId: listTransferServices
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransferServiceListOut'
          description: Successful Response
        '422':
          content:
            application/problem+json:
              examples:
                INVALID_REQUEST:
                  description: Correct the named fields and resubmit.
                  summary: Invalid request
                  value:
                    code: INVALID_REQUEST
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Correct the named fields and resubmit.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Invalid request
                    type: https://swisstouristy.com/developers/errors/invalid_request
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Invalid request
        '429':
          content:
            application/problem+json:
              examples:
                RATE_LIMITED:
                  description: Wait for the interval in retry_after_seconds, then retry.
                  summary: Rate limit exceeded
                  value:
                    code: RATE_LIMITED
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Wait for the interval in retry_after_seconds, then retry.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retry_after_seconds: 30
                    retryable: true
                    status: 429
                    title: Rate limit exceeded
                    type: https://swisstouristy.com/developers/errors/rate_limited
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Rate limit exceeded
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
        '503':
          content:
            application/problem+json:
              examples:
                UPSTREAM_UNAVAILABLE:
                  description: Retry shortly; a dependency was unavailable.
                  summary: Upstream unavailable
                  value:
                    code: UPSTREAM_UNAVAILABLE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Retry shortly; a dependency was unavailable.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: true
                    status: 503
                    title: Upstream unavailable
                    type: https://swisstouristy.com/developers/errors/upstream_unavailable
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Upstream unavailable
      summary: List Transfer Services
      x-rate-limit-tier: discovery
  /api/public/v1/vehicle-classes:
    get:
      operationId: listVehicleClasses
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VehicleClassListOut'
          description: Successful Response
        '422':
          content:
            application/problem+json:
              examples:
                INVALID_REQUEST:
                  description: Correct the named fields and resubmit.
                  summary: Invalid request
                  value:
                    code: INVALID_REQUEST
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Correct the named fields and resubmit.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: false
                    status: 422
                    title: Invalid request
                    type: https://swisstouristy.com/developers/errors/invalid_request
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Invalid request
        '429':
          content:
            application/problem+json:
              examples:
                RATE_LIMITED:
                  description: Wait for the interval in retry_after_seconds, then retry.
                  summary: Rate limit exceeded
                  value:
                    code: RATE_LIMITED
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Wait for the interval in retry_after_seconds, then retry.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retry_after_seconds: 30
                    retryable: true
                    status: 429
                    title: Rate limit exceeded
                    type: https://swisstouristy.com/developers/errors/rate_limited
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Rate limit exceeded
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
        '503':
          content:
            application/problem+json:
              examples:
                UPSTREAM_UNAVAILABLE:
                  description: Retry shortly; a dependency was unavailable.
                  summary: Upstream unavailable
                  value:
                    code: UPSTREAM_UNAVAILABLE
                    detail: A sentence describing this particular failure.
                    field_errors: []
                    instance: /api/public/v1/...
                    next_action: Retry shortly; a dependency was unavailable.
                    request_id: req_9f2c1b7ae4d84c6f9b2e10a3
                    retryable: true
                    status: 503
                    title: Upstream unavailable
                    type: https://swisstouristy.com/developers/errors/upstream_unavailable
              schema:
                $ref: '#/components/schemas/ProblemOut'
          description: Upstream unavailable
      summary: List Vehicle Classes
      x-rate-limit-tier: discovery
servers:
- url: https://swisstouristy.com/api/public/v1
x-ratelimit-tiers:
  auth_failure:
    max_requests: 10
    window_seconds: 300
  checkout:
    max_requests: 5
    window_seconds: 60
  discovery:
    max_requests: 120
    window_seconds: 60
  quote_authoritative:
    max_requests: 10
    window_seconds: 60
  quote_estimate:
    max_requests: 20
    window_seconds: 60
  quote_read:
    max_requests: 60
    window_seconds: 60
  routing:
    max_requests: 60
    window_seconds: 60
