Getting Started with the Xeni Activities APIHow to Book an ActivityHow to Browse Activity Tags and CategoriesHow to Cancel an Activity BookingHow to Check Activity AvailabilityHow to Get Activity DetailsHow to Retrieve Activity Booking DetailsHow to Search for Activities with FiltersHow to Search for Activity DestinationsCar Rental API - Getting StartedCar Rental API - Understanding Response FieldsHow to Book a Car RentalHow to Get Rental Car Details and Equipment Add-OnsHow to Retrieve or Cancel a Car Rental BookingHow to Search for Available Rental CarsHow to Search for Pickup LocationsHow to Use Car Rental Search FiltersDeals API Best Practices for IntegrationDeals API Frequently Asked QuestionsGetting Started with the Xeni Deals APIDeals API Request Parameters and Headers ReferenceDeals API Supported Currencies and LocalizationHow to Display Deals in Your ApplicationHow to Fetch Hotel Deals by LocationFlights API Error Codes and TroubleshootingGetting Started with the Xeni Flights APIHow to Book a FlightHow to Check Flight Availability and PricingHow to Confirm or Cancel a Flight BookingHow to Retrieve Fare Rules for a FlightHow to Retrieve Flight Booking DetailsHow to Search for Airports Using AutocompleteHow to Search for FlightsHow to Use Flight Search Filters, Sorting, and PaginationHow to Check Room Availability and PricingHow to Filter Vacation Rental ResultsHow to Get Resort Property Details, Amenities, and AccessibilityHow to Hold and Confirm a Resort BookingHow to Release a Resort HoldHow to Retrieve Resort Booking DetailsHow to Search for Available ResortsHow to Search for Resort DestinationsHow to Search for Vacation Rental LocationsHow to Search for Vacation RentalsHow to Use Resort Search Filters and SortingGetting Started with the Xeni Resorts APIResorts API: Understanding Booking Statuses and PoliciesGetting Started with the Vacation Rentals APIVacation Rentals Frequently Asked QuestionsVacation Rentals Supported Property TypesUnderstanding Async Search for Vacation RentalsAuthentication & API SignaturesBooking Hotels — Direct API & SSO CheckoutError Handling, Rate Limits & Best PracticesGetting Started with the Xeni Hotels APIManaging Bookings: Status, Retrieval & CancellationPricing Confirmation & Token LifecycleRetrieving Hotel Details & Room AvailabilitySearching for Hotels: Locations, Filters & PaginationSearching for HotelsSession Management & Correlation IDsAPI authentication and getting your API keys

Error Handling, Rate Limits & Best Practices

Last updated: 2026-02-13

Error Handling, Rate Limits & Best Practices

A production-grade integration should handle API errors gracefully, respect rate limits, and follow caching and performance best practices. This article covers all three topics to help you build a reliable, performant integration.

Error Response Format

When an API call fails, the response body contains a structured error:

JSON
{
  "message": "Description of the error",
  "status": 400
}

Some error responses include additional detail:

JSON
{
  "error": {
    "message": "Detailed error description",
    "status": 400
  }
}

*

HTTP Status Codes

StatusMeaningCommon CausesAction
200SuccessRequest completed normally.Process the response data.
400Bad RequestMissing required parameters, invalid date format, invalid coordinates, malformed request body.Validate your request data before sending. Check required fields and data types.
401UnauthorizedMissing, expired, or invalid API signature.Generate a new signature and retry the request.
404Not FoundInvalid property ID, booking ID, or endpoint path.Verify the ID exists and the endpoint URL is correct.
429Too Many RequestsRate limit exceeded.Back off and retry after the window resets. See Rate Limits below.
500Internal Server ErrorUnexpected server-side issue.Retry after a brief delay. If persistent, contact support.
503Service UnavailableAPI is temporarily unavailable (maintenance, overload).Retry with exponential backoff.

*

Error Handling by Endpoint

Authentication Errors (401)

The most common cause is an expired signature. Implement auto-refresh logic (see Authentication & API Signatures) and retry the failed request with the new signature.

