Pricing Confirmation & Token Lifecycle
Hotel prices are dynamic — they can change between the time a guest views availability and the time they decide to book. The pricing confirmation step locks in a rate and returns a new token that's valid for booking. This article explains the two-token flow, why it matters, and how to handle token expiration.
Why Two Tokens?
The booking flow uses two sequential tokens:
- Availability Token — Obtained from the Check Availability endpoint. Identifies a specific room, rate, and bed configuration. This token is not a price guarantee.
- Pricing Token — Obtained from the Confirm Price endpoint (this article). Locks in the exact price for up to 10 minutes. This is the token you use for booking.
Important: You must not use the availability token directly for booking. Always call the pricing confirmation endpoint first to get a pricing token. Attempting to book with an availability token will fail.
Token Flow Diagram
Check Availability ↓availabilitytoken (identifies room/rate — price may change) ↓Confirm Price ↓pricingtoken (locked price — valid for 10 minutes) ↓SSO Checkout / Create Booking
*
Confirm Price Endpoint
Endpoint
GET /hotels/api/v2/properties/price?availability_token={token}¤cy={currency}
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
availabilitytoken | string | Yes | The availabilitytoken from rates[].beds[].availability_token in the availability response. |
currency | string | No | Currency for the quoted price. Default: USD. |
Example Request
GET /hotels/api/v2/properties/price?availabilitytoken=eyJhbGciOiJIUzI1NiJ9.room101...¤cy=USDAuthorization: {signature}x-correlation-id: {correlationid}Content-Type: application/json
Example Response
{
"data": {
"total_price": 891.08,
"base_price": 756,
"taxes": 95.08,
"fees": 40,
"currency": "USD",
"pricingtoken": "eyJhbGciOiJIUzI1NiJ9.pricingfinal..."
}
}Response Fields
| Field | Type | Description |
|---|---|---|
totalprice | number | Final total price including all taxes and fees. |
baseprice | number | Room rate before taxes and fees. |
taxes | number | Tax amount. |
fees | number | Service and booking fees. |
currency | string | Currency code for the quoted price. |
pricing_token | string | The token to use for booking. This is a new token, different from the availability token you sent in. |
Key point: The pricingtoken in the response is a new, different token from the availabilitytoken you provided in the request. You must use this new pricing_token for the SSO checkout or booking step.
*
Token Lifecycle & Expiration
Availability Token
- Source:
rates[].beds[].availability_tokenfrom the availability response. - Validity: Short-lived. Availability and prices can change at any time.
- Usage: Pass to the pricing confirmation endpoint only.
- Recommendation: Confirm pricing as soon as the guest selects a room. Don't cache availability tokens for extended periods.
Pricing Token
- Source:
pricing_tokenfrom the pricing confirmation response. - Validity: 10 minutes from the time it was issued.
- Usage: Pass to the SSO checkout URL or the booking creation endpoint.
- On expiration: If the token expires before the guest completes checkout, you must repeat the availability check and pricing confirmation to obtain a new token.
Handling Expired Tokens
If a pricing token has expired (more than 10 minutes since confirmation), the booking or checkout will fail. Handle this gracefully:
- Track when the pricing token was issued (store a timestamp alongside it).
- Before generating a checkout URL, check whether the token is still within its 10-minute window.
- If expired, transparently re-run the availability check and price confirmation before presenting the checkout link.
- Inform the guest if the price has changed between confirmations.
Example: Token Expiry Check (JavaScript)
function isPricingTokenValid(tokenIssuedAt) { const TENMINUTESMS = 10 60 1000; return (Date.now() - tokenIssuedAt) < TENMINUTESMS;}
// Before booking:if (!isPricingTokenValid(session.priceLockedAt)) { // Re-run availability check → confirm price → get new token const availability = await checkAvailability(hotelId, dates, occupancy); const pricing = await confirmPrice(availability.token); session.pricingToken = pricing.pricingToken; session.priceLockedAt = Date.now();}
*
Price Changes Between Steps
It's possible for the confirmed price to differ from the initial rate shown during the hotel search or availability check. This can happen due to:
- Dynamic pricing — Rates adjust based on real-time demand.
- Currency fluctuations — If displaying prices in a non-default currency.
- Limited inventory — The originally shown rate may have sold out, resulting in a different rate tier.
Always display the confirmed price from the pricing endpoint as the final price the guest will pay. The pricing confirmation response is the source of truth.
*
Summary: What to Store at Each Step
| Step | Values to Store |
|---|---|
| Check Availability | room.id, rates[].beds[].availabilitytoken, propertyid |
| Confirm Price | pricingtoken, totalprice, timestamp of when the token was issued |
| SSO Checkout | Use the pricingtoken + room.id + propertyid to build the URL |
*
](#article-6)_