Hotel Price Intelligence & Rate Parity Tracker avatar

Hotel Price Intelligence & Rate Parity Tracker

Pricing

Pay per usage

Go to Apify Store
Hotel Price Intelligence & Rate Parity Tracker

Hotel Price Intelligence & Rate Parity Tracker

Compare hotel prices across Booking.com, Hotels.com, and Expedia in one run. Detect rate parity violations and find the best OTA deal for any hotel.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

BotFlowTech

BotFlowTech

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 days ago

Last modified

Share

Compare hotel prices across Booking.com, Hotels.com, and Expedia in one run. Detect rate parity violations and find the best deals automatically.


What it does

This actor takes a list of hotel names (or a city/country) and a date range, then searches all three major Online Travel Agencies in parallel. For every hotel it produces a single comparison record containing:

  • The lowest price per night on each OTA
  • Which platform has the best deal (bestOTA)
  • The absolute price variance in your chosen currency
  • Whether rate parity is maintained (prices within 5% across OTAs)
  • Availability status, room types, cancellation policy, and breakfast flags

Each record is pushed to the Apify dataset in real time as hotels are processed, so you can integrate it into monitoring dashboards, spreadsheet exports, or downstream webhooks.


Use cases

Use caseWho uses it
Rate parity monitoringRevenue managers at hotel chains checking that OTAs honor contracted rates
OTA competitive comparisonTravel agencies and booking platforms benchmarking competitor pricing
Price trend trackingRunning the actor on a daily schedule to build a 30-day pricing history per hotel
Deal-finder appsConsumer apps surfacing the cheapest OTA for a given hotel and date
Hotel competitor intelligenceIndependent hotels monitoring nearby property prices to adjust their own rates
Travel journalismDeal-hunters and travel bloggers verifying "best price guarantee" claims

Input

{
"hotelNames": ["Marriott Times Square", "Hilton London Metropole"],
"checkIn": "2025-06-15",
"checkOut": "2025-06-18",
"adults": 2,
"rooms": 1,
"currency": "USD",
"platforms": ["booking", "hotels", "expedia"],
"maxHotels": 50
}

Or use location-based bulk search instead of hotelNames:

{
"searchByLocation": {
"city": "Paris",
"country": "FR",
"stars": 4
},
"checkIn": "2025-08-01",
"checkOut": "2025-08-04",
"adults": 2,
"rooms": 1,
"currency": "EUR",
"platforms": ["booking", "expedia"],
"maxHotels": 100
}

Input fields

FieldTypeDefaultDescription
hotelNamesstring[]List of hotel names to compare. Use specific names for best matching (e.g. "Marriott Times Square New York").
searchByLocationobjectAlternative to hotelNames. Finds all hotels in a city, optionally filtered by star rating.
searchByLocation.citystringCity name (e.g. "New York", "London")
searchByLocation.countrystringCountry name or ISO 2-letter code (e.g. "US", "FR")
searchByLocation.starsnumberOptional star rating filter (1–5)
checkInstringrequiredCheck-in date in YYYY-MM-DD format
checkOutstringrequiredCheck-out date in YYYY-MM-DD format
adultsinteger2Number of adult guests per room
roomsinteger1Number of rooms
currencystring"USD"ISO 4217 currency code for prices
platformsstring[]["booking","hotels","expedia"]Which OTAs to query. Any subset of the three.
maxHotelsinteger50Max hotels to process (1–500)
proxyConfigurationobjectApify proxy settings. Residential proxies strongly recommended.
requestTimeoutSecsinteger60Per-page timeout in seconds
maxConcurrencyinteger3Parallel browser sessions (1–10)

Output

One dataset item per hotel. Example output for two hotels:

