---
title: "Arm Flight Booking Session Fare Hold"
method: POST
path: "/flight-booking/sessions/{session_id}/fare-hold"
tags: ["flight-booking"]
---

# Arm Flight Booking Session Fare Hold

`POST /flight-booking/sessions/{session_id}/fare-hold`

Arm a 24h members-only hold on the session's entitled price.

One tap, no numbers: travel snapshots price, fare identity, party, seats
and bags from the session itself, so nothing the client displays can be
replayed into the hold. Travel's structured refusals (membership_required,
already_active carrying the hold, cap_reached, session_not_holdable)
reach the web verbatim.

## Path parameters

- `session_id` string, uuid, required

## Response `201`

Successful Response

- FareHoldBlock — The ``fare_hold`` node on every session response.
  - `hold` FareHoldSummary — One fare_holds row as clients see it. Money is integer cents.
    - `id` string, uuid, required
    - `status` 'active' | 'redeemed' | 'released' | 'expired', required
    - `armed_at` string, date-time, required
    - `expires_at` string, date-time, required
    - `basis_tier` 'free' | 'member' | 'acquisition', required
    - `currency` string, required
    - `held_flight_cents` integer, required
    - `held_items_total_cents` integer
    - `held_items` FareHoldHeldLine[], nullable
      - `kind` 'bag' | 'seat', required
      - `anchor` FareHoldHeldLineAnchor, required — Which flight (seat) or journey (bag) a held line rides. ``schemas.domain.ancillary_identity.SegmentAnchor.as_dict()``.
        - `carrier` string, nullable
        - `flight_number` string, nullable
        - `origin` string, nullable
        - `destination` string, nullable
        - `departure_date` string, nullable
      - `designator` string, nullable
      - `bag` FareHoldHeldBag
        - `checked` boolean, nullable
        - `cabin` boolean, nullable
        - `weight_norm` string, nullable
        - `display_name` string, nullable
      - `quantity` integer, required
      - `traveler_profile_id` string, nullable
      - `held_amount_cents` integer, required
      - `currency` string, required
    - `held_fares` FareHoldHeldFare[], nullable
      - `fare_family_id` string, nullable
      - `fare_label` string, nullable
      - `cabin` string, nullable
      - `held_flight_cents` integer, required
      - `currency` string, required
      - `source` 'session' | 'ladder', required
      - `selected` boolean
    - `itinerary_fingerprint` string, required
    - `fare_match` FareHoldFareMatch — Arm-time fare identity (``schemas.domain.fare_hold_identity.build_fare_match``).
      - `itinerary_fingerprint` string, nullable
      - `fare_family_id` string, nullable
      - `fare_label` string, nullable
      - `cabin` string, nullable
      - `observation_id` string, nullable
    - `pax_count` integer, required
    - `passenger_mix` PassengerCount — Passenger breakdown for offers/searches. Simple counts by type.
      - `adults` integer
      - `children` integer
      - `infants_in_seat` integer
      - `infants_on_lap` integer
    - `flight_summary` FareHoldFlightSummary — Display-only card facts snapshotted at arm time. Built by ``services.fare_hold_service.build_flight_summary``: nulls where the session payload was thin, never a guess. Forwards everything the payload has so the card can grow without a backend change.
      - `origin` string, nullable
      - `destination` string, nullable
      - `departure_date` string, nullable
      - `return_date` string, nullable
      - `carrier` string, nullable
      - `flight_numbers` string[]
      - `fare_label` string, nullable
      - `origin_city` string, nullable
      - `destination_city` string, nullable
      - `trip_type` 'one_way' | 'round_trip' | 'multi_city', nullable
      - `is_international` boolean, nullable
      - `carriers` string[]
      - `fare_family_id` string, nullable
      - `cabin` string, nullable
      - `requested_cabin` string, nullable
      - `fare_features` string[]
      - `baggage_notes` string[]
      - `book_with` string, nullable
      - `separate_tickets` boolean, nullable
      - `source` string, nullable
      - `observed_at` string, date-time, nullable
      - `seats_available` integer, nullable
      - `total_stops` integer, nullable
      - `total_duration_minutes` integer, nullable
      - `legs` FareHoldFlightLeg[]
        - `direction` 'outbound' | 'return' | 'leg', required
        - `origin` string, nullable
        - `destination` string, nullable
        - `origin_city` string, nullable
        - `destination_city` string, nullable
        - `departure_date` string, nullable
        - `departure_time` string, nullable
        - `arrival_date` string, nullable
        - `arrival_time` string, nullable
        - `stops` integer
        - `duration_minutes` integer, nullable
        - `carrier` string, nullable
        - `carriers` string[]
        - `cabin` string, nullable
        - `fare_family` string, nullable
        - `fare_family_id` string, nullable
        - `flight_numbers` string[]
        - `overnight` boolean, nullable
        - `layovers` FareHoldFlightLayover[]
          - `airport` string, nullable
          - `city` string, nullable
          - `duration_minutes` integer, nullable
        - `segments` FareHoldFlightSegment[]
          - `origin` string, nullable
          - `destination` string, nullable
          - `origin_city` string, nullable
          - `destination_city` string, nullable
          - `origin_terminal` string, nullable
          - `destination_terminal` string, nullable
          - `departure_date` string, nullable
          - `departure_time` string, nullable
          - `arrival_date` string, nullable
          - `arrival_time` string, nullable
          - `duration_minutes` integer, nullable
          - `carrier` string, nullable
          - `marketing_carrier` string, nullable
          - `operating_carrier` string, nullable
          - `flight_number` string, nullable
          - `raw_flight_number` string, nullable
          - `marketing_flight_number` string, nullable
          - `cabin` string, nullable
          - `raw_supplier_cabin` string, nullable
          - `cabin_confidence` string, nullable
          - `booking_class` string, nullable
          - `fare_family` string, nullable
          - `fare_family_id` string, nullable
          - `aircraft` string, nullable
          - `overnight` boolean, nullable
          - `often_delayed` boolean, nullable
    - `conv_trip_id` string, uuid, nullable
    - `source_session_id` string, uuid, required
    - `observation_id` string, uuid, nullable
    - `card_observation_id` string, uuid, nullable
    - `last_live_cents` integer, nullable
    - `last_quoted_at` string, date-time, nullable
    - `last_quote_reason` 'ok' | 'fare_gone' | 'unknown', nullable
    - `dismissed_at` string, date-time, nullable
    - `redeemed_booking_id` string, uuid, nullable
    - `ended_at` string, date-time, nullable
  - `pricing` FareHoldPricing — What the shared resolver decided for this checkout under the hold. ``reason`` is the resolver's word; ``applies`` is True only for ``ok``. ``held_fare`` is the rung of ``FareHoldSummary.held_fares`` the resolver matched this checkout to (None when the hold does not apply or on a legacy single-fare hold); ``held_fares_count`` is how many rungs the hold carries, so a surface can say "and 2 other fares" without the list.
    - `applies` boolean, required
    - `reason` 'ok' | 'not_active' | 'expired' | 'itinerary_mismatch' | 'fare_mismatch' | 'party_mismatch' | 'pax_mismatch' | 'currency_mismatch' | 'invalid_held_total' | 'invalid_live_total' | 'cabin_unknown' | 'cabin_mismatch', required
    - `price_dropped` boolean, required
    - `flight` FareHoldFlightPricing, required
      - `held_cents` integer, required
      - `live_cents` integer, required
      - `charge_cents` integer, required
    - `items` FareHoldPricedItem[]
      - `disposition` 'honored' | 'customer_min' | 'dropped_unavailable', required
      - `kind` 'bag' | 'seat', nullable
      - `traveler_profile_id` string, nullable
      - `seat` string, nullable
      - `quantity` integer, nullable
      - `held_cents` integer, required
      - `live_cents` integer, nullable
      - `charge_cents` integer, nullable
      - `absorbed_cents` integer, required
      - `current_product_id` string, nullable
      - `current_passenger_id` string, nullable
      - `anchor` FareHoldHeldLineAnchor — Which flight (seat) or journey (bag) a held line rides. ``schemas.domain.ancillary_identity.SegmentAnchor.as_dict()``.
        - `carrier` string, nullable
        - `flight_number` string, nullable
        - `origin` string, nullable
        - `destination` string, nullable
        - `departure_date` string, nullable
      - `designator` string, nullable
      - `matched_on` 'anchor' | 'legacy_key', nullable
    - `charge_total_cents` integer, required
    - `live_total_cents` integer, required
    - `absorbed_cents` integer, required
    - `expires_at` string, date-time, nullable
    - `held_fare` FareHoldHeldFare — One rung of a whole-flight hold, at its own arm-time party total.
      - `fare_family_id` string, nullable
      - `fare_label` string, nullable
      - `cabin` string, nullable
      - `held_flight_cents` integer, required
      - `currency` string, required
      - `source` 'session' | 'ladder', required
      - `selected` boolean
    - `held_fares_count` integer
  - `offer` FareHoldOffer, required — Server-driven decision on what the hold slot shows. ``available`` renders the tappable line; ``membership_required`` renders the locked member-benefit row; every other reason renders nothing (the client never re-derives these from flags or membership state).
    - `available` boolean, required
    - `reason` 'membership_required' | 'membership_unavailable' | 'paused' | 'already_held' | 'cap_reached' | 'session_not_holdable' | 'departs_too_soon', nullable
    - `min_departure_lead_hours` integer, nullable
    - `hold_hours` integer, nullable
  - `restore` FareHoldRestoreOutcome[]
    - `kind` 'bag' | 'seat', required
    - `designator` string, nullable
    - `anchor` FareHoldHeldLineAnchor, required — Which flight (seat) or journey (bag) a held line rides. ``schemas.domain.ancillary_identity.SegmentAnchor.as_dict()``.
      - `carrier` string, nullable
      - `flight_number` string, nullable
      - `origin` string, nullable
      - `destination` string, nullable
      - `departure_date` string, nullable
    - `disposition` 'restored_at_held' | 'restored_live_cheaper' | 'already_in_basket' | 'kept_customer_choice' | 'gone' | 'unknown' | 'ambiguous', required
    - `held_cents` integer, required
    - `live_cents` integer, nullable
    - `message` string, required
    - `detail` string, nullable

