Session Management & Correlation IDs
The Xeni Hotels API uses correlation IDs to tie related API calls together within a single search-to-booking session. Understanding how correlation IDs work is essential for a correct integration. This article explains the session lifecycle, when correlation IDs change, and how to manage them.
What Is a Correlation ID?
A correlation ID is a unique identifier that the API generates and returns in the response headers of your first API call (typically the autocomplete/location search). It links all subsequent calls — hotel search, details, availability, pricing, and booking — into a coherent session.
Think of it as a session token for the API. Without it, the API can't associate your availability check with the hotel search that preceded it.
How Correlation IDs Are Created
- You make your first API call (usually
GET /hotels/api/v2/autocomplete). - The response includes an
x-correlation-idheader. - You capture this value and include it as the
x-correlation-idheader in every subsequent API call.
Example: Capturing the Correlation ID
// JavaScript (axios)const response = await axios.get('/hotels/api/v2/autocomplete', { params: { key: 'Miami' }, headers: { 'Authorization': signature, 'Content-Type': 'application/json' }});
// Capture the correlation ID from response headersconst correlationId = response.headers['x-correlation-id'];
// Use it in all subsequent callsconst searchResponse = await axios.post('/hotels/api/v2/properties?page=1&limit=20', searchBody, { headers: { 'Authorization': signature, 'Content-Type': 'application/json', 'x-correlation-id': correlationId // Pass it forward }});
Example: Python
# Python (requests)response = requests.get( f"{base_url}/hotels/api/v2/autocomplete", params={"key": "Miami"}, headers={"Authorization": signature, "Content-Type": "application/json"})
Capture from response headerscorrelation_id = response.headers.get("x-correlation-id")
Use in subsequent callssearchresponse = requests.post( f"{baseurl}/hotels/api/v2/properties?page=1&limit=20", json=searchbody, headers={ "Authorization": signature, "Content-Type": "application/json", "x-correlation-id": correlationid })
*
Session Lifecycle
A session begins with a location search and continues through the entire booking flow:
┌─────────────────────────────────────────────────────┐│ SESSION START ││ ││ 1. searchLocations("Miami") ││ → API returns x-correlation-id: "abc-123" ││ ││ 2. searchHotels(lat, long, dates) ││ → Send x-correlation-id: "abc-123" ││ ││ 3. getHotelDetails(propertyId) ││ → Send x-correlation-id: "abc-123" ││ ││ 4. checkAvailability(propertyId, dates, occupancy) ││ → Send x-correlation-id: "abc-123" ││ ││ 5. getPrice(availabilityToken) ││ → Send x-correlation-id: "abc-123" ││ ││ 6. SSO Checkout or createBooking(pricingToken) ││ → Uses x-correlation-id: "abc-123" ││ ││ SESSION END │└─────────────────────────────────────────────────────┘
The same correlation ID is used throughout the entire flow. All steps are linked to the same session.
*
When Does the Correlation ID Change?
A new correlation ID is generated when a new location search is performed. This is by design — a new location search starts a new session.
Example: User Changes Destination
1. User searches "Miami" → correlationId = "abc-123" → Hotels in Miami are displayed
- User searches "Las Vegas" → API returns NEW correlationId = "def-456" → Hotels in Las Vegas are displayed
- User selects a hotel in Las Vegas → Use correlationId "def-456" (NOT "abc-123") → The Miami session is effectively abandoned
Important: When a new location search returns a new correlation ID, you must discard the old correlation ID and all associated session data (search results, availability tokens, pricing tokens). These are invalidated when the session changes.
*
What to Store in Your Session
To manage the search-to-booking flow, your application should maintain session state that tracks these values:
| Field | Set When | Used By |
|---|---|---|
correlationId | Location search | All subsequent API calls (header) |
locationData | Location search | Hotel search (coordinates), SSO checkout URL |
searchParams | Hotel search | Pagination, availability check, SSO checkout URL |
searchResults | Hotel search | Display to user, hotel selection |
propertyId | User selects a hotel | Details, availability, SSO checkout URL |
roomId | Availability check | SSO checkout URL |
availabilityToken | Availability check | Price confirmation |
pricingToken | Price confirmation | SSO checkout URL, booking creation |
pricingTokenIssuedAt | Price confirmation | Token expiry check (10-minute window) |
*
Session Storage Recommendations
Server-Side Sessions
For most integrations, we recommend storing session data server-side with a TTL (time-to-live):
- Redis — Ideal for session storage with automatic expiration. Set a TTL of 30 minutes to match the API signature lifetime.
- In-memory store — Suitable for development or single-server deployments. Use a Map with periodic cleanup.
- Database — Viable for persistence, but add a
last_activitytimestamp and clean up stale sessions.
Recommended TTL
Set your session TTL to 30 minutes, matching the API signature lifetime. Extend the TTL on each user interaction to keep active sessions alive.
Session Cleanup
When a session expires or the user starts a new search:
- Discard the old correlation ID.
- Clear stored search results, tokens, and pricing data.
- The new location search will establish a fresh session with a new correlation ID.
*
Common Pitfalls
| Pitfall | Consequence | Solution |
|---|---|---|
Not passing x-correlation-id | API calls fail or return inconsistent data. | Always capture and forward the correlation ID after the first call. |
| Reusing old correlation IDs | Booking or availability calls reference stale search context. | Replace the correlation ID whenever a new location search returns a new one. |
| Using an availability token after getting a pricing token | Booking fails. | Always use the pricing_token from the pricing confirmation step. |
| Not clearing session data on new search | Old tokens and results from a previous destination contaminate the new search flow. | Reset all session data (except the new correlation ID) when the user searches a new location. |
*
](#article-9)_