Hotel guides

Handling price changes

Between search and checkout a rate can go up, down, change its cancellation terms or sell out. The price-check tells you which, and a booking won't go through until you've shown the traveller what changed.

What a price-check returns

A price-check compares the live rate with what the search showed and reports two flags:

FieldTrue when
priceChangedThe total price differs from the search price. changes.price holds the old and new amounts — on commissionable rates, the published price.
policyChangedThe cancellation terms differ. changes.cancellation holds the old and new policies. from can be null when the search had no terms to compare, and supplierFlaggedOnly: true means the inventory source reported a change even though the terms read the same — say so rather than showing two identical columns.
Response · 200 — price and policy changed (abridged)
{
  "data": {
    "quoteId": "66f1c0b8e4b0c1d2e3f4a7a2",
    "priceChanged": true,
    "policyChanged": true,
    "changes": {
      "price": {
        "from": { "amountMinor": 48230, "currency": "USD" },
        "to":   { "amountMinor": 49110, "currency": "USD" }
      },
      "cancellation": {
        "from": { "refundable": true, "freeCancelBefore": "2026-11-08T12:00:00Z", "deadlines": [] },
        "to":   { "refundable": false, "deadlines": [] }
      }
    },
    "breakdown": { "sell": { "amountMinor": 49110, "currency": "USD" } },
    "quote": { "_id": "66f1c0b8e4b0c1d2e3f4a7a2", "status": "price_checked" }
  },
  "meta": {},
  "error": null
}

A change is still a 200: the rate is available, on new terms. The new terms are the ones you'll book.

Show the change, then acknowledge it

When either flag is true, show the traveller the old and new price and the new cancellation terms, and ask them to accept. Only then book with changesAcknowledged: true:

POST /bookings body
{
  "quoteId": "66f1c0b8e4b0c1d2e3f4a7a2",
  "paymentMethod": "credit",
  "changesAcknowledged": true,
  "travelers": [
    { "firstName": "Anna", "lastName": "Smith", "email": "anna.smith@example.com", "phone": "+447700900123", "roomIndex": 0 },
    { "firstName": "Ben", "lastName": "Smith", "roomIndex": 0 }
  ]
}

Book a changed quote without the acknowledgement and you get 400 changes_ack_required. Don't set it automatically: it records that the traveller saw the change, and a silent price rise is the complaint you're avoiding.

What to show before the traveller confirms

Whether or not anything changed, your checkout page should show these from the price-check response:

  • The total — the amount you'll be charged: breakdown.sell on net rates, agencyCommission.grossMinor on commissionable rates. breakdown.serviceFee is informational and isn't added.
  • Cancellation terms — quote.cancellationPolicy: whether it is refundable, the free-cancellation deadline, and each penalty after it. Show the terms as returned; don't round or reword the deadlines.
  • Taxes paid at the hotel — quote.details.excludedTaxes. These are not in the price and are collected by the property, often per night or per person. Label them clearly so the traveller isn't surprised at check-in.
  • Rate comments — quote.details.rateComments. The hotel's own notes: check-in rules, deposits, what the rate includes. Travellers must see these before they confirm.

Package rates

Rows with summary.isPackage: true are package rates: they may only be sold together with another travel service such as a flight, never as a room on its own. If you are selling one inside a package, book with packageRateAcknowledged: true; otherwise, don't offer it. Without the flag the booking returns 400 package_ack_required.

When a rate sells out

If the room is gone, the price-check returns 409 rate_unavailable:

Response · 409
{
  "data": null,
  "meta": {},
  "error": {
    "code": "rate_unavailable",
    "message": "This selected rate is no longer available. Refresh the hotel rates and choose another option.",
    "details": []
  }
}

Tell the traveller the room has just sold out, fetch the hotel's rate sheet again, and let them choose another room. Don't retry the same quote; it won't come back.

Other outcomes

ResponseWhat happenedWhat to do
410 quote_expiredMore than 20 minutes since the quote was created or last checked.Refresh the rate sheet; if the search has expired too, search again.
409 price_check_conflictTwo price-checks for the same quote overlapped.Retry once. Make sure your checkout only fires one.
409 quote_not_repriceableThe quote has already been claimed by a booking, or has expired.Look up any existing booking before creating another; otherwise start from fresh rates.
409 price_check_currency_unavailableThe live price came back in a currency we can't settle in.Choose another rate, or search again.
503 supplier_unavailableThe inventory source didn't answer in time.Retry after a few seconds, or offer another rate.