Google Hotels Prices Scraper — Price Tracking & Rate Parity
Pricing
Pay per event
Google Hotels Prices Scraper — Price Tracking & Rate Parity
Hotel prices from Google Hotels for exact dates and guests: lowest nightly rate and stay total per hotel, plus every booking site’s rate (Booking.com, Expedia, Agoda, official site). Track prices daily, check rate parity, build price history. Pay per priced row.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Tedj MEABIOU
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 hours ago
Last modified
Categories
Share
Google Hotels prices scraper for exact dates and guests: the lowest nightly rate and the stay total for every hotel in a search, then every booking site's rate for each hotel — Booking.com, Expedia, Agoda, Hotels.com, Trip.com and the hotel's official site — with free-cancellation flags and deep links. Run it once for a price check, on a schedule for hotel price tracking and rate parity, or with a date sweep to build a price calendar and your own hotel price history. No Google API key, no login, no browser: it reads the same public Google Hotels results any visitor sees, through Apify's proxies, and returns clean JSON.
You pay only for priced rows. Sold-out hotels, empty searches and status rows cost nothing, and the price per row is stated on this page and identical on every plan.
What does Google Hotels Prices Scraper do?
Google Hotels is a metasearch engine: for a hotel and a stay it shows the rates of every booking site it knows and the hotel's own site. This scraper reads that comparison for the dates, occupancy, currency and market you choose and turns it into three kinds of rows:
hotelrows — up to 200 hotels per place search (Google's results, paged) or exactly the properties you list: lowest nightly rate, stay total, deal note ("19% less than usual"), star class, rating and review count, coordinates, website, Google Maps link and the Google Hotels entity id.offerrows — for every priced hotel, each booking source's rate: nightly, total for the stay, free-cancellation flag and deadline, the source's link, and for official sites the booking-engine URL with your dates already filled in. Optionally every room type and rate.statusrows — one per place or property and stay: how many hotels, how many priced, how many offers, any error. Never charged.
It is the data behind a Google Hotels price tracker, a hotel price monitoring workflow, a rate shopping tool or a rate parity check — without the SaaS subscription, and with the raw hotel price data in your own dataset.
Google Hotels price tracking with your own data
Google's built-in hotel price tracking emails you when a price moves, but it picks the sources, keeps the history and gives you no export. Scheduling this scraper gives you the same signal as data you own:
- Track a city or a shortlist daily. Schedule the run (Apify Console → Schedules, or the API) with relative dates such as
"checkIn": "30 days", "checkOut": "32 days": every run prices the stay 30 days out, forever. Each run appends rows withfetched_at, so the dataset becomes your hotel price history. - Price alerts. A Google Hotels price alert you control: connect the run to n8n, Make or Zapier through Apify's integrations and alert on
nightlybelow a threshold, or on a specificsourcedropping below the official site. - Rate calendars.
sweepDays: 6prices the same length of stay for each of the next seven check-in days in one run — a price calendar per hotel, or "which weekend is cheapest".
Google Hotels' own price history and price alerts stay inside Google; this is how you get the numbers out.
Rate parity and rate shopping for hotels
For revenue managers the offer rows are the point. One run answers, per property and stay: what is the official site charging, what is every OTA charging, which rate is refundable until when, and what is each source's stay total. That is a rate parity check across every channel Google lists, at the price of a few cents per hotel.
- Put your properties and your competitive set in
hotels(Google Hotels URLs — find them on google.com/travel/hotels — or theentity_idfrom an earlier run). No search is needed: one offers call per property and stay. - Use
offerLevel: "sources"(default) for one row per source with its lowest rate — the rate shopping view — orofferLevel: "rooms"for every room type and rate. - Sources are keyed by
source_id, and the property's own listing carriesofficial: true, so a parity breach is a one-line comparison: any row whereofficialis false andnightlyis below the official row.
The same rows serve a hotel competitor rate shopping tool, hotel price intelligence dashboards, OTA rate comparison and channel-manager checks.
Input
| Field | Meaning |
|---|---|
queries | Free-text places exactly as you would type them into Google Hotels: "hotels in Lisbon", "hotels near Times Square", "5-star hotels Bangkok Sukhumvit". Google's results are paged 20 at a time; the scraper pages on until maxHotels distinct hotels. |
hotels | Specific properties without a search: Google Hotels URLs (…/travel/hotels/entity/ChkI…) or entity tokens from an earlier run. One offers call per property and stay. |
checkIn, checkOut | YYYY-MM-DD, or relative to the run date for schedules: "30 days", "6 weeks", "+30d", today, tomorrow. Nights = the difference. Past check-ins are rejected before anything is fetched. |
sweepDays | Also price the same length of stay starting on each of the next N days (rate calendars). |
adults, childrenAges | Occupancy per room; prices scale exactly as on Google. |
currency, language, country | Any ISO currency for every price; Google UI language (hl); market (gl) — prices and available sources differ by market. |
maxHotels | Distinct hotels per place and stay, up to 200 (one list call per 20). |
includeOffers | Fetch every source's rate per hotel (one extra call per hotel). |
offerLevel | sources: one row per source, lowest rate (about 5–25 rows per hotel). rooms: every source × room × rate with room names and cancellation deadlines (about 50–100 rows per hotel). |
maxOffersPerHotel | 0 = every source; N = only the N cheapest rows per hotel (cost control). |
proxyConfiguration | Apify datacenter proxies work; keep the default. |
sessions, perIp | Parallel proxy sessions and requests per second per IP (defaults 4 and 0.5). |
Example: hotel prices in a city for a stay
{ "queries": ["hotels in Lisbon"], "checkIn": "2026-10-03", "checkOut": "2026-10-06", "adults": 2, "currency": "USD", "maxHotels": 60 }
Example: rate parity for your own properties, scheduled daily, always 30 days out
{ "hotels": ["https://www.google.com/travel/hotels/entity/ChkIhLCQwvjO2IYWGg0vZy8xMXE0bTZieDkyEAE"], "checkIn": "30 days", "checkOut": "32 days", "sweepDays": 6, "currency": "EUR", "offerLevel": "sources" }
Example: cheapest weekend in the next two months for a family
{ "queries": ["family hotels Orlando near Disney"], "checkIn": "2026-10-02", "checkOut": "2026-10-04", "sweepDays": 56, "adults": 2, "childrenAges": [5, 9], "currency": "USD", "maxHotels": 20, "includeOffers": false }
Output
hotel row (the Console's Hotels and Offers by source views show the same rows as tables; the dataset schema documents every field):
{ "type": "hotel", "query": "hotels in Lisbon", "check_in": "2026-10-03", "check_out": "2026-10-06", "nights": 3, "adults": 2, "children": 0, "currency": "USD","rank": 1, "name": "The Central House Lisbon Baixa", "hotel_id": "10088532857338925820", "entity_id": "ChkIg-b2ismUj7M1Gg0vZy8xMWg3MThreGg1EAE","stars": 2, "class_label": "2-star hotel", "rating": 4.3, "reviews": 727, "lat": 38.7131, "lng": -9.1368, "types": ["hostel"],"nightly": 81.81, "nightly_display": "$82", "total": 245, "total_display": "$245", "deal": "19% less than usual", "source": null,"website": "https://www.thecentralhousegroup.com/", "maps_url": "https://maps.google.com/?cid=3848859359889388291", "thumbnail": "https://lh3.googleusercontent.com/gps-cs-s/…","google_url": "https://www.google.com/travel/hotels/entity/ChkIg-b2ismUj7M1Gg0vZy8xMWg3MThreGg1EAE", "total_results": 15000, "fetched_at": "2026-08-25T14:03:11+00:00" }
offer row (one per source with offerLevel: "sources"; per room and rate with "rooms"):
{ "type": "offer", "name": "Hyatt Regency Lisbon", "entity_id": "ChoI4cjBy-KGurGyARoNL2cvMTFtdnFfdncydhAB", "check_in": "2026-10-03", "check_out": "2026-10-06", "nights": 3, "adults": 2, "children": 0, "currency": "USD","source": "Booking.com", "source_id": 184, "official": false, "room": null, "nightly": 569.35, "total": 1708.05, "max_guests": null,"free_cancel": null, "free_cancel_until": null, "link": "https://www.google.com/travel/lodging/clk?pc=…", "partner_url": "https://www.booking.com/hotel/pt/hyatt-regency-lisbon.html?checkin=2026-10-03&checkout=2026-10-06…", "lowest": true, "fetched_at": "2026-08-25T14:03:14+00:00" }
Rows with "lowest": true are each source's cheapest rate; official-site rows carry the hotel's booking engine URL with your dates in partner_url. A source is keyed by source_id — a name such as Holidu or Booking.com can appear twice for one property when Google lists both its official listing (official: true) and its marketplace rate. Properties given in hotels are answered from their offers page: the hotel row carries name, headline nightly rate and stay total; star class, rating and coordinates come from place searches only.
status row (never charged):
{ "type": "status", "query": "hotels in Lisbon", "hotel": null, "check_in": "2026-10-03", "check_out": "2026-10-06", "hotels": 25, "priced": 24, "offers": 310, "duplicates": 0, "offer_errors": 0, "error": null, "fetched_at": "2026-08-25T14:03:20+00:00" }
How much does it cost?
Pay per event, only for priced rows: a hotel row (a hotel with a price for your dates) and an offer row (one source's rate). Sold-out hotels, empty searches and status rows are free, and a hotel and stay is billed once per run even when overlapping searches return it twice. A city search of 60 hotels with source-level offers is a few hundred rows; a daily parity check of ten properties with seven check-in days is about 70 hotel rows plus their offers. Apify's platform usage for a run of that size is a fraction of a cent — the runs above cost $0.001–$0.003 in compute. The exact per-row prices are on this page's pricing tab, and maxOffersPerHotel caps the offer rows when you only need the cheapest few sources.
Google Hotels API or scraper: how this compares
Google has no public Google Hotels API for reading prices: its Hotel APIs (Hotel Prices, Hotel Ads, Book on Google) are partner feeds for hotels that send prices to Google. Reading prices back means a scraper or a SERP API vendor.
- SerpApi Google Hotels API, DataForSEO, SearchApi, Bright Data sell a Google hotel price API per search. They return the search page; per-source rates and room-level offers usually need a second product or are not exposed, and you pay per search whether or not it had results.
- This scraper returns hotels and every source's rate as flat rows, bills per priced row, handles paging to 200 hotels, occupancy including children's ages, any currency and market, relative dates for schedules, and property mode for your own hotels. It runs inside Apify, so scheduling, storage, webhooks and integrations come with it.
- Writing your own with Python ("scrape google hotels", "scrape hotel prices", "web scraping hotel prices"): Google Hotels renders prices through internal RPC calls, not HTML, and the payload formats change. The point of this actor is that someone keeps that working and reports failures as
statusrows instead of silent zeros.
If you searched for "Google Hotels API free" or a hotel price comparison API: there is a free tier on Apify, no API key from Google is needed, and empty results are never charged. As a hotel rates API it is one POST with the dates and a dataset of rows back.
How to use it from Python, JavaScript, curl, n8n, Make or an AI agent
Run it from the Apify Console with the form, or programmatically. Replace <TOKEN> with your Apify API token.
Python:
from apify_client import ApifyClientclient = ApifyClient("<TOKEN>")run = client.actor("kestrel/google-hotels-prices").call(run_input={"queries": ["hotels in Lisbon"], "checkIn": "2026-10-03", "checkOut": "2026-10-06", "adults": 2, "currency": "USD", "maxHotels": 40})rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())hotels = [r for r in rows if r["type"] == "hotel"]; offers = [r for r in rows if r["type"] == "offer"]cheapest = min((h for h in hotels if h["nightly"]), key=lambda h: h["nightly"])print(cheapest["name"], cheapest["nightly_display"], cheapest["total_display"])
JavaScript / Node.js:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<TOKEN>' });const run = await client.actor('kestrel/google-hotels-prices').call({ hotels: ['https://www.google.com/travel/hotels/entity/ChkIhLCQwvjO2IYWGg0vZy8xMXE0bTZieDkyEAE'], checkIn: '30 days', checkOut: '32 days', currency: 'EUR' });const { items } = await client.dataset(run.defaultDatasetId).listItems();const official = Math.min(...items.filter(x => x.type === 'offer' && x.official).map(x => x.nightly));const parityBreaches = items.filter(o => o.type === 'offer' && !o.official && o.nightly < official);console.log(parityBreaches.map(o => [o.name, o.source, o.nightly]));
curl:
curl -X POST "https://api.apify.com/v2/acts/kestrel~google-hotels-prices/run-sync-get-dataset-items?token=<TOKEN>" \-H "Content-Type: application/json" \-d '{"queries": ["hotels in Lisbon"], "checkIn": "2026-10-03", "checkOut": "2026-10-06", "maxHotels": 20, "includeOffers": false}'
- n8n, Make, Zapier: use the Apify node/app with this actor's id, or a webhook on run finished, then read the dataset — a hotel price tracker or alert flow is three nodes.
- AI agents and MCP: the actor is available through the Apify MCP server and Apify AI; the README, input schema and flat row types are written so an agent can ask "hotels in Lisbon under $150 from Oct 3 to 6 with free cancellation" and filter the rows.
- Google Sheets, BigQuery, Airtable: export the dataset from the run page or through Apify's integrations.
Is it legal to scrape Google Hotels prices?
The scraper reads publicly displayed prices — the same figures any visitor sees without logging in — and stores no personal data: rows describe hotels, sources and rates, not people. Collecting public pricing for analysis and monitoring is common practice in the hotel industry (every rate shopping tool does it), but terms of service and local law differ; check that your use complies, and use the data for your own analysis rather than republishing it as Google's.
Limits and honest notes
- A place search pages through Google's ranking 20 at a time up to
maxHotels(200); neighbourhood or landmark queries add coverage beyond that. - Prices are what Google Hotels shows for the market (
country) and currency you choose; whether taxes and fees are included follows Google's display rules for that market. Thetotalis the stay total Google shows. - Sources per hotel vary by market and day (typically 5–25 with US settings). Sold-out hotels appear as
hotelrows without a price and are not charged. - Google changes its internal formats occasionally; a daily canary run watches for that, the actor is rebuilt within days, and every run reports
statusrows so a failure is visible rather than a silent zero. - Google never fails a place search. An unrecognised or misspelt place is silently matched to somewhere else and answered with real hotels, which are delivered and billed like any other row. There is no signal in Google's response that says "I did not find that place", and a fuzzy-matched nonsense string can return a cluster as tight as a genuine region, so this cannot be detected reliably enough to refuse the run without also breaking legitimate broad searches like
"Portugal"or"California". Each placestatusrow therefore carriesspread_km— the median distance of the returned hotels from their centre. A city is single digits, a region tens, a country a few hundred; anything in the thousands almost certainly did not resolve. Above 500km the run logs a warning. Pass an exact place name or a Google Hotels entity URL when it matters, and checkspread_kmand each hotel'slat/lngbefore trusting a run.
FAQ
Does it need a Google Hotels API key or a Google account?
No. There is no public Google Hotels API for reading prices; the scraper uses the public results page through Apify's proxies. No login, cookies or API key.
Can I get hotel price history and price alerts from Google Hotels?
Google's own tracker keeps history and alerts inside Google. Schedule this scraper (daily, with relative dates) and every run appends dated rows to your dataset — that is your price history — and an Apify integration (n8n, Make, Zapier, webhook) turns a drop into an alert.
How is this different from Google's "Track hotel prices" feature?
Google's feature emails you about the listings it chooses to watch and does not let you pick sources or export data. This scraper returns every source's rate for the exact dates, occupancy and currency you set, as rows you own.
Which booking sites are covered?
Whatever Google Hotels lists for that property and market: Booking.com, Expedia, Hotels.com, Agoda, Trip.com, Priceline, Kayak, eDreams, Vio.com, the official site and dozens of regional OTAs. The source name and source_id come straight from Google.
Does it include taxes and fees?
It returns the nightly price and the stay total Google Hotels displays for your market. In some markets Google shows all-in prices, in others taxes are added later; set country to the market you sell in and compare like with like.
How many hotels can one run return?
Up to 200 per place search, or as many properties as you list in hotels, times the number of stays (sweepDays). A run stops cleanly when it reaches the spending limit you set on the run.
Why do prices differ from what I see in my browser?
Google prices depend on market, currency, occupancy, dates and sometimes the device. Match country, currency, adults, childrenAges and the dates, and compare the total for the stay rather than a headline nightly figure.
Can I use it as a hotel price scraper for Booking.com or Expedia specifically?
Yes for prices: each offer row names its source, so filtering source == "Booking.com" gives you Booking.com's rate per hotel and stay, and likewise for Expedia, Agoda or Hotels.com — without scraping each site separately. For reviews or room descriptions use a Booking.com scraper or Expedia scraper built for that site.
Is there a free tier?
Yes: Apify's free plan covers small runs, and this scraper never charges for a run that returns no priced rows.
Last verified working: 2026-08-29.
Related scrapers
Hotel prices are one side of a trip. These read the rest of it, and they share the same row shape, the same pay-per-delivered-row billing and the same scheduling story:
- Hotel Rate Parity Checker — the same comparison as one row per property and stay with the parity math done: cheapest and dearest source, spread, and which OTAs undercut the official site by how much.
- Google Flights Scraper — airfare for a route and date, with a cheapest-day sweep.
- Airbnb Scraper — Airbnb prices, availability calendars and occupancy.
- Airbnb Reviews Scraper — every guest review of an Airbnb listing, with translations.
- Agoda Reviews Scraper — Agoda hotel reviews with separate positives and negatives.
All of them bill per delivered row, never charge for rows a filter or a spending limit removed, and write an Apify dataset you can export to CSV, Excel or JSON.