Disclosure: I build and maintain the Apify Actor used in this tutorial (ocius-data/google-hotels-reliable).
Google Hotels already does the hard part of hotel price comparison: for each property and date it lists the price on Booking.com, Expedia, Agoda, Trip.com, the hotel's own site and many smaller sites. What it does not do is give you that table as data. If you manage a hotel and want to watch your competitors' rates, check rate parity across booking sites, or build a travel product, you end up copying numbers by hand.
This tutorial uses an Apify Actor that reads Google Hotels and returns one JSON row per hotel: price per night and for the stay (taxes and fees included), stars, guest rating, reviews, amenities, coordinates and, optionally, the price on each booking site. We will write a short Node.js script that lists the hotels of a destination for given dates, cheapest first, and shows how far apart the booking sites are for the same stay.
What you need
- Node.js 18 or later.
- A free Apify account and its API token (Console, Settings, API and Integrations).
- The official client:
npm install apify-client.
Step 1: hotels and prices for one destination
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('ocius-data/google-hotels-reliable').call({
destinations: ['Cartagena, Colombia'],
checkIn: '2026-12-10',
checkOut: '2026-12-13',
adults: 2,
currency: 'USD',
country: 'US',
maxHotels: 10,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const h of items) {
console.log(h.name, h.stars, h.rating, h.priceTotal, h.currency);
}
Notes on the input:
-
destinationstakes cities, areas or a hotel name ("Hotel Tequendama Bogotá"). A hotel name returns that hotel only, which is the simplest way to track a fixed list of competitors. -
countryis the market you search from. Booking sites and prices can vary by market, so keep it fixed when you compare runs. - Leave
checkInandcheckOutempty to search 14 days from today for 2 nights. -
hotelIdis stable: use it, not the name, as the key when you store results over time.
Step 2: the price on each booking site
Set includeProviderPrices: true. The Actor then opens each hotel's page and adds providers (one entry per site, cheapest first), cheapestProvider, the address and the phone number. The full script is javascript/hotel_rates_by_site.mjs in the examples repository; this is the part that summarizes the sites:
for (const h of hotels) {
const prices = h.providers.map((p) => p.priceTotal).filter((p) => p != null);
const spread = Math.max(...prices) - Math.min(...prices);
const official = h.providers.find((p) => p.isOfficialSite);
const officialText = official ? `, official site ${official.priceTotal}` : '';
console.log(`${h.name}: ${h.providers.length} booking sites: cheapest ${h.cheapestProvider} ${Math.min(...prices)}${officialText}, spread ${spread.toFixed(2)}`);
}
Run it:
export APIFY_TOKEN=your_token
node javascript/hotel_rates_by_site.mjs "Cartagena, Colombia" 2026-12-10 2026-12-13 3
The output of a test run on 3 November 2026, 2 adults, 3 nights, totals in USD:
3 hotels in Cartagena, Colombia, 2026-12-10 to 2026-12-13 (3 nights), cheapest first:
- InterContinental Cartagena de Indias by IHG | 5* | 4.8/5 (8528) | 540.59 USD total (180.2 per night) on the results page
19 booking sites: cheapest Catchit.com 540.59, official site 797, spread 390.60
- Hyatt Regency Cartagena | 4* | 4.7/5 (4688) | 591 USD total (197 per night) on the results page
18 booking sites: cheapest Traveluro 496.61, spread 344.89
- Sofitel Legend Santa Clara Cartagena | 5* | 4.9/5 (5211) | 1863.69 USD total (621.23 per night) on the results page
20 booking sites: cheapest Trip.com 1568.06, official site 1863.75, spread 634.69
Two things stand out in this small sample, and both are worth checking before you act on the data:
-
The spread between sites is large. For the same room nights, the most expensive site asked several hundred dollars more than the cheapest. In this sample the cheapest offers came from smaller resellers. Each entry has
freeCancellation,freeCancellationUntilandpromotion, so compare conditions, not only prices. -
The results page and the hotel page can disagree. For the Hyatt, the results page showed 591 and the cheapest site on the hotel page showed 496.61. The two pages are read a few seconds apart and can list different offers. If you need the lowest available price, use the minimum of
providers, notpriceTotal.
Step 3: watch a competitive set over time
For a hotel's competitive set, list the competitors by name in destinations, set the dates you care about (for example the next four weekends) and save the input as a task in Apify Console with a daily schedule. Store each run with hotelId, checkIn, scrapedAt and the prices, and you have a rate history per competitor and stay date. Filters such as hotelClass, minRating, freeCancellation and maxPrice keep the list focused when you search a whole city.
Cost
At the time of writing: USD 0.003 per hotel saved with a price, or USD 0.006 per hotel with the price per booking site. A daily check of 20 hotels costs about USD 0.06 (USD 0.12 with booking-site prices). Hotels without a price, duplicates and failed requests are not charged. Check the Actor page for current pricing.
Limits worth knowing
- Prices depend on the market, the currency and the moment of the search, as in Google Hotels itself. Two runs minutes apart can differ.
- The results page shows up to 8 main amenities per hotel; the full list requires the booking-site option.
- Vacation rentals are skipped unless you enable
includeVacationRentals.
Try it: Google Hotels Prices API on Apify. The script used here is in the examples repository. Feature requests are welcome in the Actor's Issues tab.
Top comments (0)