# Google Flights Scraper — Cheapest Dates, Fares & Price Alerts (`cleancut/google-flights-cheapest-fares`) Actor

Find the cheapest Google Flights fare for many routes and flexible dates (a range or a whole month): price, airline, stops, times, Google's low/typical/high signal and 60-day history. Price alerts between runs. Pay per route × date.

- **URL**: https://apify.com/cleancut/google-flights-cheapest-fares.md
- **Developed by:** [Cleancut Data](https://apify.com/cleancut) (community)
- **Categories:** Travel, Automation, AI
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.04 / 1,000 cheapest fare (route × 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.
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 Flights Scraper — Cheapest Dates, Fares & Price Alerts

Find the **cheapest Google Flights fare for every route and every date** you care about: one route or hundreds, a single day, a date range or **any day of the month**. Each route × date gives you the **cheapest price, airline, stops, duration and times**, the next-cheapest alternatives, **Google's price signal (low / typical / high)** with the typical price range and **60-day price history**, and the **cheapest date of each route**. Schedule it with a monitor name and get **price-drop alerts** between runs.

**You only pay for fares delivered: one route × date = one result**, not one row per flight. Routes or dates that can't be priced are reported for free.

### What can it do?

- 🗺️ **Many routes in one run** — one per line (`EZE-MAD`, `NYC → LON`, `Buenos Aires - Madrid`) or an **origins × destinations matrix** (3 origins × 4 destinations = 12 routes).
- 📅 **Flexible dates** — single dates, ranges (`2026-12-01..2026-12-15`), **whole months** (`2026-12`) or days from today (`+30..+36`).
- 💸 **The cheapest fare per route × date** — price, airline and logo, flight numbers, stops, layovers, duration, local departure and arrival times, **bags included**, CO₂ and a **link that opens that exact search on Google Flights**.
- 🥇 **The cheapest date of each route** — every row says if it is the cheapest date (`isCheapestDate`) and how much more it costs (`priceVsCheapestDate`); a `ROUTES` summary gives the cheapest, most expensive and average price per route.
- 📉 **Google's price insights, free** — `priceLevel` (low / typical / high), the **typical price range** and the **lowest price on each of the last 60 days**.
- 🔁 **One-way or round trip** — round trips return after N nights; the price is the total for both flights and the **cheapest return flight** comes with it, free.
- 🔔 **Price alerts (monitor mode)** — every fare is compared with the previous run: `new`, `price_down`, `price_up` or `unchanged`, the previous price and the change in $ and %. Mark fares under your **target price**, or output **only the changes** (unchanged fares are not charged).
- 🧭 **Free plan mode** — check your routes and dates and see every search with its Google Flights link and the **maximum cost**, before paying anything.
- 🎛️ **Passengers, cabin and filters** — adults, children, infants, economy to first, max stops, airlines or alliances to include or exclude, max duration, departure time window, any currency and country.
- ⚡ **Fast & lightweight** — plain HTTP, no browser: **30 fares in about 30 seconds** on Apify. Airport codes, city codes and city names (`Buenos Aires`, `Londres`, `Bariloche`) all work.

### Who is it for?

- ✈️ **Travel agencies & OTAs** — publish the best fare per route and date, or quote a client the cheapest day of the month.
- 📰 **Flight-deal sites & newsletters** — scan dozens of routes every morning and keep only the fares Google marks as **low**.
- 🔔 **Price-alert apps** — schedule a monitor and push `price_down` fares or fares under a target to your users.
- 🧳 **Frequent travelers** — watch your routes and buy when the price drops.
- 🤖 **AI travel agents** — call it through the [Apify MCP server](https://mcp.apify.com); every field is documented for the model.

**Flight + hotel:** pair it with **[Google Hotels Rate Shopper](https://apify.com/cleancut/google-hotels-price-comparator)** to price the hotel for the same dates on every booking site — a complete trip quote from two scheduled runs.

### Input example

```json
{
  "routes": ["NYC-LON", "Buenos Aires - Madrid"],
  "departureDates": ["2026-12"],
  "tripType": "round-trip",
  "nights": 7,
  "adults": 2,
  "cabinClass": "economy",
  "maxStops": "1",
  "currency": "USD",
  "country": "US",
  "monitorName": "europe-december",
  "targetPrice": 600
}
```

Every field also accepts the names other flight Actors use (`origin`, `destination`, `departureDate`, `returnDate`, `cabin`, `stops`, `maxResults`), so existing integrations work as they are.

### Output example

A real fare (Buenos Aires → Madrid, searched on 4 Nov 2026), shortened:

```json
{
  "status": "ok",
  "route": "BUE → MAD",
  "origin": "Buenos Aires",
  "destination": "Madrid",
  "departureDate": "2026-12-04",
  "tripType": "one-way",
  "currency": "USD",
  "googleFlightsUrl": "https://www.google.com/travel/flights?tfs=CBwQAhoeEgoyMDI2LTEyLTA0agcIARIDQlVFcgcIARIDTUFEQAFIAXABmAEC&hl=en&gl=US&curr=USD",
  "airlineLogoUrl": "https://www.gstatic.com/flights/airline_logos/70px/AZ.png",
  "price": 560,
  "airline": "ITA, Air Europa",
  "flightNumbers": ["AZ 683", "UX 1048"],
  "stops": 1,
  "durationMinutes": 1125,
  "departureAirport": "EZE",
  "arrivalAirport": "MAD",
  "departureTime": "2026-12-04T22:20",
  "arrivalTime": "2026-12-05T21:05",
  "layovers": [{ "airport": "FCO", "city": "Rome", "durationMinutes": 205 }],
  "emissionsKg": 766,
  "priceLevel": "low",
  "typicalPriceLow": 620,
  "typicalPriceHigh": 960,
  "priceHistory": [{ "date": "2026-11-03", "price": 734 }, { "date": "2026-11-04", "price": 734 }],
  "cheapestNonstopPrice": 754,
  "flightsFound": 12,
  "alternatives": [{ "price": 560, "airline": "ITA", "flightNumbers": ["AZ 681", "AZ 64"], "stops": 1, "durationMinutes": 1810 }],
  "routeCheapestDate": "2026-12-04",
  "routeCheapestPrice": 560,
  "isCheapestDate": true,
  "priceVsCheapestDate": 0,
  "scrapedAt": "2026-11-04T12:32:03.978Z"
}
```

With a monitor name, each fare also has `changeType`, `previousPrice`, `priceChange`, `priceChangePercent` and `isBelowTarget`. Round trips add `returnDate`, `nights` and `returnFlight`.

#### Output views

The Output tab (and the API, with `?view=`) offers ready-made tables:

| View | What you get |
|---|---|
| **Cheapest fares** | One row per route and date: airline logo, price, airline, stops, duration, times, price level, cheapest-date flag and the Google Flights link |
| **Cheapest date per route** | Every date of each route with its price and how much more it costs than the route's cheapest date |
| **Alternatives** | The next-cheapest itineraries, one per row |
| **Flight legs** | Each flight of the cheapest itinerary: flight number, operating carrier, airports, times, aircraft, legroom |
| **Price insights** | Google's price level, typical range, cheapest nonstop, fastest option and CO₂ |
| **Price alerts** | Monitor mode: change vs the previous run and fares below your target |
| **Errors (free)** | Why a route or date could not be priced |

Every field is documented in the dataset schema (type, description and example), so AI agents and integrations know exactly what they get. The key-value store has a `ROUTES` record (cheapest date, most expensive date and average price per route) and a `SUMMARY` of the run.

### Errors (free)

Routes or dates that can't be priced produce a free row with `status: "error"` at the end of the dataset:

| errorCode | Meaning |
|---|---|
| `INVALID_ROUTE` | The line is not ORIGIN-DESTINATION (e.g. `JFK-LAX`) |
| `INVALID_LOCATION` | Unknown airport code or city name |
| `SAME_ORIGIN_DESTINATION` | Origin and destination are the same |
| `INVALID_DATE` | The date line can't be read |
| `NO_FLIGHTS` | Google Flights has no priced flights for that route, date and filters |
| `BLOCKED` | Google showed an anti-bot check — lower **Parallel searches** or use the RESIDENTIAL proxy group |
| `CONSENT_REQUIRED` | European IP sent to Google's cookie page — use a US proxy |
| `SOURCE_ERROR` / `UNPARSABLE` | Google kept returning an internal error or an incomplete page (each search is retried up to 8 times, with a new IP, and once more at the end of the run) |

### Pricing

Pay per event — **you only pay for fares delivered** (one route × date, with its alternatives, price insights, history and return flight). Errors, plan mode and unchanged fares with “Output only price changes” are free.

| Your Apify plan | Price per 1,000 fares |
|---|---:|
| Every plan (Free, Starter, Scale, Business…) | **$0.04** |

Plus a start fee of $0.0003 per run (at the default 256 MB of memory). Example: **the cheapest day to fly in December** on one route (31 dates) costs about **$0.0015**; a daily price alert on 10 routes × 30 dates costs about **$0.36 a month**. Other flight scrapers charge per flight row, and one search returns 15–70 of them. Set **“Max fares in total”** or the run's maximum cost to cap spending, or run **plan mode** first to see the maximum.

### Tips

- **Find the cheapest day:** put a whole month (`2026-12`) in **Departure dates** and open the **Cheapest date per route** view, or read `ROUTES`.
- **Deal hunting:** schedule a daily run with a monitor name, turn on **Output only price changes** and filter `priceLevel = low` or `isBelowTarget = true`.
- **City vs airport:** `NYC`, `LON`, `PAR`, `TYO`, `BUE` and other city codes search every airport of the city; `JFK/EWR` searches exactly those airports.
- **Proxy:** searches go direct first (fastest) and only Google's temporary errors are retried through the proxy (Apify US datacenter by default) with a new IP. If you see `BLOCKED` rows, lower **Parallel searches**.
- **Integrations:** run it from Make, Zapier, n8n or the Apify API and send `price_down` fares to Slack, email or your app.

### Responsible scraping

The Actor only reads Google Flights' public search page (`/travel/flights?tfs=…`), which `robots.txt` allows. It does not open booking pages (`/travel/flights/booking`, disallowed), does not solve captchas or imitate a browser's fingerprint, and collects no personal data.

### FAQ

**Is the price the same as on Google Flights?** Yes: it is the lowest price Google Flights lists for that search, in your currency and country. Prices change constantly; the `googleFlightsUrl` opens the same search so you can check and book.

**What if I call it with an empty input?** It runs a one-date demo search (NYC → LON) instead of failing, so AI agents and quick API tests always get a result. Add your own routes to search them.

**Does it show where to book (airline vs. agency)?** No. Booking options live on Google's booking pages, which `robots.txt` disallows for automated access. Use the link to open the search on Google Flights.

**Why one result per route × date instead of per flight?** Because that is what you need to find the cheapest fare. You still get the alternatives, and you pay one result instead of 15–70 rows.

**Multi-city trips?** Not yet: Google loads them only through its signed internal API. Search each leg as a one-way route.

**How far ahead?** Up to about 330 days, like Google Flights itself.

### Changelog

- **0.1** — First release: many routes and an origins × destinations matrix, flexible dates (ranges, whole months, days from today), one-way and round trip with the return flight, alternatives, bags included, Google's price level, typical range and 60-day history, cheapest date per route, price alerts with a target price, free plan mode and 7 output views.

### More from Cleancut Data

- 🏨 **[Google Hotels Rate Shopper](https://apify.com/cleancut/google-hotels-price-comparator)**: what every booking site charges for your hotels and dates, with taxes, free cancellation and rate-parity gaps. Pair it with this Actor for flight + hotel quotes.
- 🎬 **[YouTube Transcript Scraper](https://apify.com/cleancut/youtube-transcript-scraper)**: transcripts in bulk from videos, channels, playlists and search, with SRT/VTT, AI-ready chunks, likes and publish dates.

# Actor input Schema

## `routes` (type: `array`):

One route per line, e.g. "JFK-LAX", "NYC → LON" or "Buenos Aires - Madrid". City codes and names search all airports of the city. Several airports in one search: "JFK/EWR-LHR". Empty (and no origins/destinations) = demo route NYC-LON.

## `departureDates` (type: `array`):

One per line: a date (2026-12-10), a range (2026-12-01..2026-12-15), a whole month (2026-12, "any day of the month") or days from today (+30, or +30..+36 for a week starting in 30 days). Past dates and dates more than 330 days ahead are skipped. Empty = 30 days from today.

## `tripType` (type: `string`):

One-way, or round trip returning after the number of nights below. Round-trip prices are the total for both flights.

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

Round trip only: days between departure and return (1–60). Example: 7 = depart 2026-12-10, return 2026-12-17.

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

Passengers aged 12 or more (1–9).

## `children` (type: `integer`):

Children aged 2 to 11.

## `infantsInSeat` (type: `integer`):

Infants under 2 with their own seat.

## `infantsOnLap` (type: `integer`):

Infants under 2 on an adult's lap (one per adult).

## `cabinClass` (type: `string`):

Cabin to price.

## `maxStops` (type: `string`):

Only itineraries with at most this many stops.

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

ISO currency code for prices (USD, EUR, GBP, MXN, BRL, ARS…).

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

Two-letter country code Google prices for (US, GB, ES, MX, AR…). Fares can differ by country.

## `origins` (type: `array`):

Airport codes, city codes or city names, one per line (EZE, NYC, Madrid).

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

Airport codes, city codes or city names, one per line. Every origin is searched to every destination.

## `airlines` (type: `array`):

Two-letter airline codes (AA, IB, LA…) or alliances (STAR_ALLIANCE, ONEWORLD, SKYTEAM), one per line. Empty = all airlines.

## `excludeAirlines` (type: `array`):

Two-letter airline codes or alliances to leave out, one per line.

## `maxDurationHours` (type: `integer`):

Skip itineraries longer than this, door to door (0 = no limit).

## `departureHourFrom` (type: `integer`):

Outbound flights leaving at or after this local hour (0–23). 0 = any time.

## `departureHourTo` (type: `integer`):

Outbound flights leaving before this local hour (1–24). Example: 6 and 12 = morning flights. 24 = any time.

## `maxAlternatives` (type: `integer`):

Next-cheapest itineraries to include with each fare (0–20).

## `includeReturnFlight` (type: `boolean`):

For round trips, also get the cheapest return flight for the cheapest outbound (times, airline, stops). Free; it adds one page per fare.

## `includePriceHistory` (type: `boolean`):

Google's lowest price for the search on each of the last 60 days. Turn off for smaller rows.

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

Give your monitor a name (e.g. "bue-europe-dec") to remember prices between runs. Each fare then gets changeType, previousPrice and priceChange. Leave empty to turn monitoring off.

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

With a monitor name, only output new fares and price changes. Unchanged fares are not saved and not charged.

## `targetPrice` (type: `integer`):

Mark fares at or below this price (in the chosen currency) with isBelowTarget = true, for alerts. 0 = off.

## `mode` (type: `string`):

"Search fares" prices every route × date. "Plan only (free)" checks your routes and dates and lists each search with its Google Flights link and the maximum cost, without searching or charging.

## `maxTotalResults` (type: `integer`):

Stop after this many route × date fares (0 = no limit). Each fare is one charged result.

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

Searches run at the same time (1–16). 16 tested on Apify: 20 round trips in under a minute. Lower it if you see BLOCKED errors.

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

Searches go direct first (fastest, ~0.5 s per page). When Google answers with a temporary error, the retries go through this proxy with a new IP each time. Apify Proxy with a US IP is the default (avoids Google's EU cookie page); switch to RESIDENTIAL only if many searches end in SOURCE_ERROR.

## Actor input object example

```json
{
  "routes": [
    "NYC-LON"
  ],
  "departureDates": [
    "+30..+36"
  ],
  "tripType": "one-way",
  "nights": 7,
  "adults": 1,
  "children": 0,
  "infantsInSeat": 0,
  "infantsOnLap": 0,
  "cabinClass": "economy",
  "maxStops": "any",
  "currency": "USD",
  "country": "US",
  "origins": [],
  "destinations": [],
  "airlines": [],
  "excludeAirlines": [],
  "maxDurationHours": 0,
  "departureHourFrom": 0,
  "departureHourTo": 24,
  "maxAlternatives": 5,
  "includeReturnFlight": true,
  "includePriceHistory": true,
  "onlyChanges": false,
  "targetPrice": 0,
  "mode": "fares",
  "maxTotalResults": 0,
  "maxConcurrency": 16,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `fares` (type: `string`):

All dataset items: cheapest price per route × date with airline, stops, times, Google's price level, the route's cheapest date and free error rows.

## `cheapestDates` (type: `string`):

Every searched date of each route with its price and how much more it costs than the route's cheapest date.

## `alternatives` (type: `string`):

The next-cheapest itineraries for each route and date, one per row.

## `priceAlerts` (type: `string`):

Monitor mode: change against the previous run (new, price down, price up, unchanged) and fares below the target price.

## `routes` (type: `string`):

JSON list with one entry per route: cheapest date and price, most expensive date, average price and dates with a low price level.

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

JSON record with the number of searches, fares, errors by code, retries and the cheapest route of the run.

# 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 = {
    "routes": [
        "NYC-LON"
    ],
    "departureDates": [
        "+30..+36"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("cleancut/google-flights-cheapest-fares").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 = {
    "routes": ["NYC-LON"],
    "departureDates": ["+30..+36"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("cleancut/google-flights-cheapest-fares").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 '{
  "routes": [
    "NYC-LON"
  ],
  "departureDates": [
    "+30..+36"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyCountry": "US"
  }
}' |
apify call cleancut/google-flights-cheapest-fares --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cleancut/google-flights-cheapest-fares"
        }
    }
}
```

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/cBMOJhTOXHnzWyLbe/builds/Z4ThRDZBoozHaf8mT/openapi.json
