---
title: "Preview what cancelling a hotel booking would cost"
method: POST
path: "/v1/hotel_cancel_preview"
tags: ["Post-booking"]
---

# Preview what cancelling a hotel booking would cost

`POST /v1/hotel_cancel_preview`

## Request

- Base URL: `https://api.gojinko.com`
- URL: `https://api.gojinko.com/v1/hotel_cancel_preview`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

Quote what cancelling would return to the customer right now: the refund, the penalty in force, and the policy behind them. NOTHING is cancelled. `refund` is the customer figure — what they paid for the item less the penalty. All amounts are customer-facing only. `commitable: false` means a commit would be refused and `not_commitable_reason` says why. The handle this returns is named `quote`: it is what POST /v1/hotel_cancel_commit consumes, and it stops binding at `expires_at`. Every call here needs API authentication; this is about which mode identifies the booking. Call get_booking first, then send booking_ref and the selected booked_item_id. An owning credential identifies the booking without last_name; guests must supply it. The deprecated `provider`, `order_id`, `provider_reference` and `provider_booking_id` are accepted until 2027-04-30 where the request declares them; a request that sends one is answered with `Deprecation` and `Sunset` headers.

## Request body

- HotelCancelPreviewRequest
  - `booking_ref` string: Jinko booking reference. Call get_booking first, then select its booked_item_id for servicing.
  - `booked_item_id` string: The booked item, from get_booking items[].booked_item_id. Preserved across exchanges. Omit only when the booking has exactly one item of the requested domain; otherwise a 409 returns items to choose from.
  - `last_name` string: Required for guest lookup. A credential that owns the booking may omit it; ownership is checked by the platform.
  - `provider_reference` string: Deprecated: name the booking with booking_ref and booked_item_id from get_booking. Names the booking instead of booking_ref and last_name, never beside it, and needs a credential that owns the booking. Accepted until 2027-04-30; a request that sends it is answered with `Deprecation` and `Sunset` headers.
  - `intent` IntentInput
    - `user_intent` string, nullable: The user's natural-language intent: the Alpic PII-stripped paraphrase when available, else a best-effort fallback to the client-provided NL query.

## Response `200`

What cancelling would cost

