---
title: "Update Stay Room"
method: POST
path: "/trips/{trip_id}/itinerary/stays/{stay_id}/rooms/update"
tags: ["itinerary"]
---

# Update Stay Room

`POST /trips/{trip_id}/itinerary/stays/{stay_id}/rooms/update`

## Request

- Base URL: `https://stardrift.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://stardrift.ai/trips/{trip_id}/itinerary/stays/{stay_id}/rooms/update`
- Auth: none declared

Re-price a chosen room, or change the choice inside it.

`booking_id` is deliberately NOT settable here — it is written by the
booking service when money moves, and a client that could stamp it could
mark a room paid for without paying.

## Path parameters

- `trip_id` string, required
- `stay_id` string, required

## Headers

- `x-client-id` string, nullable

## Request body

- UpdateStayRoomRequest: Re-price a chosen room, or change the choice inside it. Only the fields set are changed; `None` means "leave alone", so nothing can be cleared through here. `latest_seen_rate` is what this exists for.
  - `room_id` string, required
  - `occupancies` RoomOccupancy[], nullable
    - `adults` integer, required
    - `children` integer[]
  - `board_type` string, nullable
  - `prefer_refundable` boolean, nullable
  - `latest_seen_rate` SeenRate: A price we OBSERVED for a room, and when. Never a held price. LiteAPI publishes no TTL on an offer — expiry surfaces only as error 4040 at prebook — so the honest shape is an observation with a timestamp rather than a quote that pretends to still be live. `offer_id` lives HERE rather than on `StayRoom` deliberately: an offer id is part of *a price seen at a time*, not part of *which room this is*. Pairing them means a stale rate is self-describing, and a surface can date the number instead of presenting it as current. Also the seed for price-change notification on a saved room: two `SeenRate`s for one `StayRoom` are a price movement.
    - `offer_id` string, required
    - `all_in_total` number, required
    - `price_per_night` number, nullable
    - `currency` string
    - `board_type` string, nullable
    - `board_name` string, nullable
    - `refundable` boolean
    - `cancel_until` string, nullable
    - `seen_at` string, date-time, required

## Response `200`

Successful Response

- StayRoomResponse
  - `itinerary` object, required
  - `rooms` StayRoom[], required
    - `id` string, required
    - `source` 'liteapi'
    - `hotel_id` string, required
    - `mapped_room_id` integer, nullable
    - `canonical_room_id` string, nullable
    - `room_name` string, required
    - `occupancies` RoomOccupancy[]
      - `adults` integer, required
      - `children` integer[]
    - `board_type` string, nullable
    - `prefer_refundable` boolean, nullable
    - `chosen_rate` SeenRate: A price we OBSERVED for a room, and when. Never a held price. LiteAPI publishes no TTL on an offer — expiry surfaces only as error 4040 at prebook — so the honest shape is an observation with a timestamp rather than a quote that pretends to still be live. `offer_id` lives HERE rather than on `StayRoom` deliberately: an offer id is part of *a price seen at a time*, not part of *which room this is*. Pairing them means a stale rate is self-describing, and a surface can date the number instead of presenting it as current. Also the seed for price-change notification on a saved room: two `SeenRate`s for one `StayRoom` are a price movement.
      - `offer_id` string, required
      - `all_in_total` number, required
      - `price_per_night` number, nullable
      - `currency` string
      - `board_type` string, nullable
      - `board_name` string, nullable
      - `refundable` boolean
      - `cancel_until` string, nullable
      - `seen_at` string, date-time, required
    - `latest_seen_rate` SeenRate: A price we OBSERVED for a room, and when. Never a held price. LiteAPI publishes no TTL on an offer — expiry surfaces only as error 4040 at prebook — so the honest shape is an observation with a timestamp rather than a quote that pretends to still be live. `offer_id` lives HERE rather than on `StayRoom` deliberately: an offer id is part of *a price seen at a time*, not part of *which room this is*. Pairing them means a stale rate is self-describing, and a surface can date the number instead of presenting it as current. Also the seed for price-change notification on a saved room: two `SeenRate`s for one `StayRoom` are a price movement.
      - `offer_id` string, required
      - `all_in_total` number, required
      - `price_per_night` number, nullable
      - `currency` string
      - `board_type` string, nullable
      - `board_name` string, nullable
      - `refundable` boolean
      - `cancel_until` string, nullable
      - `seen_at` string, date-time, required
    - `booking_id` string, uuid, nullable

## Other responses

- `422`: Validation Error

---

[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/be9ed1e6c38a?raw)