## Other responses

- `403` — Arming is paused, or price holds are a member benefit.
- `404` — No such hold or checkout session for this user.
- `409` — The hold or session is not in a state that allows this.
- `422` — Validation Error
- `503` — Membership could not be verified, or the held checkout could not be reopened.

## Changes

> 17 revisions in range; 1 not diffed.

- **2026-09-10** `09ac75a22f0e` — 5 info
  - added the optional property `detail/hold/anyOf[subschema #1: FareHoldSummary]/card_observation_id` to the response with the `403` status
  - added the optional property `detail/hold/anyOf[subschema #1: FareHoldSummary]/card_observation_id` to the response with the `404` status
  - added the optional property `detail/hold/anyOf[subschema #1: FareHoldSummary]/card_observation_id` to the response with the `409` status
  - added the optional property `detail/hold/anyOf[subschema #1: FareHoldSummary]/card_observation_id` to the response with the `503` status
  - …1 more
- **2026-09-06** `fa0678aea849` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/helloaxel/apis/client-api-gateway/changes/flight-booking/sessions/:session_id/fare-hold/post.md)

---

[API](https://skmtc.dev/helloaxel/apis/client-api-gateway.md) · [All operations](https://skmtc.dev/helloaxel/apis/client-api-gateway/llms.txt) · [OpenAPI document](https://skmtc.dev/helloaxel/apis/client-api-gateway/revisions/b7b1f6448378?raw)