- HotelCancelPreviewResponse
  - `quote_id` string: This quote. Pass it as `quote_id` to POST /v1/hotel_cancel_commit — it binds the commit to the figures below. Opaque; the format may evolve.
  - `quote` string: Deprecated: use `quote_id` instead. Same value.
  - `state` string: Lifecycle of the QUOTE, not of a cancellation — nothing has been cancelled by this call. `completed` means the figures are final until `expires_at`.
  - `commitable` boolean: Whether a commit against this quote would be accepted right now. When false, `not_commitable_reason` says why and committing is pointless.
  - `support_level` 'AUTO' | 'MANUAL_REQUIRED': How this cancellation would be carried out. `AUTO` — the platform completes it end to end. `MANUAL_REQUIRED` — it is possible, but a Jinko agent has to act; expect a delay rather than an immediate result, and do not treat it as a failure; `manual_reason` says why. There is no "unsupported" level: a supplier that cannot be cancelled through the API arrives as `commitable: false` with `not_commitable_reason: provider_unsupported`, and a booking the supplier will not cancel as it stands arrives as a 409 `not_cancellable` — from the preview as well as the commit — with `error.message` “This booking cannot be cancelled online. Contact Jinko support.”
  - `manual_reason` string: Why a person has to act, in words the customer can be shown. Present with `support_level: MANUAL_REQUIRED`. Where the reason would be the supplier’s own words, it reads “This request needs manual handling by Jinko support.” `not_commitable_reason` is the code to branch on; this is the sentence to show.
  - `expires_at` string: When this quote stops binding. Committing after it answers 409 `QUOTE_EXPIRED`; take a fresh quote and show the customer the new figure before committing again.
  - `booked_item_id` string: The booked item this quote would cancel — the `booked_item_id` get_booking returns. A booking holding several items is quoted and cancelled one item at a time.
  - `item` string: Deprecated: use `booked_item_id` instead. Same value.
  - `refund` object: THE CUSTOMER FIGURE: what would go back to the payment method, on the basis named in `basis`. Show this one. Absent is not zero.
    - `amount` number: Deprecated: use `amount_money` instead. Alternative to `value` on some endpoints (the two never appear together); its scale depends on decimal_places. When this object carries decimal_places, amount is an INTEGER in minor units — divide by 10 ** decimal_places (e.g. select_ancillaries total_with_ancillaries). When there is no decimal_places field, amount is a decimal in MAJOR units, safe to display as-is (e.g. trip and checkout totals).
    - `value` integer: Deprecated: use `amount_money` instead. Integer amount in MINOR units, always paired with decimal_places — divide by 10 ** decimal_places to display. Example: value 15977 with decimal_places 2 is 159.77 USD. Rendering this field directly shows prices 100x too high for 2-decimal currencies.
    - `currency` string: Deprecated: use `amount_money` instead. ISO 4217 currency code.
    - `decimal_places` integer: Deprecated: use `amount_money` instead. Scale of the integer value/amount: display = integer / 10 ** decimal_places. Always sent alongside minor-unit amounts. Usually the ISO 4217 digits of the currency (2 for USD/EUR/GBP, 0 for JPY/KRW, 3 for BHD/JOD/KWD) but currency-converted prices can carry a different scale — ALWAYS use the decimal_places sent with the amount, never a hardcoded 2. Only if the field is genuinely absent on a value-shaped object, fall back to the ISO digits for the currency.
    - `display` string: Deprecated: use `amount_money` instead. The same figure as a string ready to show: the ISO 4217 code, a space, then the amount, e.g. "USD 159.77". With decimal_places it is written at exactly that scale (value 1561500, JPY, decimal_places 2 is "JPY 15615.00"); without, at the ISO digits of the currency. Show this; compute with the number. Absent when the figure is not money (a cancellation step expressed as a percent or a number of nights) or could not be read unambiguously.
    - `amount_money` object: The refund figure. Absent when the figure is not known.
      - `value` integer, required: Integer amount in MINOR units at the ISO 4217 digits of `currency`: divide by 10 ** decimal_places to get the amount. Signed where the field says so (a price change delta).
      - `currency` string, required: ISO 4217 currency code.
      - `decimal_places` integer, required: The ISO 4217 digits of `currency` (2 for USD/EUR, 0 for JPY/KRW, 3 for BHD/KWD), and the scale of `value`.
      - `display` string, required: The same figure as a string ready to show: the ISO 4217 code, a space, then the amount at `decimal_places`, e.g. "USD 412.50". Show this; compute with `value`.
    - `basis` string: How the figure was computed. `sell_minus_penalty` — what the customer paid for this item, less the penalty. `original_charge` — the entire charge is reversed, penalty-free (a void). The platform chooses; the caller cannot ask for one.
  - `penalty` union: What the customer would forfeit. When unknown, the amount is omitted; a fee_known: false marker may remain. Absent is not zero. Read `fee_known` before showing it.
    - object
      - `amount` number: Deprecated: use `amount_money` instead. Alternative to `value` on some endpoints (the two never appear together); its scale depends on decimal_places. When this object carries decimal_places, amount is an INTEGER in minor units — divide by 10 ** decimal_places (e.g. select_ancillaries total_with_ancillaries). When there is no decimal_places field, amount is a decimal in MAJOR units, safe to display as-is (e.g. trip and checkout totals).
      - `value` integer: Deprecated: use `amount_money` instead. Integer amount in MINOR units, always paired with decimal_places — divide by 10 ** decimal_places to display. Example: value 15977 with decimal_places 2 is 159.77 USD. Rendering this field directly shows prices 100x too high for 2-decimal currencies.
      - `currency` string: Deprecated: use `amount_money` instead. ISO 4217 currency code.
      - `decimal_places` integer: Deprecated: use `amount_money` instead. Scale of the integer value/amount: display = integer / 10 ** decimal_places. Always sent alongside minor-unit amounts. Usually the ISO 4217 digits of the currency (2 for USD/EUR/GBP, 0 for JPY/KRW, 3 for BHD/JOD/KWD) but currency-converted prices can carry a different scale — ALWAYS use the decimal_places sent with the amount, never a hardcoded 2. Only if the field is genuinely absent on a value-shaped object, fall back to the ISO digits for the currency.
      - `display` string: Deprecated: use `amount_money` instead. The same figure as a string ready to show: the ISO 4217 code, a space, then the amount, e.g. "USD 159.77". With decimal_places it is written at exactly that scale (value 1561500, JPY, decimal_places 2 is "JPY 15615.00"); without, at the ISO digits of the currency. Show this; compute with the number. Absent when the figure is not money (a cancellation step expressed as a percent or a number of nights) or could not be read unambiguously.
      - `amount_money` object: The penalty figure. Present only when `fee_known` is true; absent when the fee is unknown, which is not zero.
        - `value` integer, required: Integer amount in MINOR units at the ISO 4217 digits of `currency`: divide by 10 ** decimal_places to get the amount. Signed where the field says so (a price change delta).
        - `currency` string, required: ISO 4217 currency code.
        - `decimal_places` integer, required: The ISO 4217 digits of `currency` (2 for USD/EUR, 0 for JPY/KRW, 3 for BHD/KWD), and the scale of `value`.
        - `display` string, required: The same figure as a string ready to show: the ISO 4217 code, a space, then the amount at `decimal_places`, e.g. "USD 412.50". Show this; compute with `value`.
      - `fee_known` boolean: false means the penalty could not be established — UNKNOWN, not zero. Render it as "we will confirm the fee", never as free cancellation, and expect the final figure on the operation status.
    - object
      - `fee_known` false, required
  - `policy` object: The supplier's cancellation policy as it stands, for explaining the figures to the customer.
    - `free_cancel_until` string, nullable: The last instant at which cancelling costs nothing. `null` means there is no free window — either the booking never had one or it has passed.
    - `is_refundable_now` boolean
    - `tiers` object[]: The supplier's policy steps in time order. Informational: the figure that binds is `penalty`, computed for right now.
      - `from` string: When this step starts applying.
      - `amount` Money: A money figure in one of two scales. New integrations read the `*_money` field beside it (a `MoneyValue`) where there is one, and `value` on objects that carry it; the rule below applies only to the deprecated forms. When `decimal_places` is present, `value` (or the deprecated `amount`) is an INTEGER in minor units: divide by 10 ** decimal_places. When it is absent, the deprecated `amount` is already in MAJOR units. Branch on whether decimal_places is present in the response you received, never on the currency code or the field name. `display` is the same figure as a string to show.
        - `amount` number: Deprecated: use `value` instead (the same integer) where this object carries decimal_places. Where it does not, the figure is in MAJOR units and the field holding this object is itself deprecated: read its `*_money` sibling. The two-scale rule applies only to deprecated fields. Alternative to `value` on some endpoints (the two never appear together); its scale depends on decimal_places. When this object carries decimal_places, amount is an INTEGER in minor units — divide by 10 ** decimal_places (e.g. select_ancillaries total_with_ancillaries). When there is no decimal_places field, amount is a decimal in MAJOR units, safe to display as-is (e.g. trip and checkout totals).
        - `value` integer: Integer amount in MINOR units, always paired with decimal_places — divide by 10 ** decimal_places to display. Example: value 15977 with decimal_places 2 is 159.77 USD. Rendering this field directly shows prices 100x too high for 2-decimal currencies.
        - `currency` string: ISO 4217 currency code.
        - `decimal_places` integer: Scale of the integer value/amount: display = integer / 10 ** decimal_places. Always sent alongside minor-unit amounts. Usually the ISO 4217 digits of the currency (2 for USD/EUR/GBP, 0 for JPY/KRW, 3 for BHD/JOD/KWD) but currency-converted prices can carry a different scale — ALWAYS use the decimal_places sent with the amount, never a hardcoded 2. Only if the field is genuinely absent on a value-shaped object, fall back to the ISO digits for the currency.
        - `display` string: The same figure as a string ready to show: the ISO 4217 code, a space, then the amount, e.g. "USD 159.77". With decimal_places it is written at exactly that scale (value 1561500, JPY, decimal_places 2 is "JPY 15615.00"); without, at the ISO digits of the currency. Show this; compute with the number. Absent when the figure is not money (a cancellation step expressed as a percent or a number of nights) or could not be read unambiguously.
      - `fraction` number: The share of the paid price withheld from `from` onwards, when the supplier states the step as a proportion rather than a sum. A step carries `amount` or `fraction`, not both.
  - `not_commitable_reason` string: Why `commitable` is false. Today: `penalty_exceeds_sell` (the penalty is at least what the customer paid), `multi_currency_basis` (the supplier prices the fee in a currency the customer was not charged in, so no single refund figure exists). A fee the supplier’s policy does not establish (`penalty.fee_known: false`) is `support_level: MANUAL_REQUIRED` with no reason code — read `manual_reason`. Two refusals are never values here: a booking the supplier will not cancel as it stands is 409 `not_cancellable` from this preview itself, and a supplier with no cancellation route is 422 `provider_unsupported`. The contract reserves further values (`provider_unsupported`, `funds_unavailable`, `insufficient_time_to_converge`) and new reasons may be added, so treat an unrecognised value as "not right now".

