Hotel cancellations and recovery
You cancel live rooms, interpret refund intentions and handle uncertain results.
You can read an advisory cancellation quote before canceling. For an eligible booking, the endpoint reads fresh supplier data. An active stored WebBeds restriction returns HTTP 422 with cancellation_restricted before any preview; restrictions are checked again after the supplier reads. WebBeds previews the penalty for each live room; source is SUPPLIER_QUOTE. LiteAPI and Duffel Stays retrieve the booking, and the service calculates from its returned cancellation policy; source is POLICY_ESTIMATE. checked_at records when the supplier reads completed in UTC. It is not an expiry or fee guarantee. The supplier's cancellation response determines the final fee. A restriction can prevent cancellation during a stated time window.
You cannot bind the cancel request to that quote or set a maximum fee. The fee can change between your quote and the supplier's cancellation, including when a penalty deadline passes. Explain this before your customer approves cancellation; if approval requires a fixed maximum fee, contact support instead of submitting an unconditional cancel request.
If a retrieved booking policy cannot establish an amount, available is false with a reason; never display that as free cancellation. A failed supplier read or an unusable WebBeds preview returns an error without falling back to stored terms. If the booking changes while the quote is fetched, the endpoint returns 409: refresh the booking before requesting another quote. Viewing a quote does not cancel rooms, start refunds or change the stored booking.
Interpret a quote
You receive HTTP 200 with either an available quote or an unavailable amount. An available amount does not establish that a new cancellation can start immediately: an earlier partial attempt may still need to finish or resume refund processing. The response uses Cache-Control: no-store; request a fresh quote when the customer returns to cancellation.
Estimate from a retrieved policy
You receive POLICY_ESTIMATE when the fee is calculated from the policy returned by a fresh booking retrieval. The example's refund is the booking price less the estimated fee, before the captured-funds cap applied during cancellation.
{
"data": {
"available": true,
"source": "POLICY_ESTIMATE",
"checked_at": "2027-10-02T09:00:00Z",
"fee": {
"amount": 0,
"currency": "USD"
},
"refund": {
"amount": 600,
"currency": "USD"
},
"free_until": "2027-11-20T00:00:00Z",
"restrictions": []
}
}Supplier cancellation preview
You receive SUPPLIER_QUOTE when WebBeds returns a cancellation preview for each remaining room. This separate example has a combined fee of 100 USD for a 600 USD stay. The preview still does not guarantee the final applied fee.
{
"data": {
"available": true,
"source": "SUPPLIER_QUOTE",
"checked_at": "2027-10-02T09:00:00Z",
"fee": {
"amount": 100,
"currency": "USD"
},
"refund": {
"amount": 500,
"currency": "USD"
},
"restrictions": []
}
}Unknown fee
You receive no fee or refund fields when available is false. Present the amount as unavailable and follow the reason; do not substitute zero or an earlier quote.
{
"data": {
"available": false,
"source": "POLICY_ESTIMATE",
"checked_at": "2027-10-02T09:00:00Z",
"reason": "no_policy"
}
}| Reason | Your next action |
|---|---|
| no_policy | Contact support when the fresh policy does not establish the fee. |
| no_total | Contact support when the required price is unavailable. |
| no_live_rooms | Read the booking to establish whether any rooms remain. |
| currency_mismatch | Contact support; do not combine amounts in different currencies. |
Restricted cancellation window
You receive HTTP 422 with reason cancellation_restricted while a stored WebBeds restriction is active, before any preview and again if one starts while the previews run. details.restricted_until gives the end of the restriction. Do not cancel before then; request a fresh quote afterward before deciding again:
{
"error": {
"code": "unprocessable",
"reason": "cancellation_restricted",
"message": "Cancellation is currently restricted",
"request_id": "req_example",
"details": {
"restricted_until": "2027-11-22T00:00:00Z"
}
}
}Cancel the stay
You submit cancellation once and read the booking while processing continues. Whole-booking suppliers cancel the stay as one operation. WebBeds cancels each live room, so one room can be released while another is refused or remains unresolved.
You treat CANCEL_IN_PROGRESS as acceptance for processing, not completion. The cancel response and subsequent booking reads use the same booking schema. The endpoint reference includes complete response examples for each outcome.
| Outcome | What you display |
|---|---|
| CANCELED with a numeric refund | Your reservation is released and a refund amount is recorded; settlement remains unconfirmed. |
| CANCELED with refund: null | Your reservation is released, but the refund requires investigation. |
| PARTIALLY_CANCELED | Your rooms with canceled_at are released; rooms without it remain live. Inspect the attempt status and error_code before deciding the next action. |
| A rejected attempt | Your unreleased rooms remain reserved. Review the refusal before another request. |
You inspect every room and the cancellation history when the booking is partially canceled. A later cancellation attempt targets the remaining live rooms. An earlier attempt's refund processing must finish or resume before another attempt can start.
Understand the refund
Your refund uses the price of the released rooms, less their cancellation fees, capped by captured funds less earlier refund intentions. Whole-booking prices and terms are counted once. The refund field records the intended amount; it does not confirm settlement by your payment provider.
You cannot establish refund settlement from the booking API or a hotel.booking.canceled event. Contact support with the booking and cancellation IDs when you need to confirm that money has reached the customer.
You read where each refund goes in the attempt's refund_to: the payments that get part of it, oldest first. Each refund returns to that payment's original card, which you find in payments, and a payment fully consumed by the fee is not listed. An empty list means nothing is refunded, including after a refused or failed attempt. Null means the destination is not established yet, because the attempt is still running or its refund needs review; the money can then return only to one of the booking's CAPTURED payments.
You may see a canceled booking with an unknown refund. That means release is confirmed but the fee or refund basis requires review. A lost Duffel cancellation response can leave this outcome even after retrieval confirms cancellation, because retrieval does not establish who canceled or the applied penalty.
Handle interrupted operations
You read the existing booking after an unknown purchase or cancellation result. The service retrieves after a recorded cancellation dispatch; it does not repeat an uncertain supplier cancellation. A repeat cancel request can resume an exhausted cancellation workflow using its stored attempt.
You request a new offer when a booking is expired. You must resolve an in-progress purchase before starting a replacement booking, because an elapsed offer does not prove that the supplier refused the purchase.