[
{
"searchedName": "Marriott Times Square",
"checkIn": "2025-06-15",
"checkOut": "2025-06-18",
"nights": 3,
"adults": 2,
"rooms": 1,
"currency": "USD",
"platforms": {
"booking": {
"platform": "booking",
"hotelName": "New York Marriott Marquis",
"normalizedName": "new york marriott marquis",
"starRating": 4,
"location": "Times Square, New York",
"latitude": null,
"longitude": null,
"lowestPricePerNight": 289.00,
"averagePricePerNight": 312.50,
"rooms": [
{
"roomType": "Standard Room",
"pricePerNight": 289.00,
"totalPrice": 867.00,
"cancellationPolicy": "free_cancel",
"breakfastIncluded": false
}
],
"cancellationPolicy": "free_cancel",
"breakfastIncluded": false,
"available": true,
"reviewScore": 8.4,
"reviewCount": 12480,
"directUrl": "https://www.booking.com/hotel/us/new-york-marriott-marquis.html",
"currency": "USD",
"scrapedAt": "2025-04-02T14:30:00.000Z",
"error": null
},
"hotels": {
"platform": "hotels",
"hotelName": "New York Marriott Marquis",
"normalizedName": "new york marriott marquis",
"starRating": 4,
"location": "Times Square, Manhattan",
"latitude": null,
"longitude": null,
"lowestPricePerNight": 299.00,
"averagePricePerNight": 299.00,
"rooms": [
{
"roomType": "Standard Room",
"pricePerNight": 299.00,
"totalPrice": 897.00,
"cancellationPolicy": "free_cancel",
"breakfastIncluded": false
}
],
"cancellationPolicy": "free_cancel",
"breakfastIncluded": false,
"available": true,
"reviewScore": 8.2,
"reviewCount": 10920,
"directUrl": "https://www.hotels.com/ho123456/",
"currency": "USD",
"scrapedAt": "2025-04-02T14:30:08.000Z",
"error": null
},
"expedia": {
"platform": "expedia",
"hotelName": "New York Marriott Marquis",
"normalizedName": "new york marriott marquis",
"starRating": 4,
"location": "Times Square, New York, NY",
"latitude": null,
"longitude": null,
"lowestPricePerNight": 312.00,
"averagePricePerNight": 312.00,
"rooms": [
{
"roomType": "Standard Room",
"pricePerNight": 312.00,
"totalPrice": 936.00,
"cancellationPolicy": "non_refundable",
"breakfastIncluded": false
}
],
"cancellationPolicy": "non_refundable",
"breakfastIncluded": false,
"available": true,
"reviewScore": 8.3,
"reviewCount": 9870,
"directUrl": "https://www.expedia.com/h1234567.Hotel-Information",
"currency": "USD",
"scrapedAt": "2025-04-02T14:30:18.000Z",
"error": null
}
},
"bestPrice": 289.00,
"bestOTA": "booking",
"worstPrice": 312.00,
"worstOTA": "expedia",
"priceVariance": 23.00,
"priceDifferencePercent": 7.96,
"rateParity": false,
"rateParityThresholdPercent": 5,
"comparedAt": "2025-04-02T14:30:18.000Z",
"dataQuality": "full"
},
{
"searchedName": "Hilton London Metropole",
"checkIn": "2025-06-15",
"checkOut": "2025-06-18",
"nights": 3,
"adults": 2,
"rooms": 1,
"currency": "USD",
"platforms": {
"booking": {
"platform": "booking",
"hotelName": "Hilton London Metropole",
"normalizedName": "hilton london metropole",
"starRating": 4,
"location": "Paddington, London",
"latitude": null,
"longitude": null,
"lowestPricePerNight": 178.00,
"averagePricePerNight": 195.00,
"rooms": [
{
"roomType": "Standard Room",
"pricePerNight": 178.00,
"totalPrice": 534.00,
"cancellationPolicy": "free_cancel",
"breakfastIncluded": false
}
],
"cancellationPolicy": "free_cancel",
"breakfastIncluded": false,
"available": true,
"reviewScore": 7.9,
"reviewCount": 8440,
"directUrl": "https://www.booking.com/hotel/gb/hilton-london-metropole.html",
"currency": "USD",
"scrapedAt": "2025-04-02T14:31:00.000Z",
"error": null
},
"hotels": {
"platform": "hotels",
"hotelName": "Hilton London Metropole",
"normalizedName": "hilton london metropole",
"starRating": 4,
"location": "Paddington, London",
"latitude": null,
"longitude": null,
"lowestPricePerNight": 180.00,
"averagePricePerNight": 180.00,
"rooms": [
{
"roomType": "Standard Room",
"pricePerNight": 180.00,
"totalPrice": 540.00,
"cancellationPolicy": "free_cancel",
"breakfastIncluded": false
}
],
"cancellationPolicy": "free_cancel",
"breakfastIncluded": false,
"available": true,
"reviewScore": 7.8,
"reviewCount": 7120,
"directUrl": "https://www.hotels.com/ho234567/",
"currency": "USD",
"scrapedAt": "2025-04-02T14:31:08.000Z",
"error": null
},
"expedia": {
"platform": "expedia",
"hotelName": "Hilton London Metropole",
"normalizedName": "hilton london metropole",
"starRating": 4,
"location": "Paddington, London, UK",
"latitude": null,
"longitude": null,
"lowestPricePerNight": 177.00,
"averagePricePerNight": 177.00,
"rooms": [
{
"roomType": "Standard Room",
"pricePerNight": 177.00,
"totalPrice": 531.00,
"cancellationPolicy": "free_cancel",
"breakfastIncluded": false
}
],
"cancellationPolicy": "free_cancel",
"breakfastIncluded": false,
"available": true,
"reviewScore": 7.9,
"reviewCount": 6980,
"directUrl": "https://www.expedia.com/h2345678.Hotel-Information",
"currency": "USD",
"scrapedAt": "2025-04-02T14:31:18.000Z",
"error": null
}
},
"bestPrice": 177.00,
"bestOTA": "expedia",
"worstPrice": 180.00,
"worstOTA": "hotels",
"priceVariance": 3.00,
"priceDifferencePercent": 1.69,
"rateParity": true,
"rateParityThresholdPercent": 5,
"comparedAt": "2025-04-02T14:31:18.000Z",
"dataQuality": "full"
}
]

Output fields reference

Top-level comparison fields