## Other responses

- `400`: Bad request
- `401`: Authentication required
- `402`: Payment required — organization balance exhausted
- `404`: Unknown booking, or one this credential may not read.
- `409`: The supplier will not cancel this booking as it stands — it is already cancelled, or was never confirmed. A hotel booking that is no longer active is also refused with `reason_code: booking_not_active` when the caller may service it (any other caller gets the same 404 as for an unknown booking). `code` is `not_cancellable`, as a sibling of `error`. `error.message` is “This booking cannot be cancelled online. Contact Jinko support.” when the supplier refused, or the platform’s sentence when the booking is no longer active. There is no quote to show and nothing to commit. Another operation already in flight on the item (an exchange, a refund or a cancellation) is refused the same way, with `code: active_operation_exists` and `active_operation` naming it: follow it with the status route and preview again once it has finished. A 409 with no `code` beside `error` is not this case — the reference matched more than one booking.
- `410`: The resource this request names no longer exists
- `422`: Validation error
- `429`: Rate limit or quota exceeded
- `502`: The travel provider rejected the request, or an upstream call failed
- `503`: No travel provider can serve the request right now
- `504`: The travel provider did not answer in time

---

[API](https://skmtc.dev/gojinko/apis/jinko-public-api.md) - [All operations](https://skmtc.dev/gojinko/apis/jinko-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/gojinko/apis/jinko-public-api/revisions/ac5046767e4c?raw)
