# Google Hotels Scraper - Prices, Ratings & Deals (`cheapapi/google-hotels-scraper`) Actor

Scrape Google Hotels for any city and dates: hotel prices per night and total, star class, rating, reviews, deals, photos, GPS. Filters. No login.

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

## Pricing

Pay per event + usage

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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, Ratings & Deals

Get every hotel Google Hotels shows for any destination and dates — nightly and total price, deals, star class, guest rating, review count, photos, GPS and a direct link — as clean rows for Excel, Google Sheets or your app. New: **price calendar mode** tracks the same stay across up to 60 consecutive check-in dates.

**Why this Actor**

- **Low price:** **$0.30–$0.45 per 1,000 hotels** (by plan) + $0.003 per search. 1,000 hotels from 10 searches cost **$0.33–$0.48** in event fees. No start fee. Apify platform usage is billed separately by Apify (at the default 256 MB a small run typically uses about $0.001–$0.005) — see the comparison below.
- **36 fields per hotel:** price per night, total for the stay, price before discount, discount %, deal text, hotel class, rating, reviews, photos, coordinates, Google Hotels link and more.
- **Price calendar:** one run gives you prices for the next 7, 14, 30 or up to 60 check-in dates — one row per hotel per date, plus the lowest and median price per date in the run summary.
- **Parallel:** up to 50 searches run at the same time; the default input finishes in about 2 minutes (see *Typical run time*).
- **All Google Hotels filters:** dates, adults and children, 31 currencies, 127 languages, 249 countries, sort order, price range, hotel class, guest rating, 18 amenities, free cancellation, vacation rentals, exact area or coordinates.
- **Stable row `id`:** the same hotel and stay gets the same `id` in every run — easy deduplication and run-to-run joins.

### Compared with alternatives

Typical run: **1,000 hotels from 10 searches** (e.g. 10 cities × 100 hotels) in one run. Prices are the lowest–highest plan price. For this Actor, Apify platform usage is billed separately by Apify (at the default 256 MB a small run typically uses about $0.001–$0.005) on top of the price shown.

| Alternative | Price for this run | Start fee | Platform usage | Prices per booking site |
|---|---|---|---|---|
| Most-used Google Hotels Actor on the Store (~600 users) | ~$1.01 on every plan ($1.00 per 1,000 hotels + $0.005 per run) | $0.005 | not charged separately | ✗ (not advertised) |
| Most active Google Hotels Actor (~580 users, ~510 of them in the last 30 days) | $2.99–$4.99 | none | not charged separately | ✗ (not advertised) |
| Per-page Actor (~480 users) | ~$0.73–$1.03 (about 50 result pages of ~20 hotels at $0.014–$0.02 per page, + $0.02 setup per run, + $0.00001 per hotel) | $0.02 setup | not charged separately | ✗ (not advertised) |
| Cheapest per-result Actor (~510 users) | ~$0.10 **+ platform usage you pay separately** | $0.00005 | billed separately | ✗ (not advertised) |
| Low-price per-result Actor (~40 users) | ~$0.09–$0.10 | $0.00005 | not charged separately | ✗ (not advertised) |
| OTA price-comparison Actor (~120 users) | $22.50–$25.00 **+ platform usage you pay separately** | $0.00005 | billed separately | ✓ |
| Actor with booking-site (OTA) rates (~85 users) | $3.20–$4.00, plus $0.0041–$0.005 per booking-site price lookup | none | not charged separately | ✓ |
| **This Actor** | **$0.33–$0.48 + platform usage billed separately by Apify** (about $0.001–$0.005 for a small run) | **none** | billed separately | only when Google shows them in the list (see "Extras" view) |

Prices from public Apify Store listings (event prices and whether the listing bills platform usage to the user), checked September 2026.

**At realistic scale** — daily price monitoring of 15 cities × 100 hotels for 30 days (45,000 hotel rows, 450 searches): **$21.60 on Free/Bronze, $18.45 on Silver, $14.85 on Gold+** in event fees, plus platform usage (estimated at roughly $0.01 per run, about $0.30 a month). The same volume costs about $45 with the most-used Actor and $135–$225 with the most active one.

Honest note: the two cheapest per-result Actors charge less per hotel than we do (one of them bills platform usage separately, like this Actor). Most of the larger Actors do not bill platform usage separately; even so, this Actor stays well below them for this run. The per-page Actor's cost depends on how many hotels Google puts on each result page. Here you can cap the event fees with **Max cost per run**, and you get the price calendar (up to 60 check-in dates per run) and per-date lowest/median prices.

**When to choose another Actor:** if the lowest possible price per hotel matters more than the price calendar and per-date summaries, the cheapest per-result Actors cost less; if you need the full price list from every booking site for each hotel (rate parity, OTA comparison), choose one of the OTA-rate Actors above.

### Not included

- **Price from every booking site (rate ladder)** — the hotel list shows one lead price per hotel. When Google includes site prices in the list, they appear in `offers` (Extras view); we do not open each hotel page to fetch them.
- **Review texts** — rows have the rating and review count only. For hotel review texts use [TripAdvisor Reviews Scraper](https://apify.com/cheapapi/tripadvisor-reviews-scraper).
- **Hotel phone, website, opening details and top reviews** — use [Google Maps Scraper Plus](https://apify.com/cheapapi/google-maps-scraper-plus) with a query like "hotels in Paris".
- **Room types, hotel descriptions and full amenity lists** — not in the Google Hotels list view.
- **Google web search rankings for hotel keywords** — use [Google SERP Scraper](https://apify.com/cheapapi/google-serp-scraper).
- **Flights and vacation packages** — not covered.

### What data you get

One row per hotel (per check-in date in price calendar mode). Full field definitions are also in the dataset schema (visible in the Console "Output" tab).

| Field | Type | Example |
|---|---|---|
| `id` | string | `2c1598dc324d2dd4` (stable row ID: same hotel + destination + dates + guests + currency → same ID in every run) |
| `destination` | string | `Paris` (your input) |
| `calendarDay` | number | `1` (price calendar: 1 = first check-in date, 2 = next day, …; always 1 in a normal search) |
| `position` | number | `1` (rank on Google Hotels) |
| `hotelName` | string | `HÔTEL RACHEL` |
| `hotelId` | string | `ChcItvPT1vS7lvkNGgsvZy8xdGRtZDV0bhAB` (Google's hotel ID) |
| `hotelClass` | number | null | `4` (stars; `null` if Google shows no star class, as in the example below) |
| `rating` | number | `3.2` (guest rating out of 5) |
| `reviewsCount` | number | `430` |
| `pricePerNight` | number | null | `61` (lowest price shown for the stay, per night) |
| `totalPrice` | number | null | `122` (price per night × nights) |
| `priceBeforeDiscount` | number | null | `null` (a number such as `87` when Google shows the undiscounted price) |
| `currency` | string | `USD` |
| `isDeal` | boolean | `true` when Google shows a discount or deal |
| `discountPercent` | number | null | `null` (a number such as `30` when Google states it) |
| `discountText` | string | null | `30% less than usual` |
| `hasPrice` | boolean | `false` when no price is shown (e.g. sold out) |
| `checkIn` / `checkOut` | string | `2026-10-13` / `2026-10-15` |
| `nights` | number | `2` |
| `adults` / `children` / `guests` | number | `2` / `0` / `2` |
| `amenities` | string\[] | null | `null` (or e.g. `["pool","free_wifi"]`) — the amenities you filtered by (every hotel returned has them) |
| `isSponsored` | boolean | `false` (true for hotel ads) |
| `latitude` / `longitude` | number | `48.882678` / `2.4036894` |
| `mapsUrl` | string | Google Maps link |
| `imageUrl` / `images` | string / string\[] | main photo / all photos on the result card |
| `hotelUrl` | string | Google Hotels page of the hotel |
| `searchUrl` | string | the Google Hotels search the row comes from |
| `searchKeyword` | string | the search as Google ran it |
| `country` / `language` | string | `US` / `en` |
| `scrapedAt` | string | ISO timestamp |

Optional fields, added **only when Google includes them in the hotel list** (most searches do not have them): `offers` (price per booking site), `pricesByDate`, `ratingDistribution`, `reviewTopics`, `otherSitesRatings`. Do not rely on them. The **Extras** view in the Output tab shows them next to the hotel name and lead price.

Output tab views: **Hotels** (overview with photos), **Prices & deals**, **Price calendar**, **Locations** and **Extras**.

### How to use

1. Open the Actor in Apify Console and click **Try for free**.
2. Enter one or more **Destinations** (a city, an area or landmark such as "Times Square, New York", or "beach resorts in Antalya").
3. Pick **Check-in date** and **Check-out date** (or leave check-out empty for 1 night), and the number of **Adults**.
4. Set **Max hotels per destination** (up to 140) and click **Start**.
5. Optional — price calendar: open **Advanced: price calendar** and set the number of check-in dates (e.g. 14). The stay length stays the same for every date.
6. Download the results as JSON, CSV, Excel or HTML, or read them through the API.

Ready-to-paste input:

```json
{
    "destinations": ["Paris", "Times Square, New York"],
    "checkIn": "2026-12-20",
    "checkOut": "2026-12-23",
    "adults": 2,
    "childrenAges": ["7"],
    "currency": "EUR",
    "maxHotelsPerSearch": 50,
    "sortBy": "lowest_price",
    "hotelClass": ["4", "5"],
    "minRating": "4",
    "freeCancellation": true
}
```

Price calendar — the same 2-night stay for 14 consecutive check-in dates (Dec 1–14), 30 hotels each:

```json
{
    "destinations": ["Paris"],
    "checkIn": "2026-12-01",
    "checkOut": "2 days",
    "priceCalendarDays": 14,
    "maxHotelsPerSearch": 30,
    "currency": "EUR"
}
```

**API — curl**

```bash
curl -X POST "https://api.apify.com/v2/acts/cheapapi~google-hotels-scraper/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"destinations":["Paris"],"checkIn":"14 days","adults":2,"maxHotelsPerSearch":20}'
```

**API — JavaScript (`apify-client`)**

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

const client = new ApifyClient({ token: '<YOUR_TOKEN>' });
const run = await client.actor('cheapapi/google-hotels-scraper').call({
    destinations: ['Paris'],
    checkIn: '2026-12-20',
    checkOut: '2026-12-23',
    adults: 2,
    currency: 'EUR',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((h) => `${h.hotelName}: ${h.pricePerNight} ${h.currency}/night`));
```

**API — Python (`apify-client`)**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_TOKEN>")
run = client.actor("cheapapi/google-hotels-scraper").call(run_input={
    "destinations": ["Paris"],
    "checkIn": "2026-12-20",
    "checkOut": "2026-12-23",
    "adults": 2,
    "currency": "EUR",
})
for hotel in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(hotel["hotelName"], hotel["pricePerNight"], hotel["currency"])
```

#### Typical run time

| Run size | Processing | Typical time |
|---|---|---|
| 1 destination × 20 hotels (default input) | fast | about 2 minutes (measured in a live run) |
| up to 50 searches (e.g. 10 cities × 100 hotels, or a 30-date price calendar) | fast | usually 2–5 minutes — searches run in parallel |
| more than 50 searches | fast | a few minutes per block of 50 searches |
| 2,000+ hotels in total, or **Processing speed** = economy | economy | up to ~45 minutes |

Times other than the first row are estimates; the run log shows progress ("Waiting for results: 12/50 searches ready").

### Use cases

- **Hotel price monitoring:** schedule daily runs for your destinations and dates and track price changes and deals.
- **Revenue management:** compare your hotel's nightly rate against competitors of the same class and rating.
- **Travel apps and comparison sites:** feed hotel lists with prices, ratings, photos and coordinates into your product.
- **Market research:** map hotel supply, star mix and price levels of a city or region.
- **Deal hunting:** find discounted 4–5 star hotels with free cancellation below a price limit.
- **Best time to book:** run the price calendar for the next 30 check-in dates and pick the cheapest arrival day per hotel.
- **Lead generation:** build lists of hotels (with Google IDs and coordinates) for sales outreach.

### Advanced options

| Input | Default | Meaning |
|---|---|---|
| `priceCalendarDays` | `1` | Price calendar: number of consecutive check-in dates (1–60) starting at the check-in date; same number of nights each time. 1 = normal search. |
| `childrenAges` | none | One entry per child with its age (0–17). Adults + children ≤ 6. |
| `currency` | `USD` | Currency of all prices (31 currencies to choose from; API users can send any 3-letter code). |
| `language` | `en` | Language of hotel names and links — select from 127 languages (`de`, `fr`, `es`, `pt-BR`, `zh-CN`, …). |
| `country` | `US` | Country the search is made from — select from 249 countries (API: ISO code such as `GB`); can change the prices and deals shown. |
| `sortBy` | `relevance` | `relevance`, `lowest_price`, `highest_rating`, `most_reviewed`. |
| `minPrice` / `maxPrice` | none | Price per night range in the chosen currency. |
| `hotelClass` | all | Star classes to include: `1`–`5`. |
| `minRating` / `maxRating` | none | Guest rating range (out of 5). |
| `amenities` | none | Only hotels with all of: free parking, parking, free Wi-Fi, free breakfast, pool, indoor/outdoor pool, spa, fitness center, bar, restaurant, room service, air conditioning, kid-friendly, pets allowed, wheelchair accessible, beach access, all-inclusive. |
| `freeCancellation` | `false` | Only offers with free cancellation. |
| `vacationRentals` | `false` | Search holiday homes and apartments instead of hotels. |
| `includeSponsored` | `true` | Keep hotel ads (flagged `isSponsored`). |
| `locationName` | none | Exact area such as `London,England,United Kingdom`. |
| `locationCode` | none | Numeric location code (e.g. `2826` = United Kingdom). |
| `coordinates` | none | Search around `latitude,longitude`. |
| `searchThisArea` | auto | Restrict results to the location above (on automatically when one is given). |
| `processingSpeed` | `auto` | `fast` (usually a few minutes), `economy` (up to ~45 min, for 500+ hotels), `auto` (economy from 2,000 hotels). Same price. |

Dates accept `YYYY-MM-DD` or relative values: check-in `"14 days"` = 14 days from today; check-out `"3 days"` = 3 nights after check-in.

### Output example

Example output — a real row from a live test run (Paris, 2 nights, 2 adults, default settings):

```json
{
    "id": "2c1598dc324d2dd4",
    "destination": "Paris",
    "calendarDay": 1,
    "position": 1,
    "hotelName": "HÔTEL RACHEL",
    "hotelId": "ChcItvPT1vS7lvkNGgsvZy8xdGRtZDV0bhAB",
    "hotelClass": null,
    "rating": 3.2,
    "reviewsCount": 430,
    "pricePerNight": 61,
    "totalPrice": 122,
    "priceBeforeDiscount": null,
    "currency": "USD",
    "isDeal": true,
    "discountPercent": null,
    "discountText": "30% less than usual",
    "hasPrice": true,
    "checkIn": "2026-10-13",
    "checkOut": "2026-10-15",
    "nights": 2,
    "adults": 2,
    "children": 0,
    "guests": 2,
    "amenities": null,
    "isSponsored": false,
    "latitude": 48.882678,
    "longitude": 2.4036894,
    "mapsUrl": "https://www.google.com/maps/search/?api=1&query=48.882678,2.4036894",
    "imageUrl": "https://lh3.googleusercontent.com/gps-cs-s/ANWiy9SJDU1Bx4FyERemybnZ-qO7UOUJG69CO9UwSJaM-oh2k9ZtkfBrSx5cYbnoUBCwh5eOulSqAid2upXJBOxyquX3hapLIvajlY56GGzsqXFkTl2q5K7O6uIcvJq-oPxFcgSz3qoB=s287-w287-h192-n-k-no-v1",
    "images": [
        "https://lh3.googleusercontent.com/gps-cs-s/ANWiy9SJDU1Bx4FyERemybnZ-qO7UOUJG69CO9UwSJaM-oh2k9ZtkfBrSx5cYbnoUBCwh5eOulSqAid2upXJBOxyquX3hapLIvajlY56GGzsqXFkTl2q5K7O6uIcvJq-oPxFcgSz3qoB=s287-w287-h192-n-k-no-v1",
        "…"
    ],
    "hotelUrl": "https://www.google.com/travel/hotels/entity/ChcItvPT1vS7lvkNGgsvZy8xdGRtZDV0bhAB?hl=en&gl=us&curr=USD",
    "searchUrl": "https://www.google.com/travel/search?q=Paris&hl=en&gl=US&…",
    "searchKeyword": "Paris",
    "country": "US",
    "language": "en",
    "scrapedAt": "2026-09-29T16:26:05.150Z"
}
```

Every run also writes a run summary (key-value store record `RUN_SUMMARY`, also linked in the Output tab) with totals, errors, skipped searches and `hotelsPerDay` — hotels delivered per check-in date across all destinations (one entry per date, `0` when a date found nothing):

```json
"hotelsPerDay": [
  { "calendarDay": 1, "checkIn": "2026-12-01", "checkOut": "2026-12-03", "hotels": 30, "searchesWithHotels": 1 },
  { "calendarDay": 2, "checkIn": "2026-12-02", "checkOut": "2026-12-04", "hotels": 0, "searchesWithHotels": 0 }
]
```

In price calendar mode it also has `priceCalendar`, one entry per destination and date:

```json
{ "destination": "Paris", "calendarDay": 3, "checkIn": "2026-12-03", "checkOut": "2026-12-05", "currency": "EUR",
  "hotels": 30, "hotelsWithPrice": 29, "lowestPricePerNight": 152, "medianPricePerNight": 231 }
```

### Pricing

**Typical cost:** 1,000 hotels from 10 searches = **$0.33–$0.48** in event fees (by plan); Apify platform usage is billed separately.

**Apify Free plan:** Apify does not pay developers for usage on its Free plan, so on the Free plan this Actor can be used for up to **$0.25 of results per calendar month** — enough to try it on a small input. When the allowance is used up, the run ends with a clear message (not an error). Any paid Apify plan removes the limit; prices are the same.

Pay per result — no subscription, no start fee. Apify platform usage is billed separately by Apify (at the default 256 MB a small run typically uses about $0.001–$0.005); the prices and examples in this section are event fees only.

| Event | Free | Bronze | Silver | Gold, Platinum, Diamond |
|---|---|---|---|---|
| Hotel delivered | $0.00045 | $0.00045 | $0.00038 | $0.00030 |
| Search (destination × check-in date, only if it returned hotels) | $0.003 | $0.003 | $0.003 | $0.003 |
| Search without hotels (the search was run but found nothing, e.g. a price-calendar date with no availability) | $0.0023 | $0.0023 | $0.0023 | $0.0023 |

A normal run makes one search per destination. In **price calendar mode** every check-in date is its own search, so a run makes *destinations × dates* searches and returns up to *destinations × dates × max hotels* rows — each row and each search is charged as above. Cost formula: `searches with hotels × $0.003 + searches without hotels × $0.0023 + hotel rows × hotel price`.

Worked examples:

- **1 destination × 20 hotels** (default): $0.012 on Free, $0.009 on Gold+.
- **10 destinations × 100 hotels = 1,000 hotels:** $0.48 on Free/Bronze, $0.41 on Silver, $0.33 on Gold+.
- **50 destinations × 20 hotels = 1,000 hotels:** $0.60 on Free, $0.45 on Gold+.
- **Price calendar, 1 destination × 7 dates × 20 hotels** = 7 searches + 140 rows: $0.084 on Free, $0.063 on Gold+.
- **Price calendar, 1 destination × 30 dates × 20 hotels** = 30 searches + 600 rows: $0.36 on Free, $0.27 on Gold+.
- **Price calendar, 3 destinations × 14 dates × 20 hotels** = 42 searches + 840 rows: $0.50 on Free, $0.38 on Gold+.
- **Price calendar, 1 destination × 30 dates, 20 hotels wanted, 5 dates sold out:** 25 searches with hotels + 5 without + 500 rows = 25 × $0.003 + 5 × $0.0023 + 500 × $0.00045 = **$0.31 on Free** (25 × $0.003 + 5 × $0.0023 + 500 × $0.0003 = $0.24 on Gold+).

A search that finds no hotels is still run, so it costs $0.0023 ("Search without hotels") instead of $0.003 — this also applies to a "no data" answer and to the rare search that got no answer or never finished although it may have been run. Searches rejected because of invalid input are free. Set a **maximum cost per run** in the run options: the Actor only starts searches the remaining budget can fully pay for and stops before exceeding it.

### Integrations

- **Scheduling:** run daily or hourly from Apify Schedules to monitor prices.
- **Google Sheets, Excel, CSV, JSON, XML:** export the dataset directly or use the Google Sheets integration.
- **Make, Zapier, n8n:** start runs and pass hotels to 1,000+ apps.
- **Webhooks:** get notified when a run finishes and fetch the dataset through the API.
- **API & SDKs:** JavaScript and Python clients (examples above); also usable from AI agents through the Apify MCP server.

### FAQ

**Is there a limit on the Apify Free plan?** Yes: up to $0.25 of this Actor's results per calendar month, enough to try it. Apify pays developers nothing for Free-plan usage while our data costs are real, so this keeps the Actor sustainable. Runs that reach the allowance stop cleanly and keep everything collected so far; the allowance resets on the 1st of the month. Any paid Apify plan has no limit.

**Is it legal to scrape Google Hotels?**
The Actor collects publicly visible hotel listings and prices — no personal data, no login. Always check the terms that apply to you and use the data responsibly; consult a lawyer if you are unsure.

**How fresh is the data?**
Every run collects the results live at the time of the run, for the dates and guests you entered.

**Why did I get fewer hotels than "Max hotels per destination"?**
Google returns at most about 140 hotels per search, and filters (price, class, rating, amenities, free cancellation) or small destinations can leave fewer. Sold-out hotels may appear without a price (`hasPrice: false`). You only pay for the hotels delivered.

**Is `pricePerNight` per room or per person?**
It is the price Google Hotels shows per night for your party (adults and children) — usually the lowest offer across booking sites. `totalPrice` is that nightly price × the number of nights.

**How does the price calendar work and what does it cost?**
Set `priceCalendarDays` to N: the Actor searches the same stay (same number of nights, guests and filters) for N consecutive check-in dates starting at your check-in date. You get one row per hotel per date and pay for each date like a normal search ($0.003 + the hotel rows; a date with no hotels costs $0.0023). Example: 1 city × 30 dates × 20 hotels = $0.27–$0.36. Use `hotelId` + `checkIn` to build a price-by-date table.

**Why do the check-in dates in the rows differ from my input?**
Rows show the dates Google actually priced. If Google has no availability for your exact dates it may show its nearest alternative — compare `checkIn`/`checkOut` with your input.

**Why was I charged $0.0023 for a search without hotels?**
The search was run for your destination and dates, but Google had no hotel matching them (sold out, too many filters, a price-calendar date with no availability) or answered "no data". Running a search has a real cost whether or not it finds hotels, so it is charged at a reduced fee instead of the $0.003 search fee. Loosen the filters or check the destination spelling to avoid empty searches. Searches rejected because of invalid input are free. If a whole block of up to 50 searches gets no answer from the data source, those searches are charged the same reduced fee (they may have been run, and they are never sent twice), and the run continues with the next block; after two such blocks in a row the run stops and the remaining searches cost nothing.

**Is Apify platform usage included, and how do I limit my spending?**
Platform usage is billed separately by Apify (at the default 256 MB a small run typically uses about $0.001–$0.005; very large or economy runs use more — each run's usage is shown in Apify Console). To cap the event fees, set **Max cost per run** in the run options: the Actor never starts searches it cannot pay for and stops before exceeding your limit.

**Can I monitor prices over time?**
Yes — save your input as a Task and add an Apify Schedule (e.g. daily). Each run is a fresh, complete snapshot (price monitoring needs every hotel every time, so there is no "only new hotels" mode). Join runs by `id` (same hotel and same stay) or by `hotelId` + `checkIn` (with relative dates like `"14 days"` the stay moves with the run date). For a price-change alert, compare `pricePerNight` of the same `id` between the last two runs, e.g. in Google Sheets or with a webhook that runs your script.

**How is the Actor tested?**
Automated unit tests cover input validation, the search options sent for each input, and the mapping of results to rows (prices, deals, dates, stable IDs, optional fields, dataset schema). End-to-end tests run the whole Actor against a simulated data service and check delivered rows, charged events, the stop at **Max cost per run** (partial results are kept), failed or empty searches (charged only when the search was actually run) and invalid input. Separate tests check that every search pays for its own data cost on every plan in the worst case. Google can change what it shows, so report anything unexpected on the Issues tab.

**Where do I get help?**
Open an issue on the Actor's Issues tab in Apify Console with your run ID — we read and answer every issue.

### Limitations

- Up to 140 hotels per destination and search; run several searches (different areas, sort orders or price ranges) for more.
- Prices are the ones Google Hotels shows in its list for the given dates and guests; they can change minutes later and may exclude some taxes and fees depending on the country.
- `totalPrice` is calculated as price per night × nights; the booking site's final total can differ.
- No per-booking-site rate ladder, review texts, hotel descriptions or full amenity lists.
- Price calendar: each date is a separate search, so a 30-date calendar costs about 30× a single search and Google may return slightly different hotel sets per date.
- Stays are limited to 30 nights and 6 guests per search.
- Economy processing is slower (up to ~45 minutes); it is only used for very large runs unless you choose it.

### Privacy

The Actor collects public business listings (hotels) only — no guest data, no reviewer names, no personal data. If you combine the output with personal data, you are responsible for complying with GDPR and other laws that apply to you.

# Actor input Schema

## `destinations` (type: `array`):

Where to search, as you would type it into Google Hotels: a city ("Paris"), an area or landmark ("Times Square, New York"), or a hotel type ("beach resorts in Antalya"). One search per line; each returns up to "Max hotels per destination" hotels A search that finds no hotels (e.g. too many filters) costs the reduced "Search without hotels" fee ($0.0023).

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

Arrival date. Pick a fixed date (YYYY-MM-DD) or a relative value that moves with each run, such as "14 days", "2 weeks", "1 month", "tomorrow" or "today" (counted from the day the run starts). Relative values are best for scheduled price monitoring. If left empty, check-in is 14 days from today.

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

Departure date (YYYY-MM-DD) or a number of nights after check-in such as "2 days". Leave empty for a 1-night stay. Max 30 nights.

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

Number of adult guests (1–6; adults + children at most 6).

## `maxHotelsPerSearch` (type: `integer`):

How many hotels to collect per destination (up to 140, in Google Hotels order or the sort you choose). In price calendar mode this applies to every check-in date.

## `priceCalendarDays` (type: `integer`):

1 = only the check-in date above (normal search). 7, 14 or 30 = search the same stay for 7, 14 or 30 consecutive check-in dates starting at the check-in date (e.g. check-in 2026-12-01 + 7 dates = 1-7 Dec). You get one row per hotel per date (column "calendarDay"). Cost grows with the number of dates: dates × destinations searches, and up to dates × destinations × max hotels hotel rows. A date with no hotels is still a search and costs the reduced "Search without hotels" fee ($0.0023). Max 60.

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

One entry per child with the child's age (0–17), e.g. 5 and 9 for two children. Leave empty for no children.

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

Currency for every price in the output (pricePerNight, totalPrice, priceBeforeDiscount, min/max price filters). Google converts the prices itself, so the amounts are what Google Hotels shows in that currency. Choose one of 31 currencies; API users can send any 3-letter code such as USD, EUR or GBP. Default: USD.

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

Language of hotel names and Google Hotels links.

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

The country the search is made from. It can change which prices and deals Google shows. Default: United States.

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

Order of the results (and so which hotels you get when you set a maximum).

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

Only hotels costing at least this much per night (in the chosen currency).

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

Only hotels costing at most this much per night (in the chosen currency).

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

Only return hotels with these official star classes (you can select several, e.g. 4 and 5 stars). Hotels without a star class are usually left out when this filter is used. Leave empty to include all hotels, rated or not.

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

Only hotels with at least this guest rating (out of 5).

## `maxRating` (type: `string`):

Only hotels with at most this guest rating (out of 5) — e.g. to find hotels with room to improve.

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

Only return hotels that offer ALL the selected amenities (e.g. pool + free Wi-Fi returns hotels with both). Each extra amenity narrows the results, so select only what you really need. The selected amenities are copied into the amenities field of every row. Leave empty for no amenity filter.

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

Only offers that can be cancelled for free.

## `vacationRentals` (type: `boolean`):

Search holiday homes and apartments instead of hotels.

## `includeSponsored` (type: `boolean`):

Keep hotels that Google shows as ads (marked isSponsored). Turn off to get organic results only.

## `locationName` (type: `string`):

Full location name in the format "City,Region,Country", e.g. "London,England,United Kingdom" or "Paris,Ile-de-France,France". Replaces "Search from country".

## `locationCode` (type: `integer`):

Numeric location code (e.g. 2826 for the United Kingdom, 1006886 for London). Replaces "Location name" and "Search from country".

## `coordinates` (type: `string`):

Search around a point, as "latitude,longitude" (e.g. "48.8566,2.3522"). Takes priority over the other location fields.

## `searchThisArea` (type: `boolean`):

On: restrict results to the location/coordinates above (the location is added to the destination text). Off: the destination text alone decides. Default: on when a location name, code or coordinates is given, otherwise off.

## `processingSpeed` (type: `string`):

Fast: results for small runs usually within a few minutes. Economy: can take up to ~45 minutes, for large runs (500+ hotels). Automatic: fast, economy for runs of 2,000+ hotels. The price is the same.

## Actor input object example

```json
{
  "destinations": [
    "Paris"
  ],
  "checkIn": "14 days",
  "checkOut": "2 days",
  "adults": 2,
  "maxHotelsPerSearch": 20,
  "priceCalendarDays": 1,
  "currency": "USD",
  "language": "en",
  "country": "US",
  "sortBy": "relevance",
  "freeCancellation": false,
  "vacationRentals": false,
  "includeSponsored": true,
  "processingSpeed": "auto"
}
```

# Actor output Schema

## `hotels` (type: `string`):

One row per hotel per search (per check-in date in price calendar mode).

## `prices` (type: `string`):

No description

## `calendar` (type: `string`):

Hotel prices by check-in date (useful when "Price calendar" is above 1).

## `summary` (type: `string`):

Counts, skipped searches and, in price calendar mode, the lowest and median price per destination and date.

# 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 = {
    "destinations": [
        "Paris"
    ],
    "checkIn": "14 days",
    "checkOut": "2 days",
    "adults": 2,
    "maxHotelsPerSearch": 20,
    "priceCalendarDays": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("cheapapi/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 = {
    "destinations": ["Paris"],
    "checkIn": "14 days",
    "checkOut": "2 days",
    "adults": 2,
    "maxHotelsPerSearch": 20,
    "priceCalendarDays": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("cheapapi/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 '{
  "destinations": [
    "Paris"
  ],
  "checkIn": "14 days",
  "checkOut": "2 days",
  "adults": 2,
  "maxHotelsPerSearch": 20,
  "priceCalendarDays": 1
}' |
apify call cheapapi/google-hotels-scraper --silent --output-dataset

```

## MCP server setup

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