# Google Hotels Scraper: Prices, Ratings and Stars for Your Dates (`cozybit/google-hotels-scraper`) Actor

Google Hotels scraper without a browser: nightly and total prices for your dates, guests and currency, plus stars, rating, reviews, coordinates and website for every property Google lists, across all result pages. Prices checked against your dates. Trial: 0.01 USD per 1,000 hotels until 30 Nov 2026.

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

## Pricing

$0.01 / 1,000 hotel properties

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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, ratings and hotel details for your dates

Get hotel and vacation-rental prices from Google Hotels as clean records, without a browser and without a Google account. For each search (a city, area or "hotels near ...") and your dates and guests, you get every property Google lists:

- **Price**: the lowest nightly price Google shows for your dates and the total for the stay, in the currency you choose.
- **Quality**: hotel class (stars), Google rating and number of reviews.
- **Details**: coordinates, website, check-in and check-out times, short description, thumbnail, and links to the Google Hotels and Google Maps entries.
- Optional **booking sites**: every site Google lists for the hotel (Booking.com, Expedia, the hotel's own site and others) with its nightly and total price and a link.
- Optional **single-hotel mode**: one hotel across up to 60 consecutive check-in dates, one row per night.
- Optional **filters**: free cancellation, price range, minimum hotel class and minimum guest rating, applied by Google itself, so you only pay for hotels that match.

Typical uses: price monitoring for a city or competitor set, rate-parity checks across booking sites, revenue management for one hotel, travel-deal research, market studies of a destination.

Prices include all platform costs: you pay per hotel returned and nothing for proxies or compute.

### Input

| Field | What it does | Default |
|---|---|---|
| Search queries | 1-100 searches, such as `Paris`, `hotels in Paris`, `hotels near Times Square`, a hotel's name or its `property_token` | required |
| Check-in / check-out date | `YYYY-MM-DD`, or a time from the run date such as `3 weeks` or `23 days` (handy for scheduled runs); up to 330 days ahead, 1-30 nights | 14 days from today, one night |
| Consecutive check-in dates | 1-60: search each query for this many check-in dates in a row, same stay length | 1 |
| Adults | 1-6 | 2 |
| Children's ages | Up to 4 ages, 0-17 (experimental, see Limits) | none |
| Currency | Any currency Google supports, such as `USD`, `EUR`, `GBP`, `INR`, `JPY` | `USD` |
| Search country | The Google market to search from, such as `US`, `DE`, `GB` | `US` |
| Maximum properties per query | 1-500; the actor follows Google's result pages | 20 |
| Include booking sites | Add each hotel's booking sites with prices and links | off |
| Free cancellation only | Google's free-cancellation filter | off |
| Minimum / maximum nightly price | Whole numbers in your currency | none |
| Minimum hotel class | 2-5 stars; that class and above | any |
| Minimum guest rating | 3.5+, 4.0+ or 4.5+ | any |

Example: up to 100 properties in Paris for two adults, three nights in March, prices in euros:

```json
{
  "queries": ["Paris"],
  "checkIn": "2027-03-12",
  "checkOut": "2027-03-15",
  "adults": 2,
  "currency": "EUR",
  "country": "FR",
  "maxResultsPerQuery": 100
}
```

Example: a scheduled daily check of two nights in Paris three weeks ahead; the dates move with each run:

```json
{ "queries": ["hotels in Paris"], "checkIn": "3 weeks", "checkOut": "23 days" }
```

Example: 4- and 5-star hotels in Paris rated 4.5 or better, up to 250 USD a night:

```json
{ "queries": ["hotels in Paris"], "checkIn": "2027-03-12", "checkOut": "2027-03-14", "minStars": 4, "minRating": "4.5", "maxPrice": 250, "maxResultsPerQuery": 40 }
```

Example: one hotel, one-night stays for each of the next 30 check-in dates, with every booking site's price:

```json
{ "queries": ["Crowne Plaza Paris Republique"], "checkIn": "2027-03-01", "checkOut": "2027-03-02", "checkInDays": 30, "includeBookingSites": true }
```

### Output

One record per property. Example (shortened thumbnail URL):

```json
{
  "query": "Orlando", "position": 4, "page": 1, "status": "ok", "error": null,
  "name": "Universal Endless Summer Resort - Dockside Inn and Suites",
  "type_text": "3-star hotel", "stars": 3, "rating": 4.4, "review_count": 25901,
  "price_per_night": 331, "price_per_night_text": "$331", "total_price_text": "$662", "currency": "USD",
  "check_in": "2026-11-13", "check_out": "2026-11-15", "adults": 2, "children_ages": [],
  "latitude": 28.4597363, "longitude": -81.462522, "country_code": "US",
  "website": "https://www.universalorlando.com/web/en/us/places-to-stay/universals-endless-summer-resort-dockside-inn-and-suites",
  "check_in_time": "4:00 PM", "check_out_time": "11:00 AM",
  "description": "Relaxed resort hotel with a food court, outdoor pools & sand beaches, plus free theme park shuttles.",
  "thumbnail_url": "https://lh3.googleusercontent.com/...",
  "property_token": "ChkIvd-lusSMvMYJGg0vZy8xMWgzbDBseGw1EAE",
  "google_hotels_url": "https://www.google.com/travel/hotels/entity/ChkIvd-lusSMvMYJGg0vZy8xMWgzbDBseGw1EAE",
  "maps_feature_id": "0x88e77f436ca4cc19:0x98cf06447496fbd",
  "source_url": "https://www.google.com/travel/search?q=Orlando&hl=en&gl=us&curr=USD&ts=...",
  "scraped_at": "2026-10-30T17:37:01.936Z"
}
```

- `price_per_night` is the lowest nightly price Google shows across booking sites, before Google's rounding (`price_per_night_text` is the rounded label). `total_price_text` is Google's label for the whole stay. Whether taxes are included follows Google's display for the search country.
- Fields Google does not show for a property are `null`; for example vacation rentals often have no stars, and a sold-out property has no price.
- `property_token` identifies a property across runs and is the key for price monitoring. You can also use it as a search query to get exactly that hotel.
- `booking_sites` is `null` unless you turn on "Include booking sites". Then it lists each site in Google's order:

```json
"booking_sites": [
  { "site": "Crowne Plaza Paris - Republique by IHG", "price_per_night": 218.98, "total_price": 437.97, "is_official": true,
    "link": "https://www.google.com/travel/lodging/clk?pc=...&pcurl=https://www.ihg.com/..." },
  { "site": "Booking.com", "price_per_night": 223.07, "total_price": 446.15, "is_official": false, "link": "https://www.google.com/travel/lodging/clk?..." }
]
```

`is_official` marks the hotel's own website. `link` is Google's click-through link to that site's offer; links expire. A hotel without offers for your dates, such as a sold-out one, has an empty list. If one hotel's booking sites cannot be read, the hotel is still returned, with `booking_sites: null` and the reason in `booking_sites_error`.

- **Single hotel:** a query with a hotel's name or `property_token` returns that one hotel. With "Consecutive check-in dates" above 1 you get one row per check-in date, each with its own `check_in` and `check_out`.
- Records keep the same field names in format v1; any future change will be announced here first.

`status: "no_data"` means Google listed no properties for that search. `status: "error"` means the search failed after all retries; `error` says why. You never pay for `no_data` or `error` records. A run summary (`RUN_SUMMARY`) is saved in the run's key-value store.

### Use it from code

Get your API token in Apify Console under **Settings > API & Integrations**. Each example runs the actor, waits for it to finish and prints the hotels.

Python (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("cozybit/google-hotels-scraper").call(run_input={
    "queries": ["hotels in Paris"],
    "checkIn": "2027-03-12",
    "checkOut": "2027-03-15",
    "currency": "EUR",
    "country": "FR",
})
for hotel in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(hotel["name"], hotel["price_per_night"], hotel["rating"])
```

JavaScript (`npm install apify-client`):

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

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('cozybit/google-hotels-scraper').call({
    queries: ['hotels in Paris'],
    checkIn: '2027-03-12',
    checkOut: '2027-03-15',
    currency: 'EUR',
    country: 'FR',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const hotel of items) console.log(hotel.name, hotel.price_per_night, hotel.rating);
```

HTTP API, one request that runs the actor and returns the records as JSON (for runs up to 5 minutes; use the clients above for longer ones):

```bash
curl -X POST "https://api.apify.com/v2/acts/cozybit~google-hotels-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>" -H "Content-Type: application/json" \
  -d '{"queries": ["hotels in Paris"], "checkIn": "2027-03-12", "checkOut": "2027-03-15", "currency": "EUR", "country": "FR"}'
```

To track prices over time, save the input as a task in Apify Console and add a schedule; relative dates such as `"checkIn": "3 weeks"` keep each run looking the same distance ahead.

### Pricing

**Trial price until 30 November 2026:** 0.01 USD per 1,000 hotels (the lowest price Apify allows). From 1 December 2026 this scraper costs 2.50 USD per 1,000 hotels. Apify notifies all users before a price change.

You pay per property returned; platform usage (compute and proxies) is included.

| Event | Price |
|---|---|
| Hotel (one property with its price for your dates) | 2.50 USD per 1,000 (0.0025 USD each) |

Booking sites and single-hotel mode are included in the hotel price during the trial; we will announce any separate price here before it applies.

Worked examples:

- One city, the first 20 properties: 20 hotels = **0.05 USD**.
- 10 cities, 100 properties each: 1,000 hotels = **2.50 USD**.
- Daily price monitoring of 50 properties for 30 days: 1,500 hotels = **3.75 USD**.

To cap spending, set a maximum cost per run in the run options; the actor stops cleanly when it is reached.

### Free Apify plan

On the free Apify plan a run returns at most **20 hotels**. When the limit is reached the run finishes successfully with the status message "Free Apify plan limit reached"; everything collected so far is in the dataset. Any paid Apify plan removes the limit.

### Reliability

In 36 test runs on the Apify platform (18 cities, 5 countries and currencies, check-in 3-180 days ahead, 1-4 nights), **every search returned properties** (1,428 in total) and Google limited no IP. The median run took 11 seconds. All 94 hotels requested with booking sites got their list. With filters on (Paris, London, New York, Rome, Berlin), all 227 returned hotels met every star, rating and price filter.

Prices are Google's own numbers: every hotel that also appeared in another Google Hotels scraper's results had the same nightly price to the cent, the same rating and the same review count. Against the most-used booking-site scraper on one Paris hotel, we returned 97 site offers to its 95, with 91 of the 93 shared offers priced within 1 USD of each other, and finished in 9.5 s against its 12.3 s.

How it stays reliable: the actor reads the data Google embeds in its result page instead of driving a browser, sends a few paced requests per IP and switches to a new IP when Google limits one. Every property is checked against your dates and currency, so a page where Google ignored your request becomes a clear error instead of wrong prices. If Google changes its page format, the run fails with a message naming the changed part rather than returning an empty or wrong dataset.

### Limits

- **Address and phone** are not included: Google leaves them out of searches with dates, and fetching each hotel's page would multiply the cost.
- **Children's ages** are experimental: the request includes them, but Google's response does not confirm them, so check prices for family searches.
- Prices are what Google shows at the time of the run and change often.
- **Filters** apply to city and area searches, not to single-hotel or `property_token` queries. Free cancellation is Google's filter; check the terms of the offer you book.
- **Booking sites** depend on Google's partners for the search country, so the list differs by market. For city searches, they add one request per hotel: 30 Paris hotels with booking sites took about 1.5 minutes.
- Up to 500 properties per search and 100 searches per run. Google itself usually stops after a few hundred properties per search.
- Google Hotels has no official public API; when Google changes its site the actor may fail until it is updated.

### Related actors

- [Google Hotels Booking-Site Prices](https://apify.com/cozybit/google-hotels-booking-prices): every booking site's price for one hotel over up to 60 check-in dates, one row per site.
- [Google Flights Scraper](https://apify.com/cozybit/google-flights-scraper): flight prices, schedules, bags and amenities for any route and date.
- [Google Flights Fare Calendar](https://apify.com/cozybit/google-flights-fare-calendar): the cheapest fare for every day over up to 180 days.

### Support

Report problems and feature requests on the actor's **Issues** tab, ideally with the run link.

# Actor input Schema

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

Enter 1-100 non-empty searches, such as Paris, hotels in Paris, a hotel's name or its property_token. A full property_token goes directly to that hotel; a name that Google resolves to one hotel is reused across dates. Spaces and duplicate queries are removed.

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

YYYY-MM-DD or a relative date such as 3 weeks, from today through 330 days ahead (UTC). Use a whole number of days, weeks, months or years. Both relative dates count from the run date, not from check-in. Empty means 14 days from today.

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

YYYY-MM-DD or a relative date such as 23 days, giving 1-30 nights after check-in. Use a whole number of days, weeks, months or years. Both relative dates count from the run date (UTC), not from check-in: 3 weeks and 23 days give a two-night stay. Empty means one night after check-in.

## `checkInDays` (type: `integer`):

Search 1-60 consecutive check-in dates, starting at checkIn, keeping the same stay length for each. For one hotel, give its name or property_token and set this to get one row per night. The last check-in must be within 330 days. City searches return hotels for every date. Free Apify plans return at most 20 hotel records across all queries and dates.

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

Number of adults, from 1 to 6.

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

Up to four ages, each 0-17. The child traveller request encoding is unverified; Google may ignore it. Leave empty for verified adult-only searches.

## `currency` (type: `string`):

Three-letter uppercase currency code, such as USD, EUR, GBP, INR or JPY. A returned currency mismatch is reported as an error.

## `country` (type: `string`):

Two-letter uppercase country code. Sets Google's market (gl) and, for residential proxies only, the proxy country. This is not the destination city. Datacenter and custom proxies retain their own routing.

## `maxResultsPerQuery` (type: `integer`):

Collect up to this many distinct properties per search, following Google's pages. Google may return fewer. Free Apify plans return at most 20 hotels across the entire run.

## `includeBookingSites` (type: `boolean`):

Get each hotel's booking sites, nightly and total stay prices, official-site flag and click-through links. For list results, adds one Google request per hotel (plus retries), making runs slower. Single-hotel and property_token results include these from the same hotel page, with no extra request. Failed lookups keep the hotel and report booking_sites_error. Prices use the hotel's currency; partners vary by market.

## `freeCancellationOnly` (type: `boolean`):

Apply Google's free-cancellation filter to search results. Off by default. Cancellation terms depend on the selected offer; check them before booking. Ignored for single-hotel and property_token results.

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

Optional minimum nightly price in the run currency, as a nonnegative whole number. Empty means no minimum. Google applies the filter; we do not remove returned rows. Ignored for single-hotel and property_token results.

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

Optional maximum nightly price in the run currency, as a nonnegative whole number. Must be at least minPrice when both are set. Empty means no maximum. Ignored for single-hotel and property_token results.

## `minStars` (type: `integer`):

Optional minimum hotel class: 2, 3, 4 or 5 stars. Selects this class and all higher classes in Google's filter. Empty means any class. Ignored for single-hotel and property_token results.

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

Optional Google guest-rating threshold: 3.5, 4.0 or 4.5. Empty means any rating. Google may include a hotel without a displayed rating; we preserve its result and return null. Ignored for single-hotel and property_token results.

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

Datacenter proxies are the default and were reliable in our platform probes. Residential proxies are optional and use the selected search country. Datacenter and custom proxies retain their own routing. There is no automatic fallback. Turn off for direct requests, which cannot rotate a blocked IP.

## Actor input object example

```json
{
  "queries": [
    "hotels in Paris"
  ],
  "checkIn": "2027-03-12",
  "checkOut": "2027-03-15",
  "checkInDays": 1,
  "adults": 2,
  "childrenAges": [],
  "currency": "USD",
  "country": "US",
  "maxResultsPerQuery": 20,
  "includeBookingSites": false,
  "freeCancellationOnly": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Hotel overview. Full dataset records also include booking_sites (opt-in partner names, nightly and total stay prices in the record's currency, official-site flags and links) and booking_sites_error. booking_sites is null when not requested or failed, or an empty array when no offers are listed; lookup failures keep the hotel's ok status and list data.

# 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": [
        "hotels in Paris"
    ],
    "checkIn": "3 weeks",
    "checkOut": "23 days"
};

// Run the Actor and wait for it to finish
const run = await client.actor("cozybit/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": ["hotels in Paris"],
    "checkIn": "3 weeks",
    "checkOut": "23 days",
}

# Run the Actor and wait for it to finish
run = client.actor("cozybit/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": [
    "hotels in Paris"
  ],
  "checkIn": "3 weeks",
  "checkOut": "23 days"
}' |
apify call cozybit/google-hotels-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cozybit/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/YC0mAdrRhMBogWXUm/builds/qy6h5OZeYTUB46gwm/openapi.json