async function apiCall(method, endpoint, data, correlationId) {  let signature = await signatureManager.getSignature();

try { return await makeRequest(method, endpoint, data, signature, correlationId); } catch (error) { if (error.status === 401) { // Signature may have expired — force refresh and retry once signature = await signatureManager.forceRefresh(); return await makeRequest(method, endpoint, data, signature, correlationId); } throw error; }}

Search Errors (No Results)

A hotel search may return zero results without an error status. This isn't an API failure — it means no properties matched your criteria. Handle this by:

  • Suggesting nearby locations or broader date ranges.
  • Relaxing filters (e.g., remove star rating or price constraints).
  • Displaying a friendly "no results" message.

Availability Errors

Rooms may become unavailable between the search and the availability check. If the availability response returns an empty array:

  • Inform the user that the room is no longer available.
  • Suggest re-searching or checking a different hotel.

Pricing Errors

If the pricing confirmation fails or the token is invalid:

  • Re-run the availability check to get a fresh availability token.
  • Confirm the price again to get a new pricing token.
  • Notify the guest if the price has changed.

Booking Errors

Booking failures can occur due to expired pricing tokens, sold-out rooms, or invalid guest data. Always:

  • Validate guest information client-side before submitting.
  • Check pricing token freshness (10-minute window) before booking.
  • Display a clear error message and offer the option to retry.

*

Rate Limits

The Xeni Hotels API enforces rate limits to ensure fair usage and system stability.

ScopeLimitWindow
General API calls100 requests15 minutes
Chat / message endpoints20 requests5 minutes

Rate Limit Headers

Rate limit information is included in response headers:

HeaderDescription
RateLimit-LimitMaximum number of requests allowed in the window.
RateLimit-RemainingNumber of requests remaining in the current window.
RateLimit-ResetTimestamp (seconds) when the rate limit window resets.

Handling 429 Responses

When you receive a 429 response:

  1. Stop making requests immediately.
  2. Wait until the rate limit window resets (check the RateLimit-Reset header).
  3. Resume with normal request patterns.

Do not retry rate-limited requests in a tight loop — this will extend the cooldown period.

*

Caching Recommendations

Intelligent caching reduces API calls, improves response times, and stays within rate limits. Here are recommended cache durations by data type:

Data TypeRecommended TTLRationale
Location autocomplete results1 hourLocations rarely change. Safe to cache aggressively.
Hotel details (property info)1 hourHotel descriptions, amenities, and photos don't change frequently.
Hotel search results30 minutesPrices and availability shift over time. Cache for short-term reuse.
Room availability5 minutesHighly volatile. Rooms sell out and prices change rapidly.
Pricing confirmationsDo not cacheEach pricing confirmation is unique and token-specific. Always call the API fresh.

Cache Key Strategy

Generate unique cache keys from the request parameters. A common approach:

// JavaScriptimport crypto from 'crypto';

function generateCacheKey(prefix, params) { const hash = crypto.createHash('md5') .update(JSON.stringify(params)) .digest('hex'); return cache:${prefix}:${hash};}

// Examples:generateCacheKey('location', { query: 'miami' });// → "cache:location:3f8c9a2b..."

generateCacheKey('search', { lat: 25.76, long: -80.19, checkIn: '2025-06-01', checkOut: '2025-06-05' });// → "cache:search:7d2e1f4a..."

*

Timeout Configuration

Set appropriate request timeouts for each API call. Our recommendations:

EndpointRecommended Timeout
Signature generation10 seconds
Location autocomplete10 seconds
Hotel search30 seconds
Hotel details15 seconds
Availability check30 seconds
Price confirmation15 seconds
Booking creation30 seconds

Hotel search and availability checks may take longer because they query multiple suppliers in real time.

*

Retry Strategy

Not all errors are permanent. Use a retry strategy with exponential backoff for transient failures:

Error TypeRetry?Strategy
401 UnauthorizedYes (once)Refresh signature, then retry.
429 Rate LimitedYes (after wait)Wait for the reset window, then retry.
500 Server ErrorYes (up to 3)Exponential backoff: wait 1s, 2s, 4s.
503 UnavailableYes (up to 3)Exponential backoff: wait 2s, 4s, 8s.
400 Bad RequestNoFix the request. Retrying with the same data will produce the same error.
404 Not FoundNoVerify the resource ID. Retrying won't help.

Example: Retry with Exponential Backoff

async function apiCallWithRetry(fn, maxRetries = 3) {  for (let attempt = 0; attempt <= maxRetries; attempt++) {    try {      return await fn();    } catch (error) {      const status = error.response?.status;

// Don't retry client errors (except 401 and 429) if (status && status >= 400 && status < 500 && status !== 401 && status !== 429) { throw error; }

if (attempt === maxRetries) throw error;

const delay = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s await new Promise(resolve => setTimeout(resolve, delay)); } }}

*

Production Readiness Checklist

Before going live, verify your integration meets these criteria:

ItemDetails
Signature auto-refreshSignatures refresh before the 30-minute expiry window.
Correlation ID managementCaptured from first response and forwarded on all subsequent calls. Replaced on new location searches.
Token lifecycle handlingAvailability tokens are used for pricing only. Pricing tokens (10-minute TTL) are used for booking. Expiry is checked before use.
Error handlingAll HTTP error codes are handled. 401 triggers signature refresh. 429 triggers backoff.
Rate limit complianceApplication respects rate limits and doesn't retry 429s aggressively.
CachingLocations and hotel details are cached. Availability is cached briefly or not at all.
TimeoutsAll API calls have appropriate timeouts configured.
Credential securityAPI key and secret are stored in environment variables, not in source code.
Environment configurationUAT and production base URLs are configurable, not hard-coded.
Graceful degradationIf caching layer (Redis) is unavailable, the application falls back to direct API calls.
LoggingAPI calls, errors, and key events are logged for debugging and monitoring.
Health checksApplication exposes a health endpoint that verifies connectivity to dependencies (Redis, Xeni API signature status).

*

Getting Help

If you encounter issues that aren't resolved by this documentation:

  • Check the error message: The API returns descriptive error messages that usually point to the root cause.
  • Verify in UAT first: Test your request against the UAT environment to isolate the issue.
  • Contact support: Reach out to your Xeni account representative with the following details:

- The full API request (endpoint, headers, body)
- The full API response (status code, headers, body)
- The correlation ID from the session
- The timestamp of the request

Was this article helpful?