# Google Flights Scraper: Flight Prices & Fare Deals (`automatic/google-flights-deals-monitor`) Actor

Google Flights scraper: live one-way and round-trip prices for any route or pasted Google Flights link. Airline, stops, times, airports, duration, layovers, CO2 and Google's price outlook. Compare up to 14 departure dates; filter by cabin, passengers, stops and airlines.

- **URL**: https://apify.com/automatic/google-flights-deals-monitor.md
- **Developed by:** [Philip Kirkbride](https://apify.com/automatic) (community)
- **Categories:** Travel
- **Security:** Limited permissions
- **Stats:** 1 total users, 1 monthly users, 93.1% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.40 / 1,000 results

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 Flights Scraper: Flight Prices & Fare Deals

Get live flight prices from Google Flights for any route, one-way or round trip. Give a route (airport codes or city names) with optional dates, or paste a Google Flights link, and every itinerary on the results page becomes one row: price in your currency, airline, stops, departure and arrival airports with codes, times and dates, total duration, each layover with its airport and length, estimated CO2 emissions, a basic-economy flag and Google's price outlook for the search ("low", "typical" or "high").

Compare up to 14 departure dates in one run and get the cheapest fare for each day. Filter by cabin class, number of passengers, maximum stops and airlines. Each itinerary is returned once, even though Google lists some of them twice, so you never pay for a repeated fare.

Use it as a Google Flights API: send routes and dates, get back a clean dataset you can download as JSON, CSV or Excel, read from your own code, or refresh on a schedule for fare alerts. Every run fetches fresh prices.

### Quick Start

```json
{
  "origin": "JFK",
  "destination": "LHR",
  "departDate": "2027-01-12",
  "returnDate": "2027-01-19",
  "currency": "USD"
}
```

This run returns the round-trip itineraries Google Flights shows for New York to London, 12 to 19 January 2027: airline, stops, times, duration, layovers and the round-trip total for each. Leave out `returnDate` for a one-way search. Use `routes` to search several routes in one run, or `searchUrls` to reuse a search you already set up on Google Flights.

### Use cases

- **Fare alerts and price tracking**: re-run the same routes every day and watch the cheapest price and Google's price outlook (`low`, `typical`, `high`). Send an alert when a fare drops below your target.
- **Flexible-date search**: compare up to 14 departure dates and pick the cheapest day to fly, like a fare calendar.
- **Travel agencies and deal newsletters**: scan many routes from your home airports and publish the best fares.
- **Corporate travel and budgeting**: price recurring business trips by cabin, airline and number of stops.
- **Airline and route research**: fares, durations and nonstop availability by airline across routes, dates and currencies.
- **Greener trips**: compare itineraries by CO2 estimate and layover time.

### Input recipes

**One-way fares for a single day**

```json
{"origin": "JFK", "destination": "LAX", "departDate": "2027-01-19"}
```

**A weekend round trip priced in euros**

```json
{"origin": "LHR", "destination": "BCN", "departDate": "2027-01-22", "returnDate": "2027-01-25", "currency": "EUR"}
```

**Full itinerary detail per segment**

```json
{"origin": "JFK", "destination": "LAX", "departDate": "2027-01-19", "searchMode": "full"}
```

In `full` mode, segment details appear only when `legs_status` is `verified`; otherwise `legs` is absent.

**Cheapest day to fly: one row per departure date for a week**

```json
{"origin": "LIM", "destination": "MAD", "departDate": "2027-02-02", "departDateWindowDays": 7, "currency": "PEN"}
```

**A round trip of fixed length across two weeks of departure dates**

```json
{"origin": "MEX", "destination": "CUN", "departDate": "2027-02-02", "returnDate": "2027-02-09", "departDateWindowDays": 14, "currency": "MXN"}
```

Each date keeps the same 7-night trip: the return date moves with the departure.

**Nonstop business class for two**

```json
{"origin": "JFK", "destination": "LAX", "departDate": "2027-01-19", "cabinClass": "business", "adults": 2, "maxStops": 0}
```

**Only certain airlines, at most one stop**

```json
{"origin": "SCL", "destination": "BOG", "departDate": "2027-01-12", "maxStops": 1, "airlines": ["LA", "AV"], "currency": "COP"}
```

**Several routes in one run**

```json
{"routes": [{"origin": "MEX", "destination": "CUN"}, {"origin": "Lima", "destination": "Bogotá", "departDate": "2027-02-02"}], "currency": "MXN"}
```

**A search you set up on Google Flights**

```json
{"searchUrls": ["https://www.google.com/travel/flights?q=Flights%20to%20CDG%20from%20JFK%20on%202027-01-12%20through%202027-01-19"], "currency": "USD"}
```

Set up the search on google.com/travel/flights with the filters you want, copy the link from the address bar and paste it. The link keeps its own route, dates, passengers, cabin and filters; prices come back in the `currency` you choose.

### Input

| Input | Type | Default | Meaning |
| --- | --- | --- | --- |
| `routes` | array | `[]` | Routes to search. Each has `origin` and `destination` (airport code or city name) and optional `departDate` and `returnDate` (YYYY-MM-DD). One-way without `returnDate`, round trip with it. |
| `origin`, `destination` | string | `LIM`, `MAD` | Shortcut for a single route. Ignored when `routes` is set. |
| `departDate`, `returnDate` | string | empty | Dates for the single-route shortcut (YYYY-MM-DD). Leave `departDate` empty to let Google Flights pick a date. |
| `departDateWindowDays` | integer | `1` | Search this many consecutive departure dates from `departDate` (up to 14). The return date moves with it. With more than 1, each date returns its cheapest itinerary. |
| `searchUrls` | array | `[]` | Google Flights links (`google.com/travel/flights...`) for one-way or round-trip searches. Each link is one search, with its own filters. |
| `searchMode` | string | `deals` | `deals` returns itinerary fields. `full` may also include verified per-segment details in `legs`: flight numbers, marketing and operating airline, aircraft, legroom, airports, dates, times and duration. `legs_status` reports whether those details are available; unverified itineraries have no `legs`. |
| `maxResults` | integer | `25` | Maximum itineraries per search (1-100). |
| `currency` | string | `USD` | `USD`, `EUR`, `GBP`, `PEN`, `MXN`, `BRL`, `COP`, `ARS` or `CLP`. |
| `cabinClass` | string | `economy` | `economy`, `premium-economy`, `business` or `first`. |
| `adults`, `children` | integer | `1`, `0` | Passengers. Prices are the total for everyone (up to 9). |
| `maxStops` | integer | empty | `0` for nonstop only, `1` or `2` for at most that many stops. Empty means any number of stops. |
| `airlines` | array | `[]` | Only these airlines, as 2-character codes (`DL`, `IB`, `LA`, ...). |
| `requestDelaySecs` | number | `2` | Seconds to wait between searches. |

Cabin class, passengers, airlines and a 1 or 2 stop limit need 3-letter airport codes and a `departDate` on every route. Nonstop works with city names and without dates.

Dates must be valid `YYYY-MM-DD`, from UTC today minus one day through 330 days ahead (the extra day allows local same-day searches across UTC-12 to UTC+14); return dates cannot precede departure. This 330-day horizon is an actor-imposed conservative limit, not a verified Google Flights limit. Every day in a date window must remain within that horizon. Routes with malformed, past or out-of-horizon dates are skipped individually without producing or charging rows; their routes and reasons appear in the log, run status message and `OUTPUT.skippedRoutes`. If every route is invalid and no pasted links remain, the run fails with an input error. `maxResults` must be an integer from 1 to 100 (per search).

Route searches check the requested route, departure date, cabin and passenger count. Mismatched or unverifiable searches are skipped with a diagnostic code; if every search is rejected, the run fails without fare rows. Prefer three-letter airport codes for precise route selection. City-name searches cover supported metro areas, including Tokyo, London, New York and Mexico City; a city that cannot be confirmed may be rejected with `ROUTE_UNVERIFIABLE`.

For pasted links, consult `verification` before relying on the route, dates, cabin or passenger count. Unverified values are not confirmed facts; cabin and passenger fields can be null, and some date years remain unverified. Round-trip rows also carry `return_date_verified`: `true` means the requested return date was confirmed; `false` means it was not. Both can be returned, and the run status counts unverified return dates. Pasted-link searches do not provide a requested return date for this check.

### What it returns

One row per itinerary:

| Field | Meaning |
| --- | --- |
| `route` | The route searched, e.g. `LHR→BCN`, or the route of a pasted link. |
| `url` | The Google Flights search the row comes from. |
| `price`, `currency` | Displayed price in the requested currency. Passenger selection may be unverified on pasted links; consult `verification`. Round trips show the round-trip total. |
| `trip` | `one-way` or `round-trip`, always the trip type you searched. |
| `stops`, `airline` | `Nonstop`, `1 stop`, `2 stops` ..., and the airline shown on the itinerary. |
| `depart_airport`, `depart_airport_code`, `depart_time`, `depart_date`, `depart_date_iso` | Departure airport name and code, clock time, date as shown and as YYYY-MM-DD. |
| `arrive_airport`, `arrive_airport_code`, `arrive_time`, `arrive_date`, `arrive_date_iso` | The same for arrival. The arrival date shows overnight flights. |
| `duration`, `duration_minutes` | Total travel time as shown and in minutes. |
| `layovers` | One entry per stop: `airport`, `airport_code`, `city`, `duration`, `duration_minutes`, `overnight`. |
| `co2_kg`, `co2_vs_typical_pct` | Estimated emissions in kg, and percent versus a typical flight on the route (0 = average). |
| `is_basic_economy` | True for fares without overhead bin access. |
| `is_top_flight` | True when Google lists the itinerary among its top flights. |
| `price_level`, `cheapest_time_to_book` | Google's price outlook for the search (`low`, `typical`, `high`) and when booking is usually cheapest, when shown. |
| `search_depart_date`, `cabin_class`, `passengers` | Requested departure date (null for pasted links or undated searches), confirmed cabin and passenger count (null when unconfirmed). |
| `return_date_verified` | Optional, round-trip rows only (both modes): `true` when the requested return date is confirmed; `false` when it is not or no requested return date is available for checking. Rows can be returned either way; the run status counts unverified return dates. Absent on one-way rows. |
| `verification` | Optional object, emitted on every row: `route`, `date`, `cabin`, `passengers` are each `verified` or `unverified`. Unverified values are not confirmed facts; dates can have unconfirmed years. |
| `legs_status` | Full search mode only: `verified` when segment details are confirmed for the itinerary; `unverified` when they cannot be confirmed (no `legs` then). Absent in deals mode. |
| `legs` | Full search mode only: one entry per flight segment, in order — `flight_number` (displayed number), `marketing_airline`, `operating_flight_number` and `operating_airline` when the flight is operated by another carrier, `aircraft`, `legroom`, `legroom_inches`, the segment's own `depart/arrive_airport(_code)`, `depart/arrive_date_iso`, `depart/arrive_time` and `duration_minutes`. |
| `source`, `scraped_at` | `google.com/travel/flights` and the collection time (UTC, ISO 8601). |

### Output example

A full-search-mode row (Lima to Madrid, round trip 2 to 8 April 2027, collected on 29 October 2026). The default deals mode returns the same itinerary fields without `legs` and `legs_status`:

```json
{
  "route": "LIM→MAD",
  "url": "https://www.google.com/travel/flights?q=flights+from+LIM+to+MAD+on+2027-04-02+through+2027-04-08&hl=en-US&gl=US&curr=USD",
  "price": 1750,
  "currency": "USD",
  "trip": "round-trip",
  "stops": "Nonstop",
  "airline": "Iberia",
  "depart_airport": "New Jorge Chávez International Airport",
  "depart_airport_code": "LIM",
  "depart_time": "8:00 PM",
  "depart_date": "Friday, April 2",
  "depart_date_iso": "2027-04-02",
  "arrive_airport": "Adolfo Suárez Madrid-Barajas Airport",
  "arrive_airport_code": "MAD",
  "arrive_time": "2:20 PM",
  "arrive_date": "Saturday, April 3",
  "arrive_date_iso": "2027-04-03",
  "duration": "11 hr 20 min",
  "duration_minutes": 680,
  "layovers": [],
  "co2_kg": 570,
  "co2_vs_typical_pct": -9,
  "is_basic_economy": false,
  "is_top_flight": false,
  "price_level": "typical",
  "cheapest_time_to_book": "later, Oct 26 – Jan 24",
  "search_depart_date": "2027-04-02",
  "cabin_class": "economy",
  "passengers": 1,
  "verification": {
    "route": "verified",
    "date": "verified",
    "cabin": "verified",
    "passengers": "verified"
  },
  "source": "google.com/travel/flights",
  "scraped_at": "2026-10-29T00:00:00+00:00",
  "legs_status": "verified",
  "legs": [
    {
      "depart_airport_code": "LIM",
      "depart_airport": "New Jorge Chávez International Airport",
      "arrive_airport_code": "MAD",
      "arrive_airport": "Adolfo Suárez Madrid-Barajas Airport",
      "depart_date_iso": "2027-04-02",
      "arrive_date_iso": "2027-04-03",
      "depart_time": "8:00 PM",
      "arrive_time": "2:20 PM",
      "duration_minutes": 680,
      "legroom": "31 in",
      "legroom_inches": 31,
      "aircraft": "Airbus A350",
      "flight_number": "IB 126",
      "marketing_airline": "Iberia",
      "operating_flight_number": "LA 5391",
      "operating_airline": "LATAM"
    }
  ]
}
```

### Use it as a Google Flights API

Run it from your own code with the Apify API and read the itineraries straight back. For example, with `curl`:

```bash
curl -X POST "https://api.apify.com/v2/acts/automatic~google-flights-deals-monitor/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"origin": "JFK", "destination": "LAX", "departDate": "2027-01-19", "maxResults": 10}'
```

The same works from the Apify Python and JavaScript clients and from Make, Zapier and n8n. For fare alerts, save your routes as a task, schedule it daily in the Apify Console and send the results to a webhook, Slack, email or Google Sheets.

### FAQ

**Is there an official Google Flights API?** No. Google retired its public flight-search API (QPX Express) in 2018. This Actor returns the same itineraries and prices you see on google.com/travel/flights, as structured data.

**How fresh are the prices?** Every run searches Google Flights at run time. Nothing is cached between runs, so each row is the price shown at `scraped_at`.

**Are the prices for one person or everyone?** For everyone you set in `adults` and `children`. On a round trip, `price` is the round-trip total and the row describes the outbound flight.

**How do I find the cheapest day to fly?** Set `departDate` to the first date and `departDateWindowDays` to up to 14. Each date returns its cheapest itinerary, so the rows read like a fare calendar. Add `returnDate` to keep a fixed trip length.

**How many itineraries does one search return?** The ones Google Flights shows on its results page, usually 8 to 35 per search, capped by `maxResults`.

**Can I use city names instead of airport codes?** Yes, for plain searches and nonstop-only searches. Cabin class, passengers, airlines and a 1 or 2 stop limit need 3-letter airport codes and a `departDate`.

**Which currencies are supported?** `USD`, `EUR`, `GBP`, `PEN`, `MXN`, `BRL`, `COP`, `ARS` and `CLP`.

**Can I search multi-city trips or add lap infants?** No. Google Flights shows no prices for those searches here, so use one-way or round-trip searches, one per leg if needed.

**Does it include flight numbers, aircraft or baggage fees?** Flight numbers (displayed and operating), marketing and operating airlines, aircraft and legroom: yes, in `full` mode — itineraries with verified segment details carry one `legs` entry per segment, and `legs_status` marks the itineraries that could not be matched (they carry no `legs`). Baggage fees: no. Rows otherwise carry what Google shows on the results list: airline, times, stops, layovers, duration, emissions and the basic-economy flag (no overhead bin).

**Why does `price_level` differ between two currencies for the same route?** It is Google's own outlook as shown for that search and currency at that moment.

**What happens if a route returns nothing?** That search adds no rows; check the city spelling or use airport codes. Other searches in the run can still return fares. Review the run status and log for searches that were skipped. If every search is empty, the run fails instead of finishing with an empty dataset.

### Good to know

- With `departDateWindowDays` above 1, each date is a separate search and returns one row (its cheapest itinerary). Dates Google cannot price are skipped.
- Leaving out `returnDate` always runs a true one-way search with one-way prices.
- Many routes times 14 dates is many searches; at a few seconds each, keep large runs within the run timeout or split them into several tasks.
- Prices change constantly. Every run fetches fresh prices; nothing is stored between runs.

### Price

**$0.40 per 1,000 itineraries** ($0.0004 per row), plus **$0.00005 per run start**. A start is charged once per GB of memory, so the default 512 MB run is one start. Searches that return nothing add no row charge. Platform usage is included in these prices.

# Actor input Schema

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

Each route: origin and destination (IATA code or city name, e.g. LIM, Madrid), optional departDate and returnDate (YYYY-MM-DD, the current date in UTC-12 through UTC today plus 330 days: an actor-imposed conservative horizon, not a verified Google Flights limit; routes with invalid dates are skipped individually). One-way without returnDate, round trip with it.

## `origin` (type: `string`):

Shortcut when searching one route: sets routes\[0].origin. Ignored when routes is provided.

## `destination` (type: `string`):

Shortcut when searching one route: sets routes\[0].destination. Ignored when routes is provided.

## `departDate` (type: `string`):

YYYY-MM-DD, the current date in UTC-12 through UTC today plus 330 days (actor-imposed conservative horizon, not a verified Google Flights limit; routes with invalid dates are skipped individually); leave empty to let Google Flights pick a date.

## `returnDate` (type: `string`):

YYYY-MM-DD, within the current UTC-12 date through UTC today plus 330 days, and no earlier than departure (actor-imposed conservative horizon, not a verified Google Flights limit; routes with invalid dates are skipped individually); with departDate makes the shorthand route a round trip.

## `departDateWindowDays` (type: `integer`):

Search this many consecutive departure dates, starting at each route's departDate (the return date moves with it). With more than 1, each date returns its cheapest itinerary only. Needs departDate in YYYY-MM-DD.

## `searchUrls` (type: `array`):

Paste search links from google.com/travel/flights (one-way or round trip). Each link is one search, with the filters it already carries. Prices come in the currency selected below.

## `searchMode` (type: `string`):

deals returns the standard itinerary fields. full also adds per-segment detail (legs): each segment's flight number, marketing and operating airline, aircraft, legroom and its own airports, dates, times and duration.

## `maxResults` (type: `integer`):

Stop after this many priced itineraries per route.

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

ISO code for displayed prices.

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

Cabin to price. Anything other than economy needs airport codes and a departDate on every route.

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

Adult passengers. Prices are the total for all passengers. More than 1 needs airport codes and a departDate on every route.

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

Child passengers (2-11). Needs airport codes and a departDate on every route.

## `maxStops` (type: `integer`):

0 for nonstop only, 1 or 2 for at most that many stops. Leave empty for any number of stops. Nonstop works on every route; 1 or 2 need airport codes and a departDate.

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

Only show flights from these airlines, as 2-character codes (e.g. DL, IB, LA). Needs airport codes and a departDate on every route.

## `requestDelaySecs` (type: `number`):

Minimum seconds between route requests.

## Actor input object example

```json
{
  "routes": [],
  "origin": "JFK",
  "destination": "LAX",
  "departDate": "",
  "returnDate": "",
  "departDateWindowDays": 1,
  "searchUrls": [],
  "searchMode": "deals",
  "maxResults": 25,
  "currency": "USD",
  "cabinClass": "economy",
  "adults": 1,
  "children": 0,
  "airlines": [],
  "requestDelaySecs": 2
}
```

# Actor output Schema

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

No description

# 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 = {
    "origin": "JFK",
    "destination": "LAX"
};

// Run the Actor and wait for it to finish
const run = await client.actor("automatic/google-flights-deals-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 = {
    "origin": "JFK",
    "destination": "LAX",
}

# Run the Actor and wait for it to finish
run = client.actor("automatic/google-flights-deals-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 '{
  "origin": "JFK",
  "destination": "LAX"
}' |
apify call automatic/google-flights-deals-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automatic/google-flights-deals-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/cJipOzo5wBfJhxI0e/builds/eLerVMVSHqTZUzpZJ/openapi.json
