# Google Hotels Scraper: Prices & Booking Sites (`automation_craft/google-hotels-scraper`) Actor

Google Hotels prices for your stay by place, Hotels or Maps link, id or hotel name, hotels and vacation rentals, no login. Rows: nightly and stay price, deal, class, rating, amenities. Add all booking sites with their own links, reviews, photos, 41 more markets. JSON, CSV, API; pay per property.

- **URL**: https://apify.com/automation_craft/google-hotels-scraper.md
- **Developed by:** [Automation Craft](https://apify.com/automation_craft) (community)
- **Categories:** Travel, E-commerce, Automation
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.06 / 1,000 properties

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### Google Hotels Scraper: Prices & Booking Sites

**Google Hotels scraper and API** for hotels and vacation rentals: search any city, area or landmark (or a place by its Google Maps feature id), paste Google Hotels search or property links and Google Maps place or share links, give property ids, or look up a hotel by its exact name. Every property comes with Google's lowest price for your stay, per night and for the whole stay, with and without taxes and fees, Google's deal labels, the hotel class, the rating with its histogram and review topics, amenities, check-in and check-out times, location scores, nearby places, coordinates, photos and the property's Google Hotels and Maps ids. Turn on **Property details** for every booking site Google lists with its price and the booking site's own link, the **Photo gallery**, and **Reviews** with Google's own sorts and filters.

No login, no cookies to give and no browser: the Actor reads Google Travel's own data service from Apify's network (included in the price), so the rows show the booking sites and prices a visitor in the US sees. Choose up to 10 countries a run out of 42 (the US and 41 others): each other country's own booking sites are read through Apify residential exits there. Google shows up to about 1,000 properties a search, and a free search row tells you whether a search was read to Google's end.

#### What you can do with it

- Rate shopping and price comparison: every booking site of a hotel for your dates with its price per night and stay total, free cancellation and the deadline, member prices, the cheapest, dearest and official site, and the spread between them.
- Track prices over dates: read every check-in day of the next weeks in one run (`dateWindowDays`, up to 60 days), or schedule a run with relative dates (`checkInDaysFromToday`, `nights`).
- Compare markets, currencies and devices: the same search with the booking sites of the UK, Germany, Japan or 38 more countries, in up to 10 currencies a run, on desktop or mobile.
- Build a list of a city's hotels or vacation rentals with Google's own filters (price band, class, rating, amenities, hotel types, brands and chains, free cancellation, special offers, eco certified; for rentals the rental type, bedrooms, bathrooms and rental amenities) and its four sorts.
- Collect the guest reviews Google shows (Google, Tripadvisor, Trip.com, Priceline and, for vacation rentals, the rental sites) by sort, source, a word or one of Google's review topics, for sentiment and quality work.
- Feed language models and notes: a Markdown summary of each property (free).

### How to use the Google Hotels Scraper

1. Open the Actor and type one or more places in **Places to search**, for example `Lisbon`, `Times Square, New York` or `resorts in Cancun`, or paste links into **Google Hotels or Google Maps links**, ids into **Property ids**, or names into **Hotel names**.
2. Pick **Property type** (hotels, vacation rentals, or both) and set the stay: **Check-in date** and **Check-out date**, or **Check-in, days from the run's day** and **Nights** (when you give neither: 14 days from the run's day, 2 nights), plus **Adults** (default 2) and **Children's ages**. A pasted Google Hotels search link keeps its own place, dates, guests, currency, filters and sort unless you set them here.
3. Choose **Currencies** (default USD), **Booking site markets (countries)** (default US), **Language** and **Device** if you need them, and any filters and **Sort**.
4. Set **Maximum properties (the run)** and **Maximum properties per search** (default 1,000), and turn on **Property details (every booking site)**, **Photo gallery**, **Reviews** or **Markdown summary** if you need them.
5. Click **Start**. Download the rows as JSON, CSV, Excel, XML or HTML, or read them through the Apify API.

### What data you get

One Property row per property and stay (`type: "property"`), one Review row per guest review when Reviews is on (`type: "review"`), and free rows: a search row per search (`type: "search"`), a review walk row per property (`type: "reviews"`), status rows for every miss (`type: "status"`) and one run summary (`type: "summary"`).

The same property is another row for another stay, currency, market, device or language. The Console's **Properties** view shows the main columns of the property rows, and the **Booking sites (Property details)** view the cheapest, official and spread columns.

#### Property row

