---
title: "Update Booking"
method: PATCH
path: "/bookings/{booking_id}"
tags: ["bookings"]
---

# Update Booking

`PATCH /bookings/{booking_id}`

Apply corrections using the model selected by the stored booking kind.

## Path parameters

- `booking_id` string, uuid, required

## Request body

- object

## Response `200`

Successful Response

- union
  - FlightBookingItem
    - `id` string, required
    - `event_date` string, nullable, required
    - `created_at` string, required
    - `confirmation_number` string, nullable, required
    - `status` 'active' | 'cancelled'
    - `gmail_link` string, nullable
    - `import_kind` 'email' | 'image' | 'text', nullable
    - `import_link` string, nullable
    - `import_sources` ImportSource[]
      - `kind` 'email' | 'image' | 'text', required
      - `link` string, nullable
      - `created_at` string, date-time, required
    - `source` 'email_import' | 'first_party'
    - `trip_id` string, nullable
    - `trip_title` string, nullable
    - `review` BookingReview
      - `question` 'which_trip' | 'is_this_yours', required
      - `travelers` string[]
      - `nudge` boolean
    - `booking_type` 'flight'
    - `card_data` FlightCardData, required — Flight card data for frontend - wraps Journey with card metadata. This is the serialization format sent to the frontend FlightCard component. It converts from the internal Journey model to the frontend contract.
      - `type` 'one-way' | 'round-trip' | 'multi-city', required
      - `journeys` ApiModelsFlightCardJourneyDisplay[], required
        - `direction` 'outbound' | 'return', nullable
        - `segments` SegmentDisplay[], required
          - `kind` 'flight'
          - `type` 'outbound' | 'return', nullable
          - `departure` ApiModelsFlightCardDepartureArrivalDisplay, required — Frontend format for departure/arrival points. `timezone` (IANA) and the coordinates come from the airport catalog when the journey endpoint itself has none, so a consumer can compute the offset crossed and the direction flown without its own airport table.
            - `time` string, date-time, required
            - `airport` string, required
            - `timezone` string, nullable
            - `latitude` number, nullable
            - `longitude` number, nullable
          - `arrival` ApiModelsFlightCardDepartureArrivalDisplay, required — Frontend format for departure/arrival points. `timezone` (IANA) and the coordinates come from the airport catalog when the journey endpoint itself has none, so a consumer can compute the offset crossed and the direction flown without its own airport table.
            - `time` string, date-time, required
            - `airport` string, required
            - `timezone` string, nullable
            - `latitude` number, nullable
            - `longitude` number, nullable
          - `length_in_minutes` integer, required
          - `flight_number` string, required
          - `airline` string, required
          - `airline_logo` string, nullable
          - `aircraft` string, nullable
          - `travel_class` string, nullable
          - `starlink_verdict` 'yes' | 'probably_yes' | 'probably_no' | 'no', nullable
          - `starlink_reasoning` string, nullable
        - `total_duration_in_minutes` integer, required
        - `departure_date` string, date-time, nullable
        - `arrival_date` string, date-time, nullable
      - `cash_details` ApiModelsFlightCardCashDisplay — Frontend format for cash pricing.
        - `type` 'cash'
        - `price` number, nullable
        - `currency` string
      - `cabin_class` string, nullable
      - `booking_links` BookingLink[], nullable
        - `link` string, required
        - `label` string, required
        - `price` number, nullable
        - `currency` string, nullable
        - `primary` boolean
        - `fare_name` string, nullable
        - `free_carry_on` integer, nullable
        - `free_checked_bags` integer, nullable
      - `adults` integer
      - `children` integer
      - `booking_token` string, nullable
      - `departure_token` string, nullable
      - `return_date` string, nullable
      - `__index` integer, required
      - `__tool_call_id` string, required
      - `message_id` string, nullable
      - `booking_links_status` string, nullable
      - `confirmation_number` string, nullable
      - `is_booked` boolean
      - `is_user_import` boolean
      - `user_edited` boolean
      - `award_details` object, nullable
    - `edit_data` ExtractedFlightOutput, required — Complete flight booking extracted from user message. For one-way: all segments in outbound_segments, return_segments empty For round-trip: outbound_segments has flights TO destination, return_segments has flights BACK from destination
      - `type` 'one-way' | 'round-trip'
      - `outbound_segments` ExtractedFlightSegment[], required — Segments going TO the destination
        - `departure_airport` string, required — 3-letter IATA code (e.g., 'SFO')
        - `arrival_airport` string, required — 3-letter IATA code (e.g., 'JFK')
        - `departure_datetime` string, date-time, required — Departure date and time (local time, no timezone)
        - `arrival_datetime` string, date-time, nullable — Arrival date and time (local time, no timezone)
        - `duration_minutes` integer, nullable — Flight duration in minutes if mentioned (e.g., '16h 35m' = 995)
        - `flight_number` string, nullable — Flight number (e.g., 'UA123')
        - `airline` string, nullable — Airline name
        - `cabin_class` string, nullable — Cabin class (e.g., 'Economy', 'Premium Economy', 'Business', 'First')
        - `seat` string, nullable — Seat assignment if shown (e.g., '14A', '2K')
        - `aircraft_type_iata` string, nullable — IATA aircraft type code (e.g., '77W', '320')
        - `aircraft_type_icao` string, nullable — ICAO aircraft type code (e.g., 'B77W', 'A320')
        - `tail_number` string, nullable — Aircraft registration number (e.g., 'N12345')
        - `departure_terminal` string, nullable — Departure terminal (e.g., 'T1', 'B')
        - `arrival_terminal` string, nullable — Arrival terminal
        - `departure_country` string, nullable — Departure country ISO code (e.g., 'US')
        - `arrival_country` string, nullable — Arrival country ISO code (e.g., 'GB')
        - `distance_km` number, nullable — Great-circle distance in kilometers
        - `number_of_stops` integer, nullable — Number of intermediate stops (0 for non-stop)
        - `flight_state` string, nullable — Flight state from OAG (e.g., 'Scheduled', 'InGate', 'Cancelled')
        - `pre_oag_departure_datetime` string, date-time, nullable — The ticket's own departure time, recorded the first time OAG touches this segment and never overwritten — the recovery value if an enrichment adjusts wrongly.
        - `pre_oag_arrival_datetime` string, date-time, nullable — The ticket's own arrival time; see pre_oag_departure_datetime.
        - `departure_datetime_utc` string, date-time, nullable — Authoritative departure instant from OAG, timezone-aware UTC. The naive departure_datetime stays local wall-clock at the airport.
        - `arrival_datetime_utc` string, date-time, nullable — Authoritative arrival instant from OAG, timezone-aware UTC. The naive arrival_datetime stays local wall-clock at the airport.
      - `return_segments` ExtractedFlightSegment[] — Segments coming BACK from destination (empty for one-way)
        - `departure_airport` string, required — 3-letter IATA code (e.g., 'SFO')
        - `arrival_airport` string, required — 3-letter IATA code (e.g., 'JFK')
        - `departure_datetime` string, date-time, required — Departure date and time (local time, no timezone)
        - `arrival_datetime` string, date-time, nullable — Arrival date and time (local time, no timezone)
        - `duration_minutes` integer, nullable — Flight duration in minutes if mentioned (e.g., '16h 35m' = 995)
        - `flight_number` string, nullable — Flight number (e.g., 'UA123')
        - `airline` string, nullable — Airline name
        - `cabin_class` string, nullable — Cabin class (e.g., 'Economy', 'Premium Economy', 'Business', 'First')
        - `seat` string, nullable — Seat assignment if shown (e.g., '14A', '2K')
        - `aircraft_type_iata` string, nullable — IATA aircraft type code (e.g., '77W', '320')
        - `aircraft_type_icao` string, nullable — ICAO aircraft type code (e.g., 'B77W', 'A320')
        - `tail_number` string, nullable — Aircraft registration number (e.g., 'N12345')
        - `departure_terminal` string, nullable — Departure terminal (e.g., 'T1', 'B')
        - `arrival_terminal` string, nullable — Arrival terminal
        - `departure_country` string, nullable — Departure country ISO code (e.g., 'US')
        - `arrival_country` string, nullable — Arrival country ISO code (e.g., 'GB')
        - `distance_km` number, nullable — Great-circle distance in kilometers
        - `number_of_stops` integer, nullable — Number of intermediate stops (0 for non-stop)
        - `flight_state` string, nullable — Flight state from OAG (e.g., 'Scheduled', 'InGate', 'Cancelled')
        - `pre_oag_departure_datetime` string, date-time, nullable — The ticket's own departure time, recorded the first time OAG touches this segment and never overwritten — the recovery value if an enrichment adjusts wrongly.
        - `pre_oag_arrival_datetime` string, date-time, nullable — The ticket's own arrival time; see pre_oag_departure_datetime.
        - `departure_datetime_utc` string, date-time, nullable — Authoritative departure instant from OAG, timezone-aware UTC. The naive departure_datetime stays local wall-clock at the airport.
        - `arrival_datetime_utc` string, date-time, nullable — Authoritative arrival instant from OAG, timezone-aware UTC. The naive arrival_datetime stays local wall-clock at the airport.
      - `price` number, nullable — Total cash price if mentioned (null if fully award-booked)
      - `currency` string — ISO 4217 currency code (e.g., USD, EUR, JPY)
      - `award` AwardPayment — Payment made with loyalty miles/points.
        - `amount` integer, nullable — Number of miles/points used (e.g., 800, 25000)
        - `unit` 'miles' | 'points', required — 'miles' or 'points'
        - `account` string, nullable — Loyalty account identifier if shown (e.g., 'MileagePlus XXXXX205', 'Bonvoy XXXX1234')
      - `confirmation_number` string, nullable
      - `booking_reference` string, nullable — Airline PNR / record locator (6-char alphanumeric, e.g., 'ABCDEF'). Different from confirmation_number which may be an OTA/agent booking code.
      - `eticket_number` string, nullable — E-ticket number (typically 13 digits, e.g., '0012345678901')
      - `fare_class` string, nullable — Fare/booking class letter (e.g., 'Y', 'B', 'J', 'W')
      - `checked_bags` integer, nullable — Number of checked bags included or purchased
      - `carry_on_bags` integer, nullable — Number of carry-on bags included
      - `check_in_url` string, nullable — Online check-in URL if present in the email
      - `oag_enriched_at` string, nullable — ISO timestamp when OAG enrichment was applied
      - `passenger_count` integer, nullable — Number of adult passengers on this booking (e.g., 2 passengers)
      - `passenger_names` string[] — Names of passengers if listed (e.g., ['John Smith', 'Jane Smith'])
      - `children` integer, nullable — Number of child passengers (aged 2-11)
      - `infants` integer, nullable — Number of infant passengers (under 2)
  - HotelBookingItem
    - `id` string, required
    - `event_date` string, nullable, required
    - `created_at` string, required
    - `confirmation_number` string, nullable, required
    - `status` 'active' | 'cancelled'
    - `gmail_link` string, nullable
    - `import_kind` 'email' | 'image' | 'text', nullable
    - `import_link` string, nullable
    - `import_sources` ImportSource[]
      - `kind` 'email' | 'image' | 'text', required
      - `link` string, nullable
      - `created_at` string, date-time, required
    - `source` 'email_import' | 'first_party'
    - `trip_id` string, nullable
    - `trip_title` string, nullable
    - `review` BookingReview
      - `question` 'which_trip' | 'is_this_yours', required
      - `travelers` string[]
      - `nudge` boolean
    - `booking_type` 'hotel'
    - `card_data` HotelCardData, required — Hotel card data for frontend - extends HotelOptionOutput with card metadata. This is the serialization format sent to the frontend HotelCard component. It converts from HotelOptionOutput (cached tool result) plus enrichment data.
      - `name` string, required
      - `price` number, nullable
      - `price_display` string, nullable
      - `price_before_taxes` number, nullable
      - `total_price` number, nullable
      - `total_price_display` string, nullable
      - `rating` number, nullable
      - `reviews` integer, nullable
      - `hotel_class` integer, nullable
      - `link` string, nullable
      - `description` string, nullable
      - `check_in_time` string, nullable
      - `check_out_time` string, nullable
      - `amenities` string[]
      - `essential_info` string[]
      - `latitude` number, nullable
      - `longitude` number, nullable
      - `location_rating` number, nullable
      - `nearby_places` object[]
      - `currency` string
      - `property_token` string, nullable
      - `thumbnail` string, nullable
      - `thumbnail_thumbhash` string, nullable
      - `price_tier` string, nullable
      - `source` string, nullable
      - `feed` 'b2c' | 'cug', nullable
      - `hotel_id` string, nullable
      - `rooms` RoomOption[]
        - `offer_id` string, required
        - `room_name` string, required
        - `mapped_room_id` integer, nullable
        - `bed_summary` string, nullable
        - `size_sqft` integer, nullable
        - `max_occupancy` integer, nullable
        - `board_type` string, nullable
        - `board_name` string, nullable
        - `refundable` boolean
        - `cancel_until` string, nullable
        - `price_per_night` number, nullable
        - `total_price` number, nullable
        - `initial_price` number, nullable
        - `taxes_included` boolean, nullable
        - `currency` string
        - `photos` string[]
        - `amenities` string[]
        - `why` string, nullable
      - `__index` integer, required
      - `__tool_call_id` string, required
      - `message_id` string, nullable
      - `check_in_date` string, required
      - `check_out_date` string, required
      - `adults` integer, nullable
      - `children` integer, nullable
      - `children_ages` string, nullable
      - `booking_links` BookingLink[]
        - `link` string, required
        - `label` string, required
        - `price` number, nullable
        - `currency` string, nullable
        - `primary` boolean
        - `fare_name` string, nullable
        - `free_carry_on` integer, nullable
        - `free_checked_bags` integer, nullable
      - `booking_links_status` string
      - `additional_images` string[]
      - `additional_images_thumbhashes` string[]
      - `reviews_breakdown` unknown[]
        - unknown
      - `sample_reviews` unknown[]
        - unknown
      - `address` string, nullable
      - `confirmation_number` string, nullable
      - `is_booked` boolean
      - `taxes_and_fees` number, nullable
      - `is_user_import` boolean
      - `source_reference` SourceReference — Reference to a cached tool result for tracking itinerary item sources. ``source`` distinguishes provenance: ``api`` (an AI/tool search result), ``user_import`` (parsed from the user's email — renders a "From email" badge and the imageless cost-breakdown card), ``user_manual`` (added by hand via the "Add stay" form — a normal image-carrying card, no badge), and ``user_booking`` (WE sold it — a first-party reservation taken through our own checkout; see api/services/hotel_booking_stay.py). ``user_booking`` is deliberately NOT ``user_import``: the item did not come from the user's inbox, and a "From email" badge on a booking we took money for would be a lie. Frontends branch only on ``user_import``, so the new value falls through to the ordinary card.
        - `tool_call_id` string, required
        - `result_index` integer, required
        - `source` 'api' | 'user_import' | 'user_manual' | 'user_booking'
      - `place_id` string, nullable
  - RailBookingItem
    - `id` string, required
    - `event_date` string, nullable, required
    - `created_at` string, required
    - `confirmation_number` string, nullable, required
    - `status` 'active' | 'cancelled'
    - `gmail_link` string, nullable
    - `import_kind` 'email' | 'image' | 'text', nullable
    - `import_link` string, nullable
    - `import_sources` ImportSource[]
      - `kind` 'email' | 'image' | 'text', required
      - `link` string, nullable
      - `created_at` string, date-time, required
    - `source` 'email_import' | 'first_party'
    - `trip_id` string, nullable
    - `trip_title` string, nullable
    - `review` BookingReview
      - `question` 'which_trip' | 'is_this_yours', required
      - `travelers` string[]
      - `nudge` boolean
    - `booking_type` 'rail'
    - `card_data` ImportedRailCardData, required — Flat RailOption-shaped card payload for an imported rail journey. The frontend RailCard component renders the RailOption shape (travel_legs, departure_datetime, …), NOT the nested RailCardData — sending RailCardData hits the component's empty-travel_legs guard and renders nothing. This model is the single typed source of that flat shape; both the chat hydration dict and GET /bookings use it.
      - `departure_datetime` string, date-time, required
      - `arrival_datetime` string, date-time, required
      - `duration_seconds` integer, required
      - `duration_display` string, required
      - `departure_id` string, required
      - `arrival_id` string, required
      - `train_names` string[]
      - `num_transfers` integer
      - `coach_price` number, nullable
      - `currency` string
      - `travel_legs` ImportedRailLeg[]
        - `train_id` string, required
        - `route` string
        - `departure_id` string, required
        - `arrival_id` string, required
        - `departure_time` string, required
        - `arrival_time` string, required
        - `duration` string, required
        - `operator_logo` string, nullable
      - `booking_date` string, required
      - `booking_links` BookingLink[]
        - `link` string, required
        - `label` string, required
        - `price` number, nullable
        - `currency` string, nullable
        - `primary` boolean
        - `fare_name` string, nullable
        - `free_carry_on` integer, nullable
        - `free_checked_bags` integer, nullable
      - `confirmation_number` string, nullable
      - `is_booked` boolean
      - `is_user_import` boolean
      - `ground_mode` string
  - RoadBookingItem
    - `id` string, required
    - `event_date` string, nullable, required
    - `created_at` string, required
    - `confirmation_number` string, nullable, required
    - `status` 'active' | 'cancelled'
    - `gmail_link` string, nullable
    - `import_kind` 'email' | 'image' | 'text', nullable
    - `import_link` string, nullable
    - `import_sources` ImportSource[]
      - `kind` 'email' | 'image' | 'text', required
      - `link` string, nullable
      - `created_at` string, date-time, required
    - `source` 'email_import' | 'first_party'
    - `trip_id` string, nullable
    - `trip_title` string, nullable
    - `review` BookingReview
      - `question` 'which_trip' | 'is_this_yours', required
      - `travelers` string[]
      - `nudge` boolean
    - `booking_type` 'road'
    - `card_data` RoadCardData, required — Road transport card data for the frontend RoadCard component. Flat single-ride shape: road journeys are always one leg with one RoadSegment (a round trip is two separate journeys).
      - `operator` string, nullable
      - `pickup_city` string, nullable
      - `pickup_address` string, nullable
      - `pickup_datetime` string, date-time, required
      - `dropoff_city` string, nullable
      - `dropoff_address` string, nullable
      - `dropoff_datetime` string, date-time, nullable
      - `duration_minutes` integer
      - `total_price` number, nullable
      - `currency` string
      - `passenger_names` string[]
      - `__index` integer, required
      - `__tool_call_id` string, required
      - `message_id` string, nullable
      - `confirmation_number` string, nullable
      - `is_booked` boolean
      - `is_user_import` boolean
  - CarRentalBookingItem
    - `id` string, required
    - `event_date` string, nullable, required
    - `created_at` string, required
    - `confirmation_number` string, nullable, required
    - `status` 'active' | 'cancelled'
    - `gmail_link` string, nullable
    - `import_kind` 'email' | 'image' | 'text', nullable
    - `import_link` string, nullable
    - `import_sources` ImportSource[]
      - `kind` 'email' | 'image' | 'text', required
      - `link` string, nullable
      - `created_at` string, date-time, required
    - `source` 'email_import' | 'first_party'
    - `trip_id` string, nullable
    - `trip_title` string, nullable
    - `review` BookingReview
      - `question` 'which_trip' | 'is_this_yours', required
      - `travelers` string[]
      - `nudge` boolean
    - `booking_type` 'car_rental'
    - `card_data` CarRentalCardData, required — Car rental card data for the frontend CarRentalCard component.
      - `vendor` string, required
      - `pickup_location` string, nullable
      - `pickup_city` string, nullable
      - `pickup_datetime` string, date-time, required
      - `dropoff_location` string, nullable
      - `dropoff_city` string, nullable
      - `dropoff_datetime` string, date-time, nullable
      - `vehicle_class` string, nullable
      - `driver_name` string, nullable
      - `total_price` number, nullable
      - `currency` string
      - `__index` integer, required
      - `__tool_call_id` string, required
      - `message_id` string, nullable
      - `confirmation_number` string, nullable
      - `is_booked` boolean
      - `is_user_import` boolean
  - EventBookingItem
    - `id` string, required
    - `event_date` string, nullable, required
    - `created_at` string, required
    - `confirmation_number` string, nullable, required
    - `status` 'active' | 'cancelled'
    - `gmail_link` string, nullable
    - `import_kind` 'email' | 'image' | 'text', nullable
    - `import_link` string, nullable
    - `import_sources` ImportSource[]
      - `kind` 'email' | 'image' | 'text', required
      - `link` string, nullable
      - `created_at` string, date-time, required
    - `source` 'email_import' | 'first_party'
    - `trip_id` string, nullable
    - `trip_title` string, nullable
    - `review` BookingReview
      - `question` 'which_trip' | 'is_this_yours', required
      - `travelers` string[]
      - `nudge` boolean
    - `booking_type` 'event'
    - `card_data` AttractionDisplayData, required — Pre-formatted attraction data for AttractionCard component.
      - `from_email` boolean
      - `gmail_link` string, nullable
      - `import_kind` 'email' | 'image' | 'text', nullable
      - `import_link` string, nullable
      - `import_sources` ImportSource[]
        - `kind` 'email' | 'image' | 'text', required
        - `link` string, nullable
        - `created_at` string, date-time, required
      - `id` string, required
      - `name` string, required
      - `place_id` string, nullable
      - `latitude` number, nullable
      - `longitude` number, nullable
      - `thumbnail` string, nullable
      - `thumbnail_thumbhash` string, nullable
      - `rating` number, nullable
      - `num_reviews` integer, nullable
      - `category` string, nullable
      - `address` string, nullable
      - `city` string, nullable
      - `state` string, nullable
      - `country` string, nullable
      - `source_reference` SourceReference — Reference to a cached tool result for tracking itinerary item sources. ``source`` distinguishes provenance: ``api`` (an AI/tool search result), ``user_import`` (parsed from the user's email — renders a "From email" badge and the imageless cost-breakdown card), ``user_manual`` (added by hand via the "Add stay" form — a normal image-carrying card, no badge), and ``user_booking`` (WE sold it — a first-party reservation taken through our own checkout; see api/services/hotel_booking_stay.py). ``user_booking`` is deliberately NOT ``user_import``: the item did not come from the user's inbox, and a "From email" badge on a booking we took money for would be a lie. Frontends branch only on ``user_import``, so the new value falls through to the ordinary card.
        - `tool_call_id` string, required
        - `result_index` integer, required
        - `source` 'api' | 'user_import' | 'user_manual' | 'user_booking'
      - `activity_details` object, nullable
      - `activity_type` string, nullable
      - `start_datetime` string, nullable
      - `end_datetime` string, nullable
      - `venue_name` string, nullable
      - `seat_info` string, nullable
      - `quantity` integer, nullable
      - `booking_source` string, nullable
      - `confirmation_number` string, nullable
      - `total_price` number, nullable
      - `currency` string, nullable
      - `is_booked` boolean

## Other responses

- `422` — Validation Error

## Changes

- **2026-09-05** `6c037a31dc55` — 8 breaking, 28 warning, 2 info
  - added `#/components/schemas/FlightBookingItem, #/components/schemas/HotelBookingItem, #/components/schemas/RailBookingItem, #/components/schemas/RoadBookingItem, #/components/schemas/CarRentalBookingItem, #/components/schemas/EventBookingItem` to the response body `oneOf` list for the response status `200`
  - the response's body type changed from `object` to no type for status `200`
  - removed the required property `card_data` from the response with the `200` status
  - removed the required property `confirmation_number` from the response with the `200` status
  - …34 more

[Change history](https://skmtc.dev/stardrift/apis/fastapi/changes/bookings/:booking_id/patch.md)

---

[API](https://skmtc.dev/stardrift/apis/fastapi.md) · [All operations](https://skmtc.dev/stardrift/apis/fastapi/llms.txt) · [OpenAPI document](https://skmtc.dev/stardrift/apis/fastapi/revisions/5ee46d34daa4?raw)
