# Google Hotels Price Monitor (`mouad-abbar/google-hotels-price-monitor`) Actor

Track hotel prices on Google Hotels for any dates. Schedule it daily and get only the prices that changed since the last run, plus sold-out and back-in-stock alerts.

- **URL**: https://apify.com/mouad-abbar/google-hotels-price-monitor.md
- **Developed by:** [mouad abbar](https://apify.com/mouad-abbar) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 price check (1 hotel or search, 1 date)s

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 Price Monitor

Track hotel prices on Google Hotels for any dates, and get **only what changed** since your last run: price increases, drops, sold-out hotels and hotels back in stock.

Built for scheduled monitoring: set it to run daily, and use rolling dates such as "7, 14 and 30 days from today" so the dates move forward automatically.

### Who it's for

- **Hotels and riads** watching competitors' rates before adjusting their own.
- **Travel agencies and tour operators** tracking prices for upcoming stays.
- **Analysts** building price history for a destination.

### What you get

For each hotel and check-in date:

| Field | Example |
|---|---|
| `hotelName` | Savoy Le Grand Hotel Marrakech |
| `checkIn` / `checkOut` / `nights` | 2026-12-02 / 2026-12-04 / 2 |
| `price` / `currency` / `priceText` | 1993.14 / MAD / "MAD 1,993" |
| `previousPrice` / `priceChange` / `priceChangePct` | 2134.63 / -141.49 / -6.63 |
| `changeType` | `new`, `up`, `down`, `unchanged`, `sold_out`, `back_in_stock`, `currency_changed` |
| `stars` / `hotelClass` | 5 / "5-star hotel" |
| `rating` / `reviewCount` | 4.1 / 3957 |
| `latitude` / `longitude` / `countryCode` | 31.618 / -8.010 / MA |
| `googleUrl` / `entityId` | Link to the hotel on Google Hotels |
| `trackedHotel` / `matchScore` | The name you entered and how closely the result matched it (0.75 to 1.0) |

A summary of every run (lookups, failures, hotels not found) is saved as `OUTPUT_SUMMARY` in the run's key-value store.

### How to use it

**Track specific hotels.** Add them under *Hotels to track*, with the city for accuracy:

```json
{
  "hotels": ["Savoy Le Grand Hotel Marrakech", "La Mamounia Marrakech", "Riad Qodwa Marrakech"],
  "checkInDaysAhead": [7, 14, 30],
  "nights": 2,
  "onlyChanges": true,
  "monitorName": "marrakech-competitors"
}
```

**Track a whole destination.** Use *Destination searches*, for example `hotels in Marrakech` or `5 star hotels in Paris`. Each search returns up to about 20 hotels per date.

**Monitor daily.**

1. Run it once, to record today's prices.
2. Create a **Schedule** in Apify Console (for example every morning at 7:00).
3. Turn on **Only output changes**, and keep the same **Monitor name**, so each run compares against the previous one. **Minimum change (%)** (default 1%) filters out the cent-level drift caused by Google's live currency conversion.
4. Optionally, connect an integration (email, Slack, Google Sheets, webhook) to get the changes delivered.

### Currency and proxy

Google picks the currency from the visitor's location, so **the proxy country decides the currency**: US gives USD, GB gives GBP, and so on. Don't use EU proxy countries, because Google shows them a cookie-consent page instead of prices. Residential proxies are the most reliable option.

### Reliability

- No browser is used: each lookup is a single fast page request.
- A blocked or empty page is retried with a fresh proxy session.
- Results are only kept if Google applied **your** dates, so prices are never silently mixed up with other dates.
- If Google changes its page layout, the run **fails with a clear message** instead of returning wrong data.

### Limitations

- The price is the **lowest nightly price shown on Google Hotels** for that stay, not a breakdown per booking site.
- Destination searches cover Google's first results page (up to about 20 hotels).
- When a named hotel has no availability for a date, Google often shows no hotel list. The hotel is then listed under `trackedHotelsNotFound` in the run summary.
- Google's results vary slightly between requests. Check `matchScore` the first time you track a new hotel.

### Pricing

Pay per use:

- **Search page:** charged once per Google results page checked.
- **Hotel price:** charged per result row.

With *Only output changes* turned on, unchanged prices are not output and not charged as rows.

### Questions or problems

Open an issue in the **Issues** tab. Layout changes on Google's side are usually fixed within a few days.

# Actor input Schema

## `hotels` (type: `array`):

Specific hotels to track, one per line. Add the city for accuracy, e.g. 'Savoy Le Grand Hotel Marrakech'. Each hotel returns one price per check-in date.

## `searches` (type: `array`):

Area searches, e.g. 'hotels in Marrakech' or '5 star hotels in Paris'. Each search returns up to ~20 hotels per check-in date (Google's first results page).

## `checkInDaysAhead` (type: `array`):

Check-in dates relative to the run date, e.g. \[7, 14, 30]. Best for scheduled runs: the dates move forward automatically every day.

## `checkInDates` (type: `array`):

Fixed check-in dates as YYYY-MM-DD. Past dates are skipped.

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

Length of stay. Prices are Google's displayed nightly rate for that stay.

## `onlyChanges` (type: `boolean`):

Output only prices that are new, went up or down, sold out or came back since the previous run with the same monitor name. Unchanged prices are skipped (and not charged as results).

## `minChangePct` (type: `integer`):

Price moves smaller than this percentage count as unchanged. Google converts currencies live, so prices drift by cents between runs; 1% filters that noise out. Set 0 to report every cent.

## `monitorName` (type: `string`):

Runs with the same monitor name compare against each other. Use different names for unrelated monitors.

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

Cap on hotels kept from each destination search and date.

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

Google interface language code, e.g. en, fr, es.

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

How many Google pages to fetch at the same time. Higher is faster but more likely to be rate-limited.

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

The proxy country decides the price currency (US = USD, GB = GBP). Avoid EU countries: Google shows them a cookie-consent page.

## Actor input object example

```json
{
  "hotels": [
    "Savoy Le Grand Hotel Marrakech",
    "ibis Marrakech Palmeraie"
  ],
  "searches": [
    "hotels in Marrakech"
  ],
  "checkInDaysAhead": [
    7,
    30
  ],
  "checkInDates": [],
  "nights": 1,
  "onlyChanges": false,
  "minChangePct": 1,
  "monitorName": "default",
  "maxHotelsPerSearch": 20,
  "language": "en",
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

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

One row per hotel and check-in date: price, currency, previous price, change type (new, up, down, unchanged, sold_out, back_in_stock), stars, rating and Google link. With 'Only output changes', unchanged prices are left out.

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

Counts of lookups, failures and changes by type, tracked hotels that were not found, and the name of the store that holds the price history.

# 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 = {
    "hotels": [
        "Savoy Le Grand Hotel Marrakech",
        "ibis Marrakech Palmeraie"
    ],
    "searches": [
        "hotels in Marrakech"
    ],
    "checkInDaysAhead": [
        7,
        30
    ],
    "checkInDates": [],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("mouad-abbar/google-hotels-price-monitor").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 = {
    "hotels": [
        "Savoy Le Grand Hotel Marrakech",
        "ibis Marrakech Palmeraie",
    ],
    "searches": ["hotels in Marrakech"],
    "checkInDaysAhead": [
        7,
        30,
    ],
    "checkInDates": [],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("mouad-abbar/google-hotels-price-monitor").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 '{
  "hotels": [
    "Savoy Le Grand Hotel Marrakech",
    "ibis Marrakech Palmeraie"
  ],
  "searches": [
    "hotels in Marrakech"
  ],
  "checkInDaysAhead": [
    7,
    30
  ],
  "checkInDates": [],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call mouad-abbar/google-hotels-price-monitor --silent --output-dataset

```

## MCP server setup

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

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/oZK2InUyS7yL22d4G/builds/P4hcX4aDEywKYA4fe/openapi.json
