# Google Flights Scraper - Fares, Routes & Price Monitoring (`thirdwatch/google-flights-scraper`) Actor

Scrape live Google Flights fares without a browser. Compare one-way and round-trip quotes across multi-route and flexible-date matrices with segments, aircraft, emissions, stable IDs, and price-change monitoring.

- **URL**: https://apify.com/thirdwatch/google-flights-scraper.md
- **Developed by:** [Thirdwatch](https://apify.com/thirdwatch) (community)
- **Categories:** Travel, Automation
- **Features:** Limited permissions
- **Stats:** 20 total users, 4 monthly users, 89.5% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.12 / 1,000 flight itineraries

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 — fares, flexible dates, and price monitoring

### What you get

Search live Google Flights results without running a browser. Compare one-way and round-trip quotes; scan up to 120 route/date combinations in one run; and publish only new or price-changed fares on a schedule.

The Actor returns one structured row per unique priced flight choice with price, airline, airports, exact times, stops, duration, aircraft, layovers, carbon emissions, a stable ID, and the matching Google Flights URL.

### Why use this Actor?

- **Fast, reliable extraction:** uses the fastest connection available and only falls back when needed.
- **Route matrix:** compare many routes against the same date or date window in one run.
- **Flexible-date fare calendar:** search every day or week across a date range.
- **Real fare monitoring:** stable itinerary IDs let scheduled runs emit only new itineraries or changed prices.
- **Failure-safe batches:** one failed route/date fails the run by default instead of quietly returning an incomplete comparison.
- **Low-cost by design:** priced well below the established rate for Google Flights data on Apify, without cutting route-matrix or fare-monitoring features.

### Quick start

#### One-way search

```json
{
  "origin": "JFK",
  "destination": "LAX",
  "departureDate": "2026-08-15",
  "maxResults": 50
}
```

#### Round trip

```json
{
  "origin": "LHR",
  "destination": "JFK",
  "departureDate": "2026-09-10",
  "returnDate": "2026-09-17",
  "cabinClass": "business",
  "currency": "GBP"
}
```

#### Compare routes across flexible dates

```json
{
  "routes": ["JFK-LAX", "EWR-LAX", "JFK-SFO"],
  "dateRangeStart": "2026-08-15",
  "dateRangeEnd": "2026-08-21",
  "dateStepDays": 1,
  "maxStops": 1,
  "maxResults": 1000
}
```

That input performs 21 searches: three routes × seven departure dates. The hard safety limit is 120 searches per run.

### Output example

```json
{
  "itinerary_id": "807951432bf709130c623a56",
  "search_label": "JFK-LAX 2026-08-15",
  "trip_type": "one-way",
  "primary_airline_code": "AA",
  "price": 234,
  "currency": "USD",
  "airlines": ["American"],
  "stops": 1,
  "total_duration_minutes": 422,
  "departure": "2026-08-15T08:04",
  "arrival": "2026-08-15T15:16",
  "origin": "JFK",
  "destination": "LAX",
  "segments": [
    {
      "origin": "JFK",
      "origin_name": "John F. Kennedy International Airport",
      "destination": "CLT",
      "destination_name": "Charlotte Douglas International Airport",
      "departure": "2026-08-15T08:04",
      "arrival": "2026-08-15T10:10",
      "duration_minutes": 126,
      "aircraft": "Boeing 737"
    }
  ],
  "carbon_emissions_grams": 384000,
  "typical_carbon_emissions_grams": 324000,
  "google_flights_url": "https://www.google.com/travel/flights/search?...",
  "observed_at": "2026-07-19T12:00:00+00:00"
}
```

### Fare monitoring

Use an Apify Schedule with the same input. The Actor derives a stable store from every fare-affecting input, so cabin, currency, passenger, and filter combinations cannot overwrite one another. Set `monitorStoreName` when you want an explicit human-readable watch key.

```json
{
  "origin": "DEL",
  "destination": "DXB",
  "departureDate": "2026-09-10",
  "monitorMode": "price-changes",
  "monitorStoreName": "del-dxb-september"
}
```

The first run emits every newly observed itinerary. Later runs emit only:

- `change_type: "new"` for a new itinerary;
- `change_type: "price_changed"` with `previous_price` when a known itinerary moves.

Unchanged scheduled runs write no dataset items and therefore incur no result charge.

### Input reference

| Input | What it controls |
| --- | --- |
| `origin`, `destination` | One route using three-letter IATA airport or city codes (`NYC`, `LON`); common city names such as `New York` are also accepted |
| `departureDate`, `returnDate` | Explicit one-way or round-trip dates in `YYYY-MM-DD` (`2026-12-1`, `2026/12/01` and `15 Dec 2026` also work) |
| `departureInDays`, `tripLengthDays` | Relative dates for reusable saved Tasks |
| `routes` | Many `ORIGIN-DESTINATION` pairs searched as a matrix (`JFK to LAX` and `JFK>LAX` also work) |
| `dateRangeStart`, `dateRangeEnd`, `dateRangeDays`, `dateStepDays` | Explicit or relative flexible-date searches |
| `adults`, `children`, `infantsInSeat`, `infantsOnLap` | Up to nine passengers |
| `cabinClass` | Economy, premium economy, business, or first |
| `maxStops`, `airlines` | Google-side stop and airline filters |
| `currency`, `language`, `market` | Result localization and regional availability |
| `maxResultsPerSearch`, `maxResults` | Per-search and whole-run output limits |
| `monitorMode`, `monitorStoreName` | Incremental new-fare and price-change output |
| `proxyMode` | Direct connection, a more resilient connection, or automatic fallback between the two |
| `proxyConfiguration` | Optional custom connection settings, used only by the resilient/fallback modes |
| `maxConcurrency` | Parallel route/date searches performed at once (advanced tuning) |
| `maxRetries` | Total attempts per route/date before giving up |
| `directRetries` | In Automatic mode, how many attempts try the faster connection before switching to the more resilient one |
| `failOnPartialError` | Mark a run as failed when some route/date searches could not be completed (the itineraries found are still saved). Off by default |
| `allowEmptyResults` | Kept for older saved inputs. A route/date with zero flights always finishes as a successful empty result |

### What is intentionally not claimed

Google changes the public response contract over time. This Actor currently returns the fields listed above. It does **not** claim to expose airline/OTA checkout URLs, baggage allowances, seat inventory, fare rules, or a guaranteed ticket price. `google_flights_url` reopens the same search; availability and prices can change before booking.

For round trips, Google first returns priced **outbound choices** for the requested return date. The record therefore has `trip_type: "round-trip"`, `return_date`, and both requested `search_legs`, while `segments` describes the outbound choice and `segments_scope` is `outbound_selection`. The return flight is selected on Google Flights after choosing an outbound option. Multi-city extraction is not advertised because Google's current public response does not provide the same stable itinerary list.

When Google Flights answers but lists no itineraries, the search is checked a second time and then reported as a successful empty result, with a status message on the run. Searches that could not be completed are listed in the log.

### Common workflows

1. **Daily fare alert:** one route, `monitorMode: price-changes`, daily Schedule, webhook on successful dataset items.
2. **Travel-agency comparison:** several origin airports in `routes`, one date, CSV export for a client shortlist.
3. **Flexible-date deal finder:** 14–30 day range, daily step, sort the dataset by price.
4. **Corporate route watch:** weekly route matrix with `maxStops: 0` and approved airline codes.

### Support

For a reproducible issue, include the Actor run ID, airport codes, dates, and the field or behavior you expected. Never post an Apify token or private booking information.

### Use cases

- Travel teams monitoring fares and building price-comparison tools
- Analysts comparing routes, airlines, and carriers
- Researchers building flight-price datasets

### Limitations

- Fares change in real time; a price captured during a run can move before you book.
- The Actor does not expose airline/OTA checkout URLs, baggage allowances, seat inventory, or fare rules — only the fields listed above.
- Multi-city search is not supported; only one-way, round-trip, and route/date matrices are.
- A run is capped at 120 route/date searches. A route/date with no flights finishes as a successful empty result.
- Flights that Google Flights lists without a fare (some domestic routes and far-future schedules) are skipped, because there is no price to return.

### Related Actors

- [Airbnb Scraper - Listings, Prices & Ratings](https://apify.com/thirdwatch/airbnb-scraper) — Thirdwatch
- [Booking.com Hotel Scraper - Prices, Ratings & Amenities](https://apify.com/thirdwatch/booking-hotel-scraper) — Thirdwatch
- [Ctrip / Trip.com Hotel Scraper - Prices, Ratings & Availability](https://apify.com/thirdwatch/ctrip-hotels-scraper) — Thirdwatch

Last verified: 2026-10

More scrapers at [thirdwatch.dev](https://thirdwatch.dev).

# Actor input Schema

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

Three-letter IATA airport or city code, for example JFK, LHR, or DEL (NYC or LON cover every airport in the city). Common city names such as New York or London are also accepted. Ignored when Routes are provided.

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

Three-letter IATA airport or city code, for example LAX, CDG, or DXB. Common city names are also accepted.

## `departureDate` (type: `string`):

Outbound date in YYYY-MM-DD. Leave empty to search 30 days from the run date. Formats such as 2026-12-1, 2026/12/01 or 15 Dec 2026 are also accepted.

## `departureInDays` (type: `integer`):

Used when Departure date is empty. Makes saved Tasks reusable; the default searches 30 days from each run date.

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

Optional return date in YYYY-MM-DD. Omit for a one-way search. Formats such as 2026-12-1, 2026/12/01 or 15 Dec 2026 are also accepted.

## `tripLengthDays` (type: `integer`):

Optional nights/days between outbound and return when Return date is empty. Useful in reusable saved Tasks.

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

Optional route list such as JFK-LAX and BOS-SFO (JFK to LAX and JFK>LAX also work). Every route is searched across every selected date.

## `dateRangeStart` (type: `string`):

Optional first outbound date in a fare calendar, in YYYY-MM-DD. Use together with Flexible-date end. Formats such as 2026-12-1, 2026/12/01 or 15 Dec 2026 are also accepted.

## `dateRangeEnd` (type: `string`):

Optional last outbound date in a fare calendar, in YYYY-MM-DD. The Actor searches every selected step in the range. Formats such as 2026-12-1, 2026/12/01 or 15 Dec 2026 are also accepted.

## `dateRangeDays` (type: `integer`):

Optional number of outbound dates starting at Departure date or Relative departure. Use instead of explicit range dates for reusable Tasks.

## `dateStepDays` (type: `integer`):

Days between flexible-date searches. Use 1 for a daily fare calendar or 7 for weekly sampling.

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

Number of adult passengers. Total passengers cannot exceed nine.

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

Number of child passengers.

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

Number of infants travelling in their own seat.

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

Number of lap infants. Cannot exceed the adult count.

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

Cabin used for all legs.

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

Optional stop filter applied to every leg: 0 for nonstop, 1 for up to one stop, or 2 for up to two stops.

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

Optional airline IATA codes such as DL, AA, BA, or EK.

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

ISO 4217 currency code used by Google Flights, for example USD, EUR, GBP, or INR.

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

Google Flights language code, for example en, de, fr, es, or hi.

## `market` (type: `string`):

Two-letter country code used for regional availability, for example US, GB, DE, or IN (UK is read as GB).

## `maxResultsPerSearch` (type: `integer`):

Per-route/date output cap after Google returns its itinerary list.

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

Hard cap across every route and date in this run.

## `monitorMode` (type: `string`):

Off returns every itinerary. New returns newly seen itineraries. Price changes returns new itineraries plus changed prices and previous_price.

## `monitorStoreName` (type: `string`):

Optional stable key-value store name. Use the same name for every scheduled run of one fare watch.

## `proxyMode` (type: `string`):

Automatic tries the fastest connection first and switches to a more resilient one only if needed. Direct is cheapest. The resilient option is the most reliable under heavy use.

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

Optional custom proxy settings, used for the fallback or resilient connection modes.

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

Parallel route/date searches. Keep this low for reliable direct HTTP access.

## `maxRetries` (type: `integer`):

Total request/parser attempts per route and date, including direct attempts and any residential fallback.

## `directRetries` (type: `integer`):

In Auto mode, exhaust this many low-cost direct HTTP attempts before using residential bandwidth.

## `failOnPartialError` (type: `boolean`):

Off by default: if some searches in a multi-route or multi-date run cannot be completed, the run still succeeds and saves every itinerary that was found, and the log lists the searches that were skipped. Turn on to mark such runs as failed (the itineraries found are still saved).

## `allowEmptyResults` (type: `boolean`):

Kept for compatibility with older saved inputs. A run where Google Flights answers but has no matching itineraries now always finishes successfully with an empty dataset and a status message.

## Actor input object example

```json
{
  "origin": "JFK",
  "destination": "LAX",
  "departureInDays": 30,
  "routes": [],
  "dateStepDays": 1,
  "adults": 1,
  "children": 0,
  "infantsInSeat": 0,
  "infantsOnLap": 0,
  "cabinClass": "economy",
  "airlines": [],
  "currency": "USD",
  "language": "en",
  "market": "US",
  "maxResultsPerSearch": 100,
  "maxResults": 10,
  "monitorMode": "off",
  "proxyMode": "auto",
  "maxConcurrency": 2,
  "maxRetries": 5,
  "directRetries": 3,
  "failOnPartialError": false,
  "allowEmptyResults": true
}
```

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("thirdwatch/google-flights-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("thirdwatch/google-flights-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 '{}' |
apify call thirdwatch/google-flights-scraper --silent --output-dataset

```

## MCP server setup

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