# Google Flights Scraper (`steadyscrape/google-flights-scraper`) Actor

Flight itineraries with prices, airlines, times, stops, aircraft and CO2 for any route and date, from the Google Flights results page. One-way and round trips, any cabin, up to nine travellers, your currency and market, price insights and a link per itinerary. No browser, no login.

- **URL**: https://apify.com/steadyscrape/google-flights-scraper.md
- **Developed by:** [Steady Scrape](https://apify.com/steadyscrape) (community)
- **Categories:** Travel, E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.20 / 1,000 itineraries

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 itineraries for any route and date, straight from the Google Flights results page: price, airlines, flight numbers, departure and arrival times, duration, stops and layovers, aircraft, legroom and CO2, plus Google's price insights (lowest fare, typical range, whether prices are high or low right now, and the 60-day price history). One-way and round trips, any cabin, up to nine travellers, in your currency and for your market. **Every search comes back as rows**, and when Google has nothing the row says why (`no_flights`, `invalid`, `blocked`) instead of an empty dataset. You pay only for itineraries.

No browser, no login, no API key: it reads the page Google serves, paces itself the way Google tolerates, and rotates IPs before Google's wall shows up.

### What you get

One row per itinerary, in Google's order (its "top departing flights" first, marked `isBest`):

- **The fare**: `price`, the total for all travellers in `currency`, exactly as Google shows it for `market`; `rank` and `isBest`.
- **The flights**: `airlines` / `airlineNames`, `stops`, `durationMinutes`, `departure` and `arrival` (local times, `YYYY-MM-DDTHH:MM`), `segments` (one per flight: airline, flight number, airports with names, local times, duration, aircraft, legroom, CO2 kg) and `layovers` (airport, city, minutes).
- **Round trips**: by default each row is an outbound with the lowest round-trip total, and its `url` opens the return options for it on Google Flights. With `includeReturnFlights` on, the best outbounds are expanded into one row per outbound + return pair (`returnSegments`, `returnDeparture`, `returnArrival`, `returnStops`, `returnDurationMinutes`), with the exact total and a link that has both flights chosen.
- **Emissions**: `emissions.co2Kg`, the typical value for the route and the difference in percent.
- **Price insights**: `priceInsights` (lowest fare found, usual fare, typical range, `level` high / typical / low) on every row, and `priceHistory` (lowest fare per day over the past two months) on the first row of each search.
- **What was asked**: `searchIndex`, `tripType`, `origin` / `originName`, `destination` / `destinationName`, `departureDate`, `returnDate`, `passengers`, `cabin`, `maxStops`, `currency`, `market`, `language`, `url`, `scrapedAt`.
- **`status` and `reason`**: `ok`, `no_flights` (Google lists none for that route and date), `invalid` (a date in the past or a code Google does not know), or `blocked` (every IP route was refused; unpaid).

### Input

| field | what it does |
|---|---|
| `origin`, `destination` | Airport codes (`JFK`) or metro codes (`NYC`, `LON`). |
| `departureDates` | One search per date. A flexible range is several dates. |
| `returnDate` or `stayNights` | Makes round trips: back on one date, or N nights after each departure. |
| `urls` | Searches copied from Google Flights (links with `tfs=`), searched as they are. |
| `adults`, `children`, `infantsInSeat`, `infantsOnLap` | Up to nine seated travellers. |
| `cabin` | `economy`, `premium_economy`, `business`, `first`. |
| `maxStops` | `any`, `nonstop`, `one`, `two`: Google's own filter. |
| `currency`, `market`, `language` | Prices in this currency for this point of sale (`us`, `de`, `br`), names in this language. |
| `includeReturnFlights`, `maxOutboundsToExpand` | Fetch the return options of the first N outbounds (one extra page each). |
| `maxItinerariesPerSearch` | Keep only the first N; 0 keeps all Google shows (usually 20–35). |
| `residentialFallback` | Retry through residential proxies when Google refuses the datacenter IPs. Default on. |

```json
{
    "origin": "JFK",
    "destination": "LAX",
    "departureDates": ["2026-11-10", "2026-11-11", "2026-11-12"],
    "stayNights": 7,
    "adults": 2,
    "cabin": "economy",
    "maxStops": "nonstop",
    "currency": "USD",
    "market": "us"
}
```

### Output example

```json
{
    "searchIndex": 1,
    "status": "ok",
    "reason": null,
    "tripType": "round_trip",
    "origin": "JFK",
    "originName": "John F. Kennedy International Airport",
    "destination": "LAX",
    "destinationName": "Los Angeles International Airport",
    "departureDate": "2026-11-10",
    "returnDate": "2026-11-17",
    "passengers": { "adults": 2, "children": 0, "infantsInSeat": 0, "infantsOnLap": 0 },
    "cabin": "economy",
    "maxStops": "nonstop",
    "currency": "USD",
    "market": "us",
    "language": "en",
    "rank": 1,
    "isBest": true,
    "price": 1066,
    "airlines": ["AA"],
    "airlineNames": ["American"],
    "stops": 0,
    "durationMinutes": 371,
    "departure": "2026-11-10T06:00",
    "arrival": "2026-11-10T09:11",
    "segments": [
        { "airline": "AA", "airlineName": "American", "flightNumber": "171", "from": "JFK", "fromName": "John F. Kennedy International Airport", "to": "LAX", "toName": "Los Angeles International Airport", "departure": "2026-11-10T06:00", "arrival": "2026-11-10T09:11", "durationMinutes": 371, "aircraft": "Airbus A321neo", "legroom": "31 in", "co2Kg": 324 }
    ],
    "layovers": [],
    "returnStops": null,
    "returnDurationMinutes": null,
    "returnDeparture": null,
    "returnArrival": null,
    "returnSegments": null,
    "returnLayovers": null,
    "emissions": { "co2Kg": 324, "typicalCo2Kg": 361, "differencePercent": -10 },
    "priceInsights": { "lowestPrice": 864, "usualPrice": 704, "typicalLow": 410, "typicalHigh": 820, "level": "high" },
    "priceHistory": [{ "date": "2026-09-10", "price": 348 }],
    "url": "https://www.google.com/travel/flights/search?tfs=…&hl=en&gl=us&curr=USD",
    "scrapedAt": "2026-09-18T12:00:00.000Z"
}
```

### Prices: what to expect

- **`price` is the total for every traveller** in the search, as Google shows it. Two adults pay twice a one-adult search, give or take fare classes.
- **Google prices by point of sale.** A fare seen from Germany is not the fare seen from the US, even in the same currency: set `market` to the country you would buy from, or the numbers will not match your own browser.
- **Round trips show the lowest total per outbound** until the return options are fetched; the pair rows carry the exact total.
- Prices change by the hour. `scrapedAt` says when the row was read, and `priceHistory` how the lowest fare moved.

### Use cases

- **Fare monitoring**: schedule a run per route and date set; alert when `price` or `priceInsights.lowestPrice` drops.
- **Flexible dates**: list the dates you could fly and compare the lowest fare of each search.
- **Route and airline analysis**: which carriers fly a route, with how many stops, at what times and what CO2.
- **Travel apps and content**: feed live fares and itineraries into a site, a spreadsheet or an agent, with a deep link per itinerary.

### Limits and honesty

- A search returns what Google shows on its first screen (typically 20–35 itineraries: its picks plus "other flights"). Use the stops filter, the cabin and the dates to narrow.
- The page's "more flights", the price graph and the date grid are not reachable without a Google session. A flexible range is one search per date here.
- Multi-city trips are not supported yet (paste a link and the first leg's options come back).
- Google's data is Google's: airline names and airport names come in the `language` you choose.

### Pricing

Pay per event: one `itinerary` event per row with status `ok`. Rows with any other status are free, and so is every request that gave nothing. Set a spending limit on the run and the Actor stops at it.

### Legal

The Actor reads publicly available fare listings that Google Flights shows to anyone, without logging in. It stores no personal data. Use the data in line with Google's terms and your local law; scheduled fare monitoring for your own routes is what it is built for.

# Actor input Schema

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

Airport code (<code>JFK</code>) or metro code (<code>NYC</code>, <code>LON</code>: every airport of the city).

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

Airport or metro code.

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

One search per date, <code>YYYY-MM-DD</code>. A flexible range is several dates here.

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

Makes every search a round trip back on this date. Leave empty for one-way, or use <b>Stay nights</b> when the dates differ.

## `stayNights` (type: `integer`):

Round trips returning this many nights after each departure date (instead of one return date for all).

## `urls` (type: `array`):

Searches copied from Google Flights (links with a <code>tfs</code> parameter). Each is searched as it is, with its own currency, market and language when the link carries them.

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

No description

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

No description

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

No description

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

One per adult at most.

## `cabin` (type: `string`):

No description

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

Google's own filter, applied in the search.

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

Three-letter code (<code>USD</code>, <code>EUR</code>, <code>GBP</code>). Prices come as totals for all travellers in this currency.

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

Two-letter country code (<code>us</code>, <code>de</code>, <code>br</code>). Google prices by point of sale: set the country you would buy from, or the prices will not be the ones you see in your own browser.

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

Language of airport and airline names (<code>en</code>, <code>es</code>, <code>pt-BR</code>).

## `includeReturnFlights` (type: `boolean`):

Google shows outbounds first, each with the lowest round-trip total. On, the Actor opens the return options of the best outbounds too (one extra page each) and gives one row per outbound + return pair with its exact total.

## `maxOutboundsToExpand` (type: `integer`):

How many outbounds (in Google's order) get their return options when the setting above is on.

## `maxItinerariesPerSearch` (type: `integer`):

Keep only the first N in Google's order (best flights first). 0: all Google shows (usually 20–35).

## `residentialFallback` (type: `boolean`):

When Google refuses the run's own IP and the datacenter proxies, retry through residential proxies (included in the price: you pay per row, not per proxy byte). Off: those searches come back with status <code>blocked</code>, unpaid.

## Actor input object example

```json
{
  "origin": "JFK",
  "destination": "LAX",
  "departureDates": [
    "2026-11-10"
  ],
  "adults": 1,
  "children": 0,
  "infantsInSeat": 0,
  "infantsOnLap": 0,
  "cabin": "economy",
  "maxStops": "any",
  "currency": "USD",
  "market": "us",
  "language": "en",
  "includeReturnFlights": false,
  "maxOutboundsToExpand": 5,
  "maxItinerariesPerSearch": 0,
  "residentialFallback": true
}
```

# Actor output Schema

## `itineraries` (type: `string`):

No description

## `summary` (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",
    "departureDates": [
        "2026-11-10"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadyscrape/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 = {
    "origin": "JFK",
    "destination": "LAX",
    "departureDates": ["2026-11-10"],
}

# Run the Actor and wait for it to finish
run = client.actor("steadyscrape/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 '{
  "origin": "JFK",
  "destination": "LAX",
  "departureDates": [
    "2026-11-10"
  ]
}' |
apify call steadyscrape/google-flights-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,steadyscrape/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/I0jTx7MNEszzKqZYk/builds/bLMCk0RlxF186o70p/openapi.json