FieldTypeDescription
searchedNamestringThe hotel name as provided in the input
checkInstringCheck-in date (YYYY-MM-DD)
checkOutstringCheck-out date (YYYY-MM-DD)
nightsnumberNumber of nights
adultsnumberAdults searched for
roomsnumberRooms searched for
currencystringCurrency of all prices
platformsobjectPer-platform data keyed by booking, hotels, expedia
bestPricenumber | nullLowest price per night found across all platforms
bestOTAstring | nullPlatform name with the lowest price
worstPricenumber | nullHighest price per night found
worstOTAstring | nullPlatform name with the highest price
priceVariancenumber | nullAbsolute difference: worstPrice - bestPrice
priceDifferencePercentnumber | nullRelative spread: (worstPrice - bestPrice) / bestPrice * 100
rateParityboolean | nulltrue if all OTA prices are within 5% of each other; false = violation; null = only one platform returned data
rateParityThresholdPercentnumberThreshold used for rate parity check (default: 5%)
comparedAtstringISO 8601 timestamp of when comparison was computed
dataQuality"full" | "partial" | "failed"full = all queried platforms returned prices; partial = some failed; failed = none returned data

Per-platform price fields (inside platforms.booking, platforms.hotels, platforms.expedia)

FieldTypeDescription
platformstringPlatform identifier
hotelNamestringHotel name as returned by the OTA
normalizedNamestringNormalized name used for matching
starRatingnumber | nullHotel star rating (1–5)
locationstringAddress or neighborhood string from the OTA
latitudenumber | nullGPS latitude (when available)
longitudenumber | nullGPS longitude (when available)
lowestPricePerNightnumber | nullCheapest room option per night
averagePricePerNightnumber | nullAverage across available room types
roomsRoomOffer[]Array of room offers (see below)
cancellationPolicy"free_cancel" | "non_refundable" | "mixed" | "unknown"Overall cancellation policy
breakfastIncludedboolean | nullWhether any offer includes breakfast
availablebooleanWhether the hotel had any availability
reviewScorenumber | nullGuest review score (OTA scale, typically 0–10)
reviewCountnumber | nullTotal number of guest reviews
directUrlstringDeep link to hotel page on the OTA
currencystringCurrency of prices
scrapedAtstringISO 8601 timestamp when this OTA was queried
errorstring | nullError message if this OTA failed for this hotel

Room offer fields (inside rooms[])

FieldTypeDescription
roomTypestringRoom category name
pricePerNightnumberPrice per night for this room type
totalPricenumberTotal price for the full stay
cancellationPolicy"free_cancel" | "non_refundable" | "unknown"Cancellation policy for this specific room
breakfastIncludedbooleanWhether breakfast is included

Rate parity explained

Rate parity is a contractual or strategic requirement that a hotel's room prices remain consistent across all booking channels (OTAs, direct website, etc.).

This actor flags a rate parity violation when any OTA's price differs from the cheapest platform by more than 5% (priceDifferencePercent > 5).

Revenue managers can run this actor daily on a schedule and filter output for rateParity: false to catch violations and renegotiate OTA contracts.


Scheduling for price monitoring

To track a hotel's price over time, schedule the actor using Apify Scheduler:

  1. Go to Schedules in your Apify Console
  2. Create a new schedule (e.g. daily at 6:00 AM UTC)
  3. Attach this actor with your hotel list and target dates
  4. Connect the dataset to a Google Sheet or webhook for automatic alerting

Each run's output is appended to the dataset, building a historical price record.


Proxy recommendations

Hotel booking sites aggressively block datacenter IPs. For reliable results:

  • Use Apify Residential Proxies (proxyConfiguration: { useApifyProxy: true, apifyProxyGroups: ["RESIDENTIAL"] })
  • For high-volume runs (100+ hotels), consider country-specific residential proxies matching the target OTA's locale
  • Datacenter proxies may work for testing but will have higher block rates in production

Pricing

$2.00 per 1,000 hotel comparisons (PAY_PER_EVENT billing)

Run typeHotelsPlatformsCost
Quick check10 hotels3 platforms$0.02
Daily monitoring500 hotels3 platforms$1.00
Weekly agency run200 hotels3 platforms$0.40

A single comparison = one dataset item (one hotel × all platforms). You are not charged per platform call — only per completed hotel comparison record.


Performance

MetricTypical value
Time per hotel (3 platforms)30–60 seconds
Concurrency (default)3 parallel browsers
50 hotels, 3 platforms~10–15 minutes
500 hotels, 3 platforms~90–150 minutes

Actual performance depends on OTA response times, proxy speed, and whether CAPTCHAs are encountered.


Limitations

  • OTAs may change their HTML structure, which can require selector updates. The actor uses multiple fallback selectors per field to reduce breakage.
  • Geographic availability: some OTA features (currencies, deal badges) vary by region. Setting proxyConfiguration to match the target currency's country improves accuracy.
  • Dynamic pricing: OTA prices can change within seconds. Prices in the dataset reflect the moment each OTA was queried during the run.
  • This actor is for market research and price intelligence purposes. Review each OTA's Terms of Service before using in production.