If you've ever booked a hotel online, you've probably seen this. The hotel's own site says €120 a night. Some site you've never heard of says €104. Same room, same dates.
Good for the guest. Not great for the hotel. They pay commission on that booking and still lose on price to a reseller. That's a rate parity problem, and it's common.
Hotels have a whole job for this. Revenue managers check competitor and OTA prices every morning. Many do it by hand, or pay for a rate shopping tool that isn't cheap.
I built a smaller, cheaper option because the data is already public on Google Hotels. Disclosure: it's mine, the Google Hotels Rate Monitor on Apify. I'll tell you where it falls short too.
Google already did the hard part
Open any hotel on Google Hotels and you see a list: Booking.com, Expedia, Agoda, Trip.com, Hotels.com, the hotel's own website and a bunch of smaller sites. Each with a price for your dates.
That list is the gold. One page, up to 20 booking sites. You don't need to scrape 20 websites. You need to read one page, for the right dates.
"For the right dates" turned out to be the hard bit. Google likes to quietly show you its own default dates if it doesn't like your request. So the actor checks the dates Google actually priced. If they don't match, the row is dropped and you don't pay for it.
What you put in
{
"hotels": ["Hotel Botanico Lisbon"],
"daysAhead": 7,
"rollingDates": 14,
"nights": 2,
"adults": 2,
"currency": "EUR"
}
You can use a hotel name with the city, a Google Hotels URL, or a search like "hotels in Lisbon" (it takes the top hotels and keeps tracking the same ones on later runs).
Rolling dates are the handy part. "Next 14 check-in dates, starting a week from today" moves with each run. So a daily schedule always looks at the same window ahead. No editing dates every Monday.
What you get back
A real row from a cloud run (I cut the price list from 20 sites to 3):
{"type": "hotelDate", "hotelName": "Hotel Botânico",
"checkIn": "2026-10-23", "checkOut": "2026-10-25", "nights": 2,
"lowestPrice": 103.94, "lowestPriceSite": "Vio.com",
"officialSitePrice": 120.5, "cheapestOta": "Vio.com",
"parityGapPct": 15.93, "sitesCount": 20,
"prices": [
{"site": "Vio.com", "pricePerNight": 103.94, "isOfficialSite": false},
{"site": "Trip.com", "pricePerNight": 103.98, "isOfficialSite": false},
{"site": "Hotel Botânico", "pricePerNight": 120.5, "isOfficialSite": true}
]}
Look at parityGapPct. The hotel's own site is almost 16% more expensive than the cheapest OTA. That's exactly the parity problem from the start of this post, in one number.
In monitor mode, later runs only give you what moved: a site changed its price (old, new, delta), the lowest price changed, the cheapest site changed, or the stay sold out. Small changes can be filtered with minChangePct or minChangeAmount.
A tiny parity report in Python
from apify_client import ApifyClient
import pandas as pd
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("ivora/google-hotels-rate-monitor").call(run_input={
"hotels": ["Hotel Botanico Lisbon"],
"daysAhead": 7, "rollingDates": 14, "nights": 2, "currency": "EUR",
})
rows = client.dataset(run["defaultDatasetId"]).list_items().items
df = pd.DataFrame([r for r in rows if r.get("type") == "hotelDate"])
bad = df[df["parityGapPct"] > 5]
print(bad[["hotelName", "checkIn", "officialSitePrice", "cheapestOta", "parityGapPct"]])
Five lines of pandas and you know which dates someone is undercutting you. Send it to Slack with an Apify webhook and you're done before coffee.
Price
No subscription:
- $0.005 per run start
- $0.003 per hotel and date checked
- $0.0005 per change row
One hotel, 14 dates, every day: about $1.50 a month. A competitor set of five hotels is around $6.50. Failed pages and wrong dates are not charged.
Limits
- Prices are what Google shows. Usually the cheapest standard room. US prices often exclude taxes, EU and UK usually include them. Member and mobile-only rates aren't visible.
- Small booking sites come and go between runs. The big OTAs and the hotel's own site are stable.
-
Name matching takes Google's first hit. Check
hotelNameon the first run, or paste the URL. - Destination searches give max 20 hotels (Google's first page).
It's not a full revenue management system. It's a cheap daily answer to "who is cheaper than us, and since when?"
Details: ivora.life/products/google-hotels-rate-monitor. The actor: apify.com/ivora/google-hotels-rate-monitor.
If you work in hotels, I'd love to hear what your morning rate check looks like. Spreadsheet? Tool? Pure suffering?
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.