# Google Hotels Prices Scraper — Price Tracking & Rate Parity (`kestrel/google-hotels-prices`) Actor

Hotel prices from Google Hotels for exact dates and guests: lowest nightly rate and stay total per hotel, plus every booking site’s rate (Booking.com, Expedia, Agoda, official site). Track prices daily, check rate parity, build price history. Pay per priced row.

- **URL**: https://apify.com/kestrel/google-hotels-prices.md
- **Developed by:** [Tedj MEABIOU](https://apify.com/kestrel) (community)
- **Categories:** Travel, Business, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Google Hotels Prices Scraper — Price Tracking & Rate Parity

Google Hotels prices scraper for exact dates and guests: the lowest nightly rate and the stay total for every hotel in a search, then every booking site's rate for each hotel — Booking.com, Expedia, Agoda, Hotels.com, Trip.com and the hotel's official site — with free-cancellation flags and deep links. Run it once for a price check, on a schedule for hotel price tracking and rate parity, or with a date sweep to build a price calendar and your own hotel price history. No Google API key, no login, no browser: it reads the same public Google Hotels results any visitor sees, through Apify's proxies, and returns clean JSON.

**You pay only for priced rows.** Sold-out hotels, empty searches and status rows cost nothing, and the price per row is stated on this page and identical on every plan.

### What does Google Hotels Prices Scraper do?

Google Hotels is a metasearch engine: for a hotel and a stay it shows the rates of every booking site it knows and the hotel's own site. This scraper reads that comparison for the dates, occupancy, currency and market you choose and turns it into three kinds of rows:

- **`hotel` rows** — up to 200 hotels per place search (Google's results, paged) or exactly the properties you list: lowest nightly rate, stay total, deal note ("19% less than usual"), star class, rating and review count, coordinates, website, Google Maps link and the Google Hotels entity id.
- **`offer` rows** — for every priced hotel, each booking source's rate: nightly, total for the stay, free-cancellation flag and deadline, the source's link, and for official sites the booking-engine URL with your dates already filled in. Optionally every room type and rate.
- **`status` rows** — one per place or property and stay: how many hotels, how many priced, how many offers, any error. Never charged.

It is the data behind a Google Hotels price tracker, a hotel price monitoring workflow, a rate shopping tool or a rate parity check — without the SaaS subscription, and with the raw hotel price data in your own dataset.

### Google Hotels price tracking with your own data

Google's built-in hotel price tracking emails you when a price moves, but it picks the sources, keeps the history and gives you no export. Scheduling this scraper gives you the same signal as data you own:

- **Track a city or a shortlist daily.** Schedule the run (Apify Console → Schedules, or the API) with relative dates such as `"checkIn": "30 days", "checkOut": "32 days"`: every run prices the stay 30 days out, forever. Each run appends rows with `fetched_at`, so the dataset becomes your hotel price history.
- **Price alerts.** A Google Hotels price alert you control: connect the run to n8n, Make or Zapier through Apify's integrations and alert on `nightly` below a threshold, or on a specific `source` dropping below the official site.
- **Rate calendars.** `sweepDays: 6` prices the same length of stay for each of the next seven check-in days in one run — a price calendar per hotel, or "which weekend is cheapest".

Google Hotels' own price history and price alerts stay inside Google; this is how you get the numbers out.

### Rate parity and rate shopping for hotels

For revenue managers the `offer` rows are the point. One run answers, per property and stay: what is the official site charging, what is every OTA charging, which rate is refundable until when, and what is each source's stay total. That is a rate parity check across every channel Google lists, at the price of a few cents per hotel.

- Put your properties and your competitive set in `hotels` (Google Hotels URLs — find them on google.com/travel/hotels — or the `entity_id` from an earlier run). No search is needed: one offers call per property and stay.
- Use `offerLevel: "sources"` (default) for one row per source with its lowest rate — the rate shopping view — or `offerLevel: "rooms"` for every room type and rate.
- Sources are keyed by `source_id`, and the property's own listing carries `official: true`, so a parity breach is a one-line comparison: any row where `official` is false and `nightly` is below the official row.

The same rows serve a hotel competitor rate shopping tool, hotel price intelligence dashboards, OTA rate comparison and channel-manager checks.

### Input

| Field | Meaning |
|---|---|
| `queries` | Free-text places exactly as you would type them into Google Hotels: `"hotels in Lisbon"`, `"hotels near Times Square"`, `"5-star hotels Bangkok Sukhumvit"`. Google's results are paged 20 at a time; the scraper pages on until `maxHotels` distinct hotels. |
| `hotels` | Specific properties without a search: Google Hotels URLs (`…/travel/hotels/entity/ChkI…`) or entity tokens from an earlier run. One offers call per property and stay. |
| `checkIn`, `checkOut` | `YYYY-MM-DD`, or relative to the run date for schedules: `"30 days"`, `"6 weeks"`, `"+30d"`, `today`, `tomorrow`. Nights = the difference. Past check-ins are rejected before anything is fetched. |
| `sweepDays` | Also price the same length of stay starting on each of the next N days (rate calendars). |
| `adults`, `childrenAges` | Occupancy per room; prices scale exactly as on Google. |
| `currency`, `language`, `country` | Any ISO currency for every price; Google UI language (`hl`); market (`gl`) — prices and available sources differ by market. |
| `maxHotels` | Distinct hotels per place and stay, up to 200 (one list call per 20). |
| `includeOffers` | Fetch every source's rate per hotel (one extra call per hotel). |
| `offerLevel` | `sources`: one row per source, lowest rate (about 5–25 rows per hotel). `rooms`: every source × room × rate with room names and cancellation deadlines (about 50–100 rows per hotel). |
| `maxOffersPerHotel` | 0 = every source; N = only the N cheapest rows per hotel (cost control). |
| `proxyConfiguration` | Apify datacenter proxies work; keep the default. |
| `sessions`, `perIp` | Parallel proxy sessions and requests per second per IP (defaults 4 and 0.5). |

#### Example: hotel prices in a city for a stay

```json
{ "queries": ["hotels in Lisbon"], "checkIn": "2026-10-03", "checkOut": "2026-10-06", "adults": 2, "currency": "USD", "maxHotels": 60 }
```

#### Example: rate parity for your own properties, scheduled daily, always 30 days out

```json
{ "hotels": ["https://www.google.com/travel/hotels/entity/ChkIhLCQwvjO2IYWGg0vZy8xMXE0bTZieDkyEAE"], "checkIn": "30 days", "checkOut": "32 days", "sweepDays": 6, "currency": "EUR", "offerLevel": "sources" }
```

#### Example: cheapest weekend in the next two months for a family

```json
{ "queries": ["family hotels Orlando near Disney"], "checkIn": "2026-10-02", "checkOut": "2026-10-04", "sweepDays": 56, "adults": 2, "childrenAges": [5, 9], "currency": "USD", "maxHotels": 20, "includeOffers": false }
```

### Output

`hotel` row (the Console's **Hotels** and **Offers by source** views show the same rows as tables; the dataset schema documents every field):

```json
{ "type": "hotel", "query": "hotels in Lisbon", "check_in": "2026-10-03", "check_out": "2026-10-06", "nights": 3, "adults": 2, "children": 0, "currency": "USD",
  "rank": 1, "name": "The Central House Lisbon Baixa", "hotel_id": "10088532857338925820", "entity_id": "ChkIg-b2ismUj7M1Gg0vZy8xMWg3MThreGg1EAE",
  "stars": 2, "class_label": "2-star hotel", "rating": 4.3, "reviews": 727, "lat": 38.7131, "lng": -9.1368, "types": ["hostel"],
  "nightly": 81.81, "nightly_display": "$82", "total": 245, "total_display": "$245", "deal": "19% less than usual", "source": null,
  "website": "https://www.thecentralhousegroup.com/", "maps_url": "https://maps.google.com/?cid=3848859359889388291", "thumbnail": "https://lh3.googleusercontent.com/gps-cs-s/…",
  "google_url": "https://www.google.com/travel/hotels/entity/ChkIg-b2ismUj7M1Gg0vZy8xMWg3MThreGg1EAE", "total_results": 15000, "fetched_at": "2026-08-25T14:03:11+00:00" }
```

`offer` row (one per source with `offerLevel: "sources"`; per room and rate with `"rooms"`):

```json
{ "type": "offer", "name": "Hyatt Regency Lisbon", "entity_id": "ChoI4cjBy-KGurGyARoNL2cvMTFtdnFfdncydhAB", "check_in": "2026-10-03", "check_out": "2026-10-06", "nights": 3, "adults": 2, "children": 0, "currency": "USD",
  "source": "Booking.com", "source_id": 184, "official": false, "room": null, "nightly": 569.35, "total": 1708.05, "max_guests": null,
  "free_cancel": null, "free_cancel_until": null, "link": "https://www.google.com/travel/lodging/clk?pc=…", "partner_url": "https://www.booking.com/hotel/pt/hyatt-regency-lisbon.html?checkin=2026-10-03&checkout=2026-10-06…", "lowest": true, "fetched_at": "2026-08-25T14:03:14+00:00" }
```

Rows with `"lowest": true` are each source's cheapest rate; official-site rows carry the hotel's booking engine URL with your dates in `partner_url`. A source is keyed by `source_id` — a name such as Holidu or Booking.com can appear twice for one property when Google lists both its official listing (`official: true`) and its marketplace rate. Properties given in `hotels` are answered from their offers page: the `hotel` row carries name, headline nightly rate and stay total; star class, rating and coordinates come from place searches only.

`status` row (never charged):

```json
{ "type": "status", "query": "hotels in Lisbon", "hotel": null, "check_in": "2026-10-03", "check_out": "2026-10-06", "hotels": 25, "priced": 24, "offers": 310, "duplicates": 0, "offer_errors": 0, "error": null, "fetched_at": "2026-08-25T14:03:20+00:00" }
```

### How much does it cost?

Pay per event, only for priced rows: a `hotel` row (a hotel with a price for your dates) and an `offer` row (one source's rate). Sold-out hotels, empty searches and `status` rows are free, and a hotel and stay is billed once per run even when overlapping searches return it twice. A city search of 60 hotels with source-level offers is a few hundred rows; a daily parity check of ten properties with seven check-in days is about 70 hotel rows plus their offers. Apify's platform usage for a run of that size is a fraction of a cent — the runs above cost $0.001–$0.003 in compute. The exact per-row prices are on this page's pricing tab, and `maxOffersPerHotel` caps the offer rows when you only need the cheapest few sources.

### Google Hotels API or scraper: how this compares

Google has no public Google Hotels API for reading prices: its Hotel APIs (Hotel Prices, Hotel Ads, Book on Google) are partner feeds for hotels that *send* prices to Google. Reading prices back means a scraper or a SERP API vendor.

- **SerpApi Google Hotels API, DataForSEO, SearchApi, Bright Data** sell a Google hotel price API per search. They return the search page; per-source rates and room-level offers usually need a second product or are not exposed, and you pay per search whether or not it had results.
- **This scraper** returns hotels *and* every source's rate as flat rows, bills per priced row, handles paging to 200 hotels, occupancy including children's ages, any currency and market, relative dates for schedules, and property mode for your own hotels. It runs inside Apify, so scheduling, storage, webhooks and integrations come with it.
- **Writing your own with Python** ("scrape google hotels", "scrape hotel prices", "web scraping hotel prices"): Google Hotels renders prices through internal RPC calls, not HTML, and the payload formats change. The point of this actor is that someone keeps that working and reports failures as `status` rows instead of silent zeros.

If you searched for "Google Hotels API free" or a hotel price comparison API: there is a free tier on Apify, no API key from Google is needed, and empty results are never charged. As a hotel rates API it is one POST with the dates and a dataset of rows back.

### How to use it from Python, JavaScript, curl, n8n, Make or an AI agent

Run it from the Apify Console with the form, or programmatically. Replace `<TOKEN>` with your Apify API token.

Python:

```python
from apify_client import ApifyClient
client = ApifyClient("<TOKEN>")
run = client.actor("kestrel/google-hotels-prices").call(run_input={
    "queries": ["hotels in Lisbon"], "checkIn": "2026-10-03", "checkOut": "2026-10-06", "adults": 2, "currency": "USD", "maxHotels": 40})
rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())
hotels = [r for r in rows if r["type"] == "hotel"]; offers = [r for r in rows if r["type"] == "offer"]
cheapest = min((h for h in hotels if h["nightly"]), key=lambda h: h["nightly"])
print(cheapest["name"], cheapest["nightly_display"], cheapest["total_display"])
```

JavaScript / Node.js:

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<TOKEN>' });
const run = await client.actor('kestrel/google-hotels-prices').call({ hotels: ['https://www.google.com/travel/hotels/entity/ChkIhLCQwvjO2IYWGg0vZy8xMXE0bTZieDkyEAE'], checkIn: '30 days', checkOut: '32 days', currency: 'EUR' });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const official = Math.min(...items.filter(x => x.type === 'offer' && x.official).map(x => x.nightly));
const parityBreaches = items.filter(o => o.type === 'offer' && !o.official && o.nightly < official);
console.log(parityBreaches.map(o => [o.name, o.source, o.nightly]));
```

curl:

```bash
curl -X POST "https://api.apify.com/v2/acts/kestrel~google-hotels-prices/run-sync-get-dataset-items?token=<TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"queries": ["hotels in Lisbon"], "checkIn": "2026-10-03", "checkOut": "2026-10-06", "maxHotels": 20, "includeOffers": false}'
```

- **n8n, Make, Zapier**: use the Apify node/app with this actor's id, or a webhook on run finished, then read the dataset — a hotel price tracker or alert flow is three nodes.
- **AI agents and MCP**: the actor is available through the Apify MCP server and Apify AI; the README, input schema and flat row types are written so an agent can ask "hotels in Lisbon under $150 from Oct 3 to 6 with free cancellation" and filter the rows.
- **Google Sheets, BigQuery, Airtable**: export the dataset from the run page or through Apify's integrations.

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

The scraper reads publicly displayed prices — the same figures any visitor sees without logging in — and stores no personal data: rows describe hotels, sources and rates, not people. Collecting public pricing for analysis and monitoring is common practice in the hotel industry (every rate shopping tool does it), but terms of service and local law differ; check that your use complies, and use the data for your own analysis rather than republishing it as Google's.

### Limits and honest notes

- A place search pages through Google's ranking 20 at a time up to `maxHotels` (200); neighbourhood or landmark queries add coverage beyond that.
- Prices are what Google Hotels shows for the market (`country`) and currency you choose; whether taxes and fees are included follows Google's display rules for that market. The `total` is the stay total Google shows.
- Sources per hotel vary by market and day (typically 5–25 with US settings). Sold-out hotels appear as `hotel` rows without a price and are not charged.
- Google changes its internal formats occasionally; a daily canary run watches for that, the actor is rebuilt within days, and every run reports `status` rows so a failure is visible rather than a silent zero.
- **Google never fails a place search.** An unrecognised or misspelt place is silently matched to somewhere else and answered with real hotels, which are delivered and billed like any other row. There is no signal in Google's response that says "I did not find that place", and a fuzzy-matched nonsense string can return a cluster as tight as a genuine region, so this cannot be detected reliably enough to refuse the run without also breaking legitimate broad searches like `"Portugal"` or `"California"`. Each place `status` row therefore carries `spread_km` — the median distance of the returned hotels from their centre. A city is single digits, a region tens, a country a few hundred; anything in the thousands almost certainly did not resolve. Above 500km the run logs a warning. Pass an exact place name or a Google Hotels entity URL when it matters, and check `spread_km` and each hotel's `lat`/`lng` before trusting a run.

### FAQ

#### Does it need a Google Hotels API key or a Google account?

No. There is no public Google Hotels API for reading prices; the scraper uses the public results page through Apify's proxies. No login, cookies or API key.

#### Can I get hotel price history and price alerts from Google Hotels?

Google's own tracker keeps history and alerts inside Google. Schedule this scraper (daily, with relative dates) and every run appends dated rows to your dataset — that is your price history — and an Apify integration (n8n, Make, Zapier, webhook) turns a drop into an alert.

#### How is this different from Google's "Track hotel prices" feature?

Google's feature emails you about the listings it chooses to watch and does not let you pick sources or export data. This scraper returns every source's rate for the exact dates, occupancy and currency you set, as rows you own.

#### Which booking sites are covered?

Whatever Google Hotels lists for that property and market: Booking.com, Expedia, Hotels.com, Agoda, Trip.com, Priceline, Kayak, eDreams, Vio.com, the official site and dozens of regional OTAs. The `source` name and `source_id` come straight from Google.

#### Does it include taxes and fees?

It returns the nightly price and the stay total Google Hotels displays for your market. In some markets Google shows all-in prices, in others taxes are added later; set `country` to the market you sell in and compare like with like.

#### How many hotels can one run return?

Up to 200 per place search, or as many properties as you list in `hotels`, times the number of stays (`sweepDays`). A run stops cleanly when it reaches the spending limit you set on the run.

#### Why do prices differ from what I see in my browser?

Google prices depend on market, currency, occupancy, dates and sometimes the device. Match `country`, `currency`, `adults`, `childrenAges` and the dates, and compare the `total` for the stay rather than a headline nightly figure.

#### Can I use it as a hotel price scraper for Booking.com or Expedia specifically?

Yes for prices: each `offer` row names its source, so filtering `source == "Booking.com"` gives you Booking.com's rate per hotel and stay, and likewise for Expedia, Agoda or Hotels.com — without scraping each site separately. For reviews or room descriptions use a Booking.com scraper or Expedia scraper built for that site.

#### Is there a free tier?

Yes: Apify's free plan covers small runs, and this scraper never charges for a run that returns no priced rows.

Last verified working: 2026-08-29.

### Related scrapers

Hotel prices are one side of a trip. These read the rest of it, and they share the same row shape, the same pay-per-delivered-row billing and the same scheduling story:

- **[Hotel Rate Parity Checker](https://apify.com/kestrel/hotel-rate-parity)** — the same comparison as one row per property and stay with the parity math done: cheapest and dearest source, spread, and which OTAs undercut the official site by how much.
- **[Google Flights Scraper](https://apify.com/kestrel/google-flights-prices)** — airfare for a route and date, with a cheapest-day sweep.
- **[Airbnb Scraper](https://apify.com/kestrel/airbnb-prices-calendar)** — Airbnb prices, availability calendars and occupancy.
- **[Airbnb Reviews Scraper](https://apify.com/kestrel/airbnb-reviews-scraper)** — every guest review of an Airbnb listing, with translations.
- **[Agoda Reviews Scraper](https://apify.com/kestrel/agoda-reviews-scraper)** — Agoda hotel reviews with separate positives and negatives.

All of them bill per delivered row, never charge for rows a filter or a spending limit removed, and write an Apify dataset you can export to CSV, Excel or JSON.

# Actor input Schema

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

Free-text place searches, exactly as you would type them into Google Hotels: "hotels in Lisbon", "hotels near Times Square", "5-star hotels Bangkok". Google's results are paged 20 at a time; maxHotels sets how many distinct hotels to collect per place. Google always answers a place search: an unrecognised or misspelt place is silently matched to somewhere else rather than failing, and those hotels are delivered and billed. Pass an exact place name or a Google Hotels entity URL, and check the status row's spread\_km (and each hotel's lat/lng) before trusting the results.

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

Track exact properties without a search: Google Hotels URLs (https://www.google.com/travel/hotels/entity/ChkI…) or bare entity tokens, e.g. from an earlier run's `google_url`/`entity_id`. One offers call per hotel and stay; the hotel row comes from that page.

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

Check-in date: absolute YYYY-MM-DD or relative to the run date (e.g. 2026-10-03, or relative for schedules: "40 days", "6 weeks", "+40d"). Relative dates keep a scheduled run valid forever.

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

Check-out date: absolute YYYY-MM-DD or relative to the run date (e.g. 2026-10-06 or "42 days" — must be after check-in; nights = the difference). Relative dates keep a scheduled run valid forever.

## `sweepDays` (type: `integer`):

0 = only the stay above. N = also fetch the same length of stay starting on each of the next N days (a 3-night stay with sweepDays 6 = 7 stays, one per check-in day). Each stay is a separate list call.

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

Adults per room (prices scale with occupancy exactly as on Google).

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

Ages of children sharing the room, e.g. \[4, 9]. Leave empty for none.

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

3-letter currency code for every price (USD, EUR, GBP, JPY, AED, …). All rows are in this one currency.

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

Google UI language (hl): affects labels such as room names and deal notes.

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

Google market (gl): which country's Google Hotels answers. Prices and available sources differ by market.

## `maxHotels` (type: `integer`):

Distinct hotels to collect per place and stay. Google returns 20 per page; the actor pages on (one list call per 20) until this many or the results end.

## `includeOffers` (type: `boolean`):

For each priced hotel also fetch its offers page (one extra call per hotel): the rates from every source — Booking.com, Expedia, Agoda, the official site… — with free-cancellation flag, stay total and deep link.

## `offerLevel` (type: `string`):

sources = one row per source with its lowest rate (rate parity; ~5–15 rows per hotel). rooms = every source × room × rate, with room names and cancellation deadlines (~50–100 rows per hotel).

## `maxOffersPerHotel` (type: `integer`):

0 = every source. N = keep only the N cheapest rows per hotel (cost control; the official site row is kept only if it is among them).

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

Google accepts Apify datacenter proxies for these calls; keep the default. Residential is unnecessary.

## `sessions` (type: `integer`):

Concurrent egress IPs; each is paced at perIp requests per second.

## `perIp` (type: `number`):

Pace per proxy session. 0.5 is safe; raise carefully.

## Actor input object example

```json
{
  "queries": [
    "hotels in Lisbon"
  ],
  "hotels": [],
  "checkIn": "30 days",
  "checkOut": "32 days",
  "sweepDays": 0,
  "adults": 2,
  "childrenAges": [],
  "currency": "USD",
  "language": "en",
  "country": "us",
  "maxHotels": 20,
  "includeOffers": true,
  "offerLevel": "sources",
  "maxOffersPerHotel": 0,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "sessions": 4,
  "perIp": 0.5
}
```

# Actor output Schema

## `dataset` (type: `string`):

Hotel price rows, per-source rate rows and status rows. Charged rows are billed as delivered; status rows are always free.

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

One JSON record with the counts this run delivered and charged, its error and duplicate tallies, and its HTTP stats.

# 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 Lisbon"
    ],
    "hotels": [],
    "checkIn": "30 days",
    "checkOut": "32 days",
    "childrenAges": [],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("kestrel/google-hotels-prices").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 Lisbon"],
    "hotels": [],
    "checkIn": "30 days",
    "checkOut": "32 days",
    "childrenAges": [],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("kestrel/google-hotels-prices").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 Lisbon"
  ],
  "hotels": [],
  "checkIn": "30 days",
  "checkOut": "32 days",
  "childrenAges": [],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call kestrel/google-hotels-prices --silent --output-dataset

```

## MCP server setup

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

```

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/EOSwJ8qocxnXiVECB/builds/XjMfbeB58T1EubmCp/openapi.json