| Field | What it holds | Filled (hotel rows) |
|---|---|---|
| `id`, `name`, `kind`, `url` | Google Hotels property id, name, `hotel` or `vacationRental`, the property's Google Hotels link | 100% |
| `checkIn`, `checkOut`, `nights`, `adults`, `childrenAges`, `currency`, `bookingSitesMarket`, `device`, `language` | the stay and the market the prices are for | 100% (children when given) |
| `position`, `search` | the place in Google's order and the search the row came from (query, text sent as `searchedAs`, view, the place Google resolved and its Maps feature id) | 98.1% (a lookup row has no position), 100% |
| `price.nightly`, `price.nightlyText`, `price.nightlyWithTaxes`, `price.nightlyWithTaxesText` | Google's lowest price per night, before and with taxes and fees | 78.9% (the rest: no price for the stay, `price.available: false`) |
| `price.stayTotal`, `price.stayTotalWithTaxes`, `price.stayBase`, `price.stayTaxes`, `price.stayFees` and their texts | the stay total and its parts | 78.9% |
| `price.deal` | Google's deal label, level and percent below usual | 18.6% |
| `hotelClass`, `hotelClassLabel` | star class and Google's label ("4-star hotel") | 74.2% |
| `rating`, `reviewCount`, `ratingHistogram` | Google rating out of 5, review count, reviews per star | 83.0% |
| `reviewAspects` | topics guests mention with mentions, positive and negative counts (the names `reviewsTopic` takes) | 79.4% |
| `amenities` | amenities with Google's code, name and whether offered | 95.5% |
| `latitude`, `longitude`, `countryCode`, `mapsFeatureId`, `mapsCid`, `googleCategories` | position, country, Maps ids and Google place categories | 99.9% to 100% |
| `website`, `checkInTime`, `checkOutTime` | the property's own site and its times | 88.2%, 95.4%, 95.0% |
| `description`, `highlights` | Google's short description and highlight lines | 68.0%, 13.5% |
| `locationScores`, `nearbyPlaces` | Google's location scores (overall, things to do, transit, airport access and more), places nearby with travel times | 100% |
| `ecoCertified` | true or false where Google says, else null | 98.8% |
| `thumbnail`, `photos` | the card's main photo and photos | 98.6% |
| `rental`, `featuredOffer`, `otherBookingSites` | vacation rentals: sleeps, bedrooms, beds, bathrooms, essentials, and the booking sites on the card with their own links | 100%, 27.8%, 95.2% of rentals |
| `address`, `phone`, `placeHierarchy` | on the list row for some places; always in Property details | 18.3%, 2.3%, 1.9% |
| `detailsStatus`, `details`, `markdown` | whether Property details were read, the details, the Markdown summary | as asked |

Measured on build 0.1.3 over the 43 runs of the real actor's platform test on 2026-11-06 (the final build reads these fields with the same code); the figures are for the hotel rows, and the `rental` line for the vacation rental rows, which carry no hotel class, amenities codes or hotel description: 1,807 hotel rows and 482 vacation rental rows with the US booking sites (cities in North America, Europe and Asia, one deep New York walk, rentals in Barcelona, Miami and Orlando).

#### Property details (add-on)

| Field | What it holds | Filled (219 records) |
|---|---|---|
| `details.bookingSites` | every booking site Google lists for the stay: `site`, `official`, `nightlyText`, `nightlyWithTaxesText`, `stayTotalText`, `stayTotalWithTaxesText` (and the numbers), `guests`, `freeCancellation`, `freeCancellationUntil`, `memberPrice`, `logo` and `bookingUrl` | 97.3% (18 sites a record on average) |
| `bookingSites[].bookingUrl` | the booking site's own link, read from Google's click link, never the click link | 100% of 3,952 sites |
| `bookingSites[].nightlyWithTaxesText`, `freeCancellation` (true), `memberPrice` | price with taxes and fees, a free cancellation offer, a member price | 86.4%, 13.0%, 2.2% of sites |
| `details.bookingSitesCount`, `details.allSiteNames` | how many sites, and their names | 97.3% |
| `details.cheapestOffer`, `details.dearestOffer`, `details.priceSpread` | cheapest and dearest stay total with taxes, and the spread | 97.3% |
| `details.officialSiteOffer` | the hotel's own site and its price | 75.8% |
| `details.sponsoredOffers`, `details.sponsoredRoomOffers` | sponsored offers and room boards (room names, rates, cancellation, beds), flagged and without their ad links | 92.7%, 93.6% |
| `details.priceInsight`, `details.cheaperDates` | Google's typical price range for the dates, its level and percentile; Google's "save if you stay" dates | 70.8%, 3.7% |
| `details.address`, `details.phone`, `details.placeId`, `details.mapsUrl` | address, phone, Google Maps place id and link | 100%, 98.2%, 100%, 100% |
| `details.reviewSources`, `details.reviewSummary`, `details.reviewSummaryNegative` | rating and count per review source, Google's review summaries | 98.6%, 84.0%, 61.2% |
| `details.amenitiesDetailed`, `details.photos`, `details.similarProperties`, `details.nearbyVacationRentals` | amenities by group, photos, similar hotels and rentals nearby | 98.2%, 100%, 97.3%, 100% |
| `details.neighbourhood`, `details.longDescription` | the neighbourhood text and the long description | 67.6%, 89.0% |
| `details.highlights`, `details.featuredIn`, `details.sustainabilityPractices`, `details.inclusivityLabels` | Google's highlights, "featured in" mentions, eco practices, inclusivity labels | 98.6%, 53.4%, 63.9%, 45.7% |

#### Photo gallery (add-on)

With Property details and **Photo gallery** on, `details.photoGallery` holds the property's gallery by category (At a glance, Amenities, Food and drink, Exterior, Bedroom, Bathroom, Interior), each photo with `url`, `width`, `height`, `category` and `source`, up to `maxPhotosPerProperty` (default 100), `details.photoCategories` gives Google's photo count and a thumbnail per category (Google's category 2, "Rooms" in Google's photo filters, comes with `category: null` in this version), and `details.photoGalleryStatus` says why it ended (`partial` when Google's pages ended first). A photo a Google user posted names that user in `source`.

#### Reviews (add-on)

| Field | What it holds | Filled (1,320 reviews) |
|---|---|---|
| `id`, `source`, `sourceId`, `rating`, `ratingScale`, `dateText`, `propertyId`, `propertyName`, `position` | the review's id, source, rating and scale, Google's relative date, the property | 100% |
| `text`, `textParts` | the review text as Google shows it | 67.3% |
| `ownerReply`, `ownerReplyDateText` | the property's reply | 44.7% |
| `tripTypeCode`, `travelGroupCode`, `subRatings` | trip type, travel group and ratings per aspect | 47.7%, 39.6%, 77.3% |
| `visitedText`, `photos`, `highlights`, `sourceReviewUrl` | the visit, the review's photos, highlight tags, the review on its source site | 22.3%, 16.8%, 27.1%, 6.1% |
| `author`, `authorUrl`, `authorPhoto` | the reviewer's name, Google profile link and photo, as Google serves them | null only when Google shows none |

The free review walk row per property (`type: "reviews"`) says how many reviews were delivered, the sort, source and filter used, and whether the walk was complete or stopped at your maximum.

#### Free search, status and summary rows

- Search row (`type: "search"`), one per search (a place, a stay, a currency, a market and a view): the query and the text sent, the place Google resolved and its Maps feature id, the filters and sort, Google's reported total (`totalReported`, capped by Google at 15,000), the properties met and delivered, repeats, skipped rows by reason, pages read and failed, sponsored rows left out, price statistics, and `status`: `complete` (Google's end or its reported total was reached), `depth_limit` (read to Google's depth of about 1,000) or `incomplete` with `stoppedBy` and the reason.
- A search Google answered with a free refusal says it in its search row's `status`: a place Google does not know (`place_not_found`) or places in two ways (`place_ambiguous`), a brand Google does not list for the place (`brand_not_offered`, with the brands it lists), dates Google does not price (`stay_not_offered`).
- Status rows (`type: "status"`) for every other miss, each free: an id of no property (`not_found`), a Maps place that is not a stay (`not_a_stay`), a property's other dates (`stay_not_offered`), a hotel name with no or several exact matches (`name_not_found`, `name_ambiguous`, with up to 8 candidates), a property or name Google did not answer (`not_read`), entries or links that could not be read (`entries_not_read`, `link_refused`, `stay_refused`), a Maps share link Google has no target for or did not answer (`link_not_found`, `link_not_read`), a search asked twice (`same_search`), a stay outside the window (`stays_out_of_window`), the charge limit (`charge_limit_reached`) and input the Actor cannot use (`invalid_input`).
- One run summary row (`type: "summary"`) with the run's counts, the events charged and the requests made.

#### Example row (shortened)

Values from a platform test run of 2026-11-05 (US booking sites); fields left out and long booking links cut where marked with `...`.

```json
{
  "type": "property",
  "id": "ChkIgOih8PGc04VTGg0vZy8xMWI4MXY0MmRyEAE",
  "kind": "hotel",
  "name": "Freehand Chicago",
  "url": "https://www.google.com/travel/hotels/entity/ChkIgOih8PGc04VTGg0vZy8xMWI4MXY0MmRyEAE?hl=en",
  "position": 1,
  "checkIn": "2026-11-19",
  "checkOut": "2026-11-21",
  "nights": 2,
  "adults": 2,
  "currency": "USD",
  "bookingSitesMarket": "US",
  "device": "desktop",
  "hotelClass": 4,
  "hotelClassLabel": "4-star hotel",
  "rating": 3.9,
  "reviewCount": 3250,
  "price": {
    "nightlyText": "$75",
    "nightlyWithTaxesText": "$88",
    "stayTotalText": "$150",
    "stayTotalWithTaxesText": "$176",
    "stayBase": 129.91406,
    "stayTaxes": 26.09375,
    "stayFees": 20,
    "deal": { "label": "19% less than usual", "level": "DEAL" }
  },
  "latitude": 41.892375699999995,
  "longitude": -87.6273243,
  "checkInTime": "3:00 PM",
  "checkOutTime": "12:00 PM",
  "mapsFeatureId": "0x880e2cad98bd799f:0x530b4ce71e087400",
  "search": { "query": "Chicago", "searchedAs": "hotels in Chicago", "kind": "hotels", "resolvedPlace": "Chicago" },
  "detailsStatus": "read",
  "details": {
    "address": "19 E Ohio St, Chicago, IL 60611",
    "bookingSitesCount": 21,
    "bookingSites": [
      { "site": "Freehand Chicago", "official": true, "nightlyText": "$167", "stayTotalWithTaxesText": "$396", "freeCancellation": true, "freeCancellationUntil": "Nov 18", "bookingUrl": "https://secure-hotel-tracker.com/gha/landing.php?..." },
      { "site": "Super.com", "official": false, "nightlyText": "$75", "stayTotalWithTaxesText": "$176", "freeCancellation": false, "bookingUrl": "https://www.super.com/travel/transition/?..." }
    ],
    "cheapestOffer": { "site": "Super.com", "stayTotalWithTaxes": 176, "stayTotalWithTaxesText": "$176" },
    "officialSiteOffer": { "site": "Freehand Chicago", "stayTotalWithTaxes": 396, "stayTotalWithTaxesText": "$396" },
    "priceSpread": 288,
    "priceInsight": { "typicalLowText": "$42", "typicalHighText": "$118", "level": "typical" }
  }
}
```

### How much does it cost to scrape Google Hotels?

You pay per row delivered (pay per event). Prices per 1,000 events:

| Event | Free | Bronze | Silver | Gold |
|---|---|---|---|---|
| Property | $0.08 | $0.073 | $0.066 | $0.057 |
| Search (once per search that delivered a property) | $0.70 | $0.64 | $0.58 | $0.50 |
| Property details (add-on; always for a property by link, id or name) | $1.40 | $1.28 | $1.16 | $1.00 |
| Review (add-on, only when on) | $0.42 | $0.38 | $0.35 | $0.30 |
| Photo (gallery add-on, only when on) | $0.14 | $0.128 | $0.116 | $0.10 |
| Local market page (only with a country other than US) | $5.60 | $5.10 | $4.60 | $4.00 |
| Local market run (only with a country other than US, once per run) | $15.00 | $15.00 | $15.00 | $15.00 |

Each run also pays a one time Actor start of $0.01 on every plan. Platinum and Diamond plans pay the Gold price. The Store pricing card shows these same prices per 1,000 events: "$0.08 / 1,000" on the Property row means one property costs 0.008 cents, and "$5.60 / 1,000" on the Local market page row means one local market page costs 0.56 cents (under a cent on every plan). A Local market page is one search page or one property record read through a residential exit in a country you chose, charged only when that read delivered a charged property; with Property details on, each property's record read there is one more Local market page. A run with another country also pays one Local market run of $0.015 ("$15.00 / 1,000" on the card) before its first local read; a run that reads only the US booking sites never pays either.

- 1,000 properties from five city searches cost $0.057 to $0.08 plus 5 Search events ($0.0025 to $0.0035) and the start fee: $0.0695 to $0.0935 for the run.
- 100 properties of one search with Property details cost $0.1062 to $0.1487 plus the start fee ($0.1162 to $0.1587).
- One hotel by id for 60 check-in days (`dateWindowDays: 60`): 60 Property and 60 Property details events, $0.0634 to $0.0888, plus the start fee ($0.0734 to $0.0988). A property by link, id or name is not a search and pays no Search event.
- One hotel by id with 500 reviews costs $0.151 to $0.211 (the Property, its Property details and 500 Review events) plus the start fee ($0.161 to $0.221).
- 100 London hotels with the UK booking sites (`countries: ["GB"]`), read in about 8 list pages (a page brings at most 18 hotels): $0.0057 to $0.008 for the properties, one Search, 8 Local market pages ($0.032 to $0.0448), the Local market run and the start fee: about $0.063 to $0.079. With Property details add 100 Property details and 100 more Local market pages: about $0.563 to $0.779.
- The same property and stay is charged once per run, even when two of your searches find it; the same review is charged once per run.
- Free: search rows, review walk rows, status rows and the summary, the Markdown summary, repeats, rows of the other view, rows beyond your maximums, every miss (a place not found, an id of no property, dates Google does not price, a name not matched exactly), Property details that did not answer for the stay (the row is delivered without the details charge) and local reads that delivered nothing. A run with no usable input charges only the start fee.
- Set a maximum cost per run in the Apify Console: the run stops at the first row it cannot pay and delivers no row unpaid, with a free row that says so.

### Input

Every setting is in the Console form with its own help text; API callers pass the same keys as JSON. What to read: `queries` (up to 500 places), `startUrls`, `propertyIds`, `hotelNames`, `propertyType`. Your stay: `checkIn` and `checkOut` or `checkInDaysFromToday` and `nights` (up to 330 days ahead, up to 30 nights), `dateWindowDays` (1 to 60), `adults` (1 to 10), `childrenAges` (up to 6 children), `currencies` (up to 10), `countries` (up to 10 of 42), `language` (30 languages), `device`. Filters and sort (Google's own, checked on every page Google answers): `sortBy`, `minPrice`, `maxPrice`, `minRating`, `hotelClass`, `amenities`, `hotelTypes`, `brands`, `freeCancellation`, `specialOffers`, `ecoCertified`, and for vacation rentals `minBedrooms`, `minBathrooms`, `rentalTypes`, `rentalAmenities`. Limits and add-ons: `maxItems`, `maxItemsPerSearch` (default 1,000, at most 1,080), `includeDetails`, `maxPropertiesWithDetails`, `includePhotoGallery`, `maxPhotosPerProperty`, `includeReviews`, `maxReviewsPerProperty` (default 20, at most 5,000), `reviewsSort`, `reviewsSource`, `reviewsQuery`, `reviewsTopic`, `reviewsTopicSentiment`, `includeMarkdown`, `maxConcurrency` (1 to 3), `proxyConfiguration`.

#### Example inputs

A city's 4 and 5 star hotels with a pool and free cancellation, cheapest first:

```json
{ "queries": ["hotels in Paris"], "checkInDaysFromToday": 35, "nights": 2, "hotelClass": ["4", "5"], "minRating": "4", "amenities": ["pool"], "freeCancellation": true, "sortBy": "lowestPrice", "maxItems": 100 }
```

Vacation rentals for a family of four:

```json
{ "queries": ["Barcelona"], "propertyType": "vacationRentals", "checkInDaysFromToday": 40, "nights": 3, "adults": 2, "childrenAges": [6, 9], "minBedrooms": 2, "rentalTypes": ["apartment"], "maxItems": 50 }
```

Every booking site of known hotels, by Google Hotels link, Google Maps place id and name, with the photo gallery:

```json
{ "startUrls": ["https://www.google.com/travel/hotels/entity/ChcI_PjctYHq-vxnGgsvbS8wMTJ2eTAychAB/prices?hl=en"], "propertyIds": ["ChIJlV9O0UtawokRXyLCJky7XRc"], "hotelNames": ["The Ritz London"], "checkInDaysFromToday": 45, "nights": 2, "includeDetails": true, "includePhotoGallery": true, "maxPhotosPerProperty": 30 }
```

One hotel's prices for 30 check-in days in two currencies:

```json
{ "propertyIds": ["ChUIksaK9_ij5_kYGgkvbS8wNjJ3YzIQAQ"], "checkInDaysFromToday": 20, "nights": 1, "dateWindowDays": 30, "currencies": ["USD", "EUR"] }
```

The UK booking sites of Edinburgh hotels in pounds, on a phone:

```json
{ "queries": ["hotels in Edinburgh"], "countries": ["GB"], "currencies": ["GBP"], "device": "mobile", "maxItemsPerSearch": 50, "includeDetails": true }
```

#### Places, links and names

A place is searched as "hotels in <place>" unless the text names a kind of stay ("resorts in Cancun"); the search row shows the text sent (`searchedAs`) and the place Google resolved. Add the country when a name is shared, or give the place's Google Maps feature id (`0x47e66e1f06e2b70f:0x40b82c3688c9460` is Paris). Property ids may be Google Hotels ids, Google Maps place ids (`ChIJ...`), Maps feature ids or Maps CIDs. A hotel name is looked up only when Google lists exactly one hotel of exactly that name; otherwise a free row lists the closest names and their ids. A property found by link, id or name always carries its Property details.

#### Personal data

A review's author name, Google profile link and photo, and the name of a Google user who posted a gallery photo, are delivered as Google serves them on every run, whatever `includePersonalData` says (the setting is still accepted so saved inputs keep working, and it has no effect). Review texts, owner replies, highlight quotes and the photos a reviewer attached are delivered as Google serves them too, and `sourceReviewUrl` links to the review on its own site. Google's vacation rental answers carry no host name. You are responsible for a lawful use of personal data, GDPR included.

### What this Actor does not do

- No room level offers apart from Google's sponsored room boards: every room board in a Google Hotels record is an ad, and the other offers carry no room name. The sponsored boards are delivered flagged, without their ad links.
- No rooms setting: Google Hotels prices a stay for the guests (adults and children), never per room.
- No autocomplete with property ids: Google's suggestions return search texts only. To turn a hotel name into its id, use `hotelNames`.
- No exact review dates: Google shows relative dates only ("3 weeks ago").
- No highest price or distance sort: Google has neither (its four orders are relevance, lowest price, highest rating and most reviewed). Such an order would need the whole list read before the first row is billed: 100 rows by highest price of a big city mean reading its whole list (a measured walk of New York to Google's depth cost USD 0.0075) for USD 0.0062 of events at Gold, below cost. Sort the delivered rows yourself.
- No booking sites as seen from China: Google does not answer through exits in China (3 of 3 tries; Hong Kong works and is in `countries`).
- No pace or session settings beyond `maxConcurrency` (1 to 3 parallel requests): the pace is fixed at about one call a second per exit, the pace Google answered 354 of 354 calls at; a refused call is asked again through a residential exit at about USD 0.0005 a call, nine times the price of a property row, so a faster pace is not offered.
- No Google click links: the booking site's own link is given instead (Google's click links are session links that expire).
- No price history, no "only new rows since the last run" memory, no change alerts and no monitor: schedule the Actor and compare the rows in your own sheet.
- No login, member or signed in prices beyond the member prices Google shows any visitor, and no booking.
- Prices are what a visitor from the US sees by default; another country's booking sites need `countries` (residential exits, the Local market events). Reviews and photos do not depend on the market.
- Google shows up to about 1,000 properties a search, hotels and vacation rentals together, even when it reports 15,000; a bigger place needs filters or smaller areas, and the search row says when a search stopped at that depth.
- A stay starts at most 330 days ahead and lasts at most 30 nights. A property found by link, id or name is that property for your stay: search filters do not filter it, and search settings without a search refuse the run.
- Work that earns nothing has a limit: a long list of places, ids or names Google does not know stops on that limit, and the rest is counted as not reached in the free summary row (nothing is charged for it).

### FAQ

#### Is it legal to scrape Google Hotels?

This Actor reads only what Google Hotels shows any visitor without a login and never opens Google's booking click links or ad links. Google's terms restrict automated access that goes against its robots.txt rules; whether and how you use the data is your decision and responsibility.

#### Does Google Hotels have an API?

Google's hotel APIs are for hotels and their connectivity partners: they send prices, content and booking links to Google and manage their Hotel Center accounts. They do not return Google Hotels results to read. This Actor works like that missing API: send a JSON input through the Apify API and read the properties, booking sites and reviews as JSON.

#### Where does Google Hotels get its prices, and why do they change by country?

From Google's partners: hotel owners, online travel agencies, metasearch sites and other travel providers. Which sites Google lists and at what price depends on the visitor's country and device, so by default the rows show the US booking sites; set `countries` to read up to 10 of 42 countries a run (any other than US through Apify residential exits there, the Local market events) and `device` to mobile for the phone set.

#### How many hotels can I get from one Google Hotels search?

Up to about 1,000 properties a search, hotels and vacation rentals together, even when Google reports 15,000. The free search row says whether the walk reached Google's end or its depth limit; to read further, split the place with filters (a price band, a class, a property type) or a smaller area.

#### Can I scrape Google Hotels reviews?

Yes, with the Reviews add-on: the reviews Google shows (Google, Tripadvisor, Trip.com, Priceline and, for vacation rentals, the rental sites; `reviewsSource` picks one of the first four), up to 5,000 a property, newest first or by most helpful, highest or lowest rating, filtered by source, by a word (Google's review search) or by one of Google's review topics. Google shows relative dates only ("3 weeks ago"), and each review carries the reviewer's name, profile link and photo as Google shows them.

#### Why does this Actor run with limited permissions?

It needs nothing beyond its own run storage (the dataset it writes and its own key-value store, where it keeps a marker for a restarted run), so it runs with Apify's limited permissions: it cannot read or change anything else in your account.

### Use it through the API

```bash
curl -X POST "https://api.apify.com/v2/acts/automation_craft~google-hotels-scraper/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"queries": ["Lisbon"], "checkInDaysFromToday": 30, "nights": 2, "currencies": ["EUR"], "maxItems": 200}'
```

```python
from apify_client import ApifyClient
client = ApifyClient("<YOUR_TOKEN>")
run = client.actor("automation_craft~google-hotels-scraper").call(run_input={"queries": ["Rome"], "checkInDaysFromToday": 14, "nights": 2, "includeDetails": True, "maxItems": 50})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row)
```

The Actor also runs from Apify's MCP server for AI agents, and from Make, Zapier and n8n through Apify's integrations.

### Changelog

- 0.1 (2026-11-06): first version.

### More data tools by Automation Craft

- [Booking.com Scraper: Hotel Prices and Availability](https://apify.com/automation_craft/booking-scraper)
- [Agoda Scraper: Hotel and Home Prices, Availability](https://apify.com/automation_craft/agoda-scraper)
- [Airbnb Scraper: Airbnb Data, Prices, Calendar](https://apify.com/automation_craft/airbnb-scraper)
- [Zillow Scraper: Homes for Sale, Rent and Sold](https://apify.com/automation_craft/zillow-scraper)
- [Realtor.com Scraper: Homes for Sale, Rent & Sold](https://apify.com/automation_craft/realtor-com-scraper)
- [Idealista Scraper: Spain, Italy, Portugal, France](https://apify.com/automation_craft/idealista-scraper)
- [Google Trends API & Scraper: Trending Searches](https://apify.com/automation_craft/google-trends-scraper)

# Changelog

This Actor's version history is a separate document: https://apify.com/automation_craft/google-hotels-scraper/changelog.md

# Actor input Schema

## `queries` (type: `array`):

Cities, areas or landmarks, one per entry, such as "Lisbon" or "Times Square, New York", searched as "hotels in <place>" unless the text names a kind of stay ("resorts in Cancun"). Add the country when a name is shared, or give the place's Google Maps feature id ("0x47e66e1f06e2b70f:0x40b82c3688c9460" is Paris). A place Google does not know is a free row. Up to about 1,000 properties a place (Google's depth).

## `startUrls` (type: `array`):

Links copied from Google: a Google Hotels search (google.com/travel/search?...), it keeps its own place, dates, guests, currency, filters and sort unless you set them below; a Google Hotels property page (google.com/travel/hotels/entity/...); a Google Maps place link of a hotel, or a Maps share link (maps.app.goo.gl).

## `propertyIds` (type: `array`):

Google Hotels property ids ("ChUI..."), Google Maps place ids ("ChIJ..."), Maps feature ids ("0x..:0x..") or Maps CIDs (digits or "0x.."). Each is read from its property record, so its row always carries the Property details.

## `hotelNames` (type: `array`):

Hotel names, such as "The Ritz London". A name is looked up only when Google lists exactly one hotel of exactly that name; otherwise a free row lists the closest names and their ids.

## `propertyType` (type: `string`):

Hotels (the default), vacation rentals, or both (each place is read twice, once per view).

## `checkIn` (type: `string`):

YYYY-MM-DD, at most 330 days ahead (Google Hotels prices no stay further out). Give it with "checkOut", or use the relative dates below. Neither given: 14 days from the run's day, 2 nights (a pasted search link keeps its own dates).

## `checkOut` (type: `string`):

YYYY-MM-DD, after the check-in date, at most 30 nights later.

## `checkInDaysFromToday` (type: `integer`):

Relative dates for scheduled runs: the check-in this many days after the run's day (UTC), 0 to 330.

## `nights` (type: `integer`):

Length of the stay with relative dates, 1 to 30.

## `dateWindowDays` (type: `integer`):

Read every check-in day from the check-in date on, this many days in a row (1 to 60), each with the same number of nights: one search or lookup per day, to compare prices across dates. Each day is its own search, charged as one.

## `adults` (type: `integer`):

Adults, 1 to 10 (default 2). Google Hotels prices a stay for the guests; it has no rooms setting.

## `childrenAges` (type: `array`):

One age per child, 0 to 17, at most 6 children.

## `currencies` (type: `array`):

Three letter currency codes (default USD). Several currencies read every search once per currency, charged as one search each.

## `countries` (type: `array`):

The country whose booking sites and prices Google shows (default US, read from Apify's own network). Another country is read through Apify residential exits in that country and adds the Local market run and Local market page events. Several countries read every search once per country.

## `language` (type: `string`):

The language of names and descriptions (default English).

## `device` (type: `string`):

Desktop (default) or mobile: Google shows a phone another booking site set and other prices.

## `sortBy` (type: `string`):

Google's own order: relevance (default), lowest price, highest rating or most reviewed. A sorted list holds fewer properties than the relevance list (Google keeps priced properties only).

## `minPrice` (type: `integer`):

Per night before taxes and fees, in the search's currency (Google's own price filter).

## `maxPrice` (type: `integer`):

Per night before taxes and fees, in the search's currency (Google's own price filter).

## `minRating` (type: `string`):

3.5+, 4+ or 4.5+ (Google's rating filter).

## `hotelClass` (type: `array`):

Hotels: 2 to 5 stars, several at once.

## `amenities` (type: `array`):

Hotels: every amenity chosen must be offered (Google's own amenity filter).

## `hotelTypes` (type: `array`):

Hotels: boutique hotels, resorts, hostels, B\&Bs and the other types Google lists.

## `brands` (type: `array`):

Hotels: brand or chain names exactly as Google Hotels lists them for the place ("Hilton Honors", "Marriott Bonvoy", "Hampton by Hilton"). A chain includes all its brands. A name Google does not list for the place makes that search a free row listing the brands it does list. Not with hotel types (Google applies none to a brand search).

## `freeCancellation` (type: `boolean`):

Hotels: only properties with a free cancellation offer for the stay.

## `specialOffers` (type: `boolean`):

Hotels: only properties with a deal for the stay.

## `ecoCertified` (type: `boolean`):

Hotels: only properties with an eco certification.

## `minBedrooms` (type: `integer`):

Vacation rentals: 1 to 5 or more.

## `minBathrooms` (type: `integer`):

Vacation rentals: 1 to 5 or more.

## `rentalTypes` (type: `array`):

Vacation rentals: apartments, houses, villas, cottages or other.

## `rentalAmenities` (type: `array`):

Vacation rentals: every amenity chosen must be offered.

## `maxItems` (type: `integer`):

The most property rows the whole run delivers. Empty: no limit beyond Google's depth and the searches' own maximum.

## `maxItemsPerSearch` (type: `integer`):

The most property rows one search (one place, stay, currency, market and view) delivers, 1 to 1,080 (default 1,000; Google shows about 1,000 a search).

## `includeDetails` (type: `boolean`):

Adds each property's full record to its row: every booking site with its price per night and stay total with and without taxes, free cancellation and deadline, member prices and the site's own booking link, the cheapest site and the official site, sponsored room offers, the price insight for the dates, address, phone, every amenity, review sources, neighbourhood, similar properties and photos. Charged per property as Property details.

## `maxPropertiesWithDetails` (type: `integer`):

With Property details: the most search rows of the run that get them (the rows after it are delivered without details and without the details charge). A property by link, id or name always carries its record. Empty: every row.

## `includePhotoGallery` (type: `boolean`):

With Property details: adds the property's photo gallery by category, up to the maximum below. Charged per photo.

## `maxPhotosPerProperty` (type: `integer`):

1 to 1,000 (default 100).

## `includeReviews` (type: `boolean`):

Adds guest reviews of each delivered property as their own rows (the reviews Google shows: Google, Tripadvisor, Trip.com, Priceline and, for vacation rentals, the rental sites). Charged per review.

## `maxReviewsPerProperty` (type: `integer`):

1 to 5,000 (default 20).

## `reviewsSort` (type: `string`):

Newest (default), most helpful, highest or lowest rating.

## `reviewsSource` (type: `string`):

Only reviews of one source (empty: every source).

## `reviewsQuery` (type: `string`):

Only reviews that mention this word or phrase (Google's review search), such as "breakfast".

## `reviewsTopic` (type: `string`):

Only reviews about one topic, by Google's own topic filter (by meaning, not only the word): a topic name as the property rows list it in "reviewAspects", such as "Breakfast", "Location" or "Food and Beverage". Not with "Reviews mentioning".

## `reviewsTopicSentiment` (type: `string`):

All mentions of the topic (default), or only the positive or only the negative ones.

## `includeMarkdown` (type: `boolean`):

Adds a Markdown summary of each property row (its facts, prices and booking sites), ready for notes and language models. Free.

## `includePersonalData` (type: `boolean`):

All public data is always delivered and this setting has no effect (kept so saved inputs keep working).

## `maxConcurrency` (type: `integer`):

Requests in parallel, 1 to 3 (default 3).

## `proxyConfiguration` (type: `object`):

Apify's own network by default, included in the price: the run's own address first, Apify's datacenter proxy as the fallback. You may give your own proxy links instead.

## Actor input object example

```json
{
  "queries": [
    "Lisbon"
  ],
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `items` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "queries": [
        "Lisbon"
    ],
    "maxItems": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation_craft/google-hotels-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "queries": ["Lisbon"],
    "maxItems": 10,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("automation_craft/google-hotels-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": [
    "Lisbon"
  ],
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call automation_craft/google-hotels-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation_craft/google-hotels-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/O0pl2mwodI2Td6M6K/builds/xbbSxsaYCSksSNIWg/openapi.json
