# Google Flights Scraper - Fares, Routes & Schedules (`cirkit/google-flights-scraper`) Actor

Scrape Google Flights without a login. Get every itinerary for any route and date: fare, airline, flight numbers, stops, layovers, aircraft, legroom, CO2 and whether the fare is cheap for that route. One-way and round trip, any currency.

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

## Pricing

from $0.70 / 1,000 flight 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

### What is Google Flights Scraper?

**Google Flights Scraper** lets you extract live airfares, schedules and routes from Google Flights, helping you track fare drops on the routes you care about, feed a travel product with real inventory, and answer "when is this route actually cheap" with data instead of a hunch.

- ✈️ **Track fares on autopilot:** price any route across a whole month of departure dates in one run, then schedule it daily and watch the curve move.
- 🧭 **Search whole cities, not single airports:** city codes such as NYC, LON and TYO cover every airport in the metro, so you see the cheapest way out of a region rather than the cheapest way out of one terminal.
- 💸 **Know if today's fare is good:** every row carries Google's own typical price for that route and date, plus the usual price range, so a fare is either cheap, normal or expensive instead of just a number.
- 🛬 **Get the whole itinerary, not a headline price:** flight numbers, aircraft type, each segment, every layover airport and how long you sit there.
- 🌱 **Compare emissions:** grams of CO2 per itinerary and per segment, against the typical emissions for that route.
- 🔁 **One run, many searches:** origins, destinations and dates are combined automatically, so three origins by two destinations by thirty dates is one input, not 180.

Google publishes no public flight search API. Google Flights Scraper reads the same data the website shows, with no login, no cookies and no API key, and returns every itinerary on the page rather than the three Google highlights at the top.

### What data does Google Flights Scraper extract?

- 💲 Fare for the whole party, in your chosen currency (`price`, `priceCurrency`)
- 🏷 Whether Google ranked it a best flight (`isBest`)
- ✈️ Airline names and code (`airlines`, `mainAirlineCode`)
- 🔢 Every flight number on the itinerary (`flightNumbers`)
- 🛫 Departure and arrival airports, codes and full names
- 🕓 Departure and arrival date and time, in local airport time
- ⏱ Total journey time in minutes and as readable text (`durationMinutes`, `durationText`)
- 🔁 Number of stops (`stops`)
- ⏳ Every layover: airport, code and how long you wait (`layovers`)
- 🧩 Per-segment detail: origin, destination, times, duration, airline, flight number, aircraft type, legroom, operating carrier and CO2 (`segments`)
- 🌱 CO2 for the itinerary, the typical CO2 for that route, and the percentage difference
- 📉 Google's typical price for the route and date, the usual price range, and how much cheaper than usual today is (`routeTypicalPrice`, `routeTypicalPriceLow`, `routeTypicalPriceHigh`, `routeSavingVsTypical`, `routePriceLevel`)
- 🔗 The Google Flights URL for the exact search, so any row can be opened and verified
- 🎫 Google's booking token for the itinerary (`bookingToken`)
- 🗓 The search that produced the row: origin, destination, dates, trip type, cabin, passenger counts, currency

### How to use Google Flights Scraper

1. Open the actor and enter one or more **origin** and **destination** airport codes, for example JFK and LAX.
2. Enter your **departure dates**. Use `2026-12-20` for a fixed date, or `+30d` for "30 days from whenever this runs", which keeps a scheduled run working forever.
3. For a round trip, add a **return date**. A single `+7d` prices a 7-night trip from every departure date you listed.
4. Set **Max results** so the cost is capped, and pick a currency.
5. Run it, then export to JSON, CSV or Excel, or pull it straight from the Apify API.

### Input

```json
{
  "origins": ["JFK", "EWR"],
  "destinations": ["LHR"],
  "departureDates": ["+30d", "+37d", "+44d"],
  "returnDates": ["+7d"],
  "cabinClass": "economy",
  "maxStops": "any",
  "adults": 1,
  "currency": "USD",
  "country": "us",
  "includeOtherFlights": true,
  "maxItems": 500
}
```

That input runs six searches: two origins by one destination by three departure dates, each priced as a 7-night round trip.

#### Relative dates

`departureDates` and `returnDates` accept `YYYY-MM-DD` or a relative offset such as `+30d`. A relative departure counts from the day the run starts. A relative return counts from its own departure date, so `+7d` always means a 7-night trip. Relative dates exist so a saved input or a daily schedule does not quietly go stale and start failing.

### Output

One row per itinerary. Trimmed for readability:

```json
{
  "searchOrigin": "JFK",
  "searchDestination": "LAX",
  "departureDate": "2026-10-23",
  "tripType": "one-way",
  "price": 239,
  "priceCurrency": "USD",
  "isBest": true,
  "airlines": ["Delta"],
  "mainAirlineCode": "DL",
  "flightNumbers": ["DL1915"],
  "departureDateTime": "2026-10-23T17:45:00",
  "arrivalDateTime": "2026-10-23T20:50:00",
  "durationMinutes": 365,
  "durationText": "6 hr 5 min",
  "stops": 0,
  "layovers": [],
  "segments": [
    {
      "departureAirportCode": "JFK",
      "departureAirportName": "John F. Kennedy International Airport",
      "arrivalAirportCode": "LAX",
      "arrivalAirportName": "Los Angeles International Airport",
      "departureDateTime": "2026-10-23T17:45:00",
      "arrivalDateTime": "2026-10-23T20:50:00",
      "durationMinutes": 365,
      "airline": "Delta",
      "flightNumber": "DL1915",
      "aircraft": "Boeing 767",
      "legroom": "31 in",
      "co2Grams": 228763
    }
  ],
  "co2Grams": 229000,
  "co2TypicalGrams": 377000,
  "co2PercentVsTypical": -34,
  "routeLowestPrice": 215,
  "routeTypicalPrice": 179,
  "routeTypicalPriceLow": 110,
  "routeTypicalPriceHigh": 235,
  "routePriceLevel": "typical",
  "searchUrl": "https://www.google.com/travel/flights?tfs=...",
  "scrapedAt": "2026-09-23T16:43:36Z"
}
```

Three table views ship with the dataset: **Overview** for route, date, fare, airline, stops and times; **Price watch** for each fare against the typical price for that route; and **Itinerary detail** for schedules, aircraft, layovers and emissions.

Times are local to the airport, which is how a ticket reads. Google publishes no UTC offset with them, and converting without one would silently shift every departure.

### How much does it cost to scrape Google Flights?

A flat **$0.70 per 1,000 results**. One result is one itinerary. There is no per-run charge and no platform usage on top.

| Results | Cost |
|---|---|
| 1,000 | $0.70 |
| 10,000 | $7.00 |
| 100,000 | $70.00 |

A full search on a busy route returns 30 to 160 itineraries, so pricing one route and date costs roughly $0.02 to $0.11.

**Monitoring mode is much cheaper.** Set `includeOtherFlights` to false and each search returns only the three to five itineraries Google ranks as best flights, which is about **$0.003 per route and date**. Checking 50 routes every day for a month costs around $4.50.

The cheapest comparable actor on the Store charges $1.00 per 1,000 plus $0.005 every time a run starts.

### Measured coverage

From QA runs on 2026-09-23 covering 600 itineraries across JFK, ORD, LHR and MIA, one way and round trip, economy and business, USD and EUR, through the Apify datacenter proxy:

| Field | Coverage | Note |
|---|---|---|
| `price`, `priceCurrency` | 100% | |
| `airlines`, `mainAirlineCode`, `flightNumbers` | 100% | |
| Departure and arrival times, `durationMinutes`, `stops` | 100% | |
| `segments` and every field inside them | 100% | 1,229 segments checked |
| `legroom` (per segment) | 97% | a few carriers do not publish it |
| `layovers` | 100% of itineraries with a stop | nonstop itineraries correctly have none |
| `co2Grams`, `co2PercentVsTypical` | 99.8% | |
| `routeTypicalPrice` and the price range | 83% | Google does not compute an insight for every route and date |

### Limits

- **One search is one route and one date.** Google Flights has no "cheapest month" feed behind this endpoint, so a 30-day sweep is 30 searches.
- **Round-trip fares are the total for the pairing Google shows.** Choosing a specific return leg happens after booking starts, which is past the point this actor reads.
- **No per-itinerary booking link.** `bookingToken` is Google's own opaque handle for the itinerary; resolving it into an airline or OTA deep link needs a second Google call this actor does not make. Every row does carry `searchUrl`, which reopens the exact search.
- **Dates beyond roughly 11 months** are rejected by Google. The row explains it rather than failing the run.
- **Fares move.** Two runs minutes apart can differ, because airline inventory does.
- **No seat maps, fare rules or baggage allowances.** Google does not expose them here.

### FAQ

#### Is it legal to scrape Google Flights?

Google Flights Scraper reads only public pages that anyone can open in a browser, with no account, no login and no cookies. It collects no personal data. Scraping publicly available information is generally lawful in the US and EU, but how you use the data is your responsibility, including compliance with Google's terms and with any local rules. If you are unsure, take legal advice. Apify's [ethical scraping guidance](https://blog.apify.com/is-web-scraping-legal/) is a good starting point.

#### Can I use Google Flights Scraper as an API?

Yes. Every actor on Apify is callable over HTTP. Start a run, poll it, and read the dataset, all from the [Apify API](https://docs.apify.com/api/v2). There is a ready-made API endpoint on the actor page with your token already filled in.

#### Can I use this in Python?

Yes, with `apify-client`:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("cirkit/google-flights-scraper").call(run_input={
    "origins": ["JFK"], "destinations": ["LAX"], "departureDates": ["+30d"], "maxItems": 100,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row["price"], row["mainAirlineCode"], row["durationText"])
```

#### How do I schedule Google Flights Scraper to run automatically?

Use Apify [Schedules](https://docs.apify.com/platform/schedules) and point it at a saved input. Set your departure dates as relative offsets such as `+30d` and `+60d` so a daily schedule always looks the same distance ahead instead of asking about a date that has already passed.

#### Can I integrate Google Flights Scraper with other apps?

Yes. Apify connects to Zapier, Make, n8n, Slack, Google Sheets, Airtable and plain webhooks, so a run can push new fares straight into a sheet or fire an alert when a price drops.

#### How do I watch a route for price drops?

Schedule the actor daily with `includeOtherFlights` set to false, which keeps only the best itineraries and costs about $0.003 per route and date. Each row carries `routeTypicalPrice` and `routePriceLevel`, so an alert can be as simple as "tell me when `routePriceLevel` is low".

#### Why did I get fewer results than expected?

Three common reasons. A `maxStops` filter of nonstop cuts most routes to a handful of itineraries. Business and first class have far less inventory than economy, so a business search on a thin route can return under ten rows. And `maxItems` applies across every search in the run, so a low cap with many routes stops before it reaches the later ones.

#### What happens if a route has no flights?

The run still succeeds and writes one row with `noResults` set to true and a `message` explaining why, so an empty result is never confused with a broken run. The same happens for an unrecognised airport code or a departure date in the past.

#### Do I need residential proxies?

No. The Apify datacenter proxy is enough, which is why this actor is cheap to run. The default proxy setting works as shipped.

#### Can I get a field that is not listed?

If it appears on the Google Flights results page, probably yes. Open an issue on the actor and say which field and which route shows it.

### You might also like

- [Airbnb Search Scraper](https://apify.com/cirkit/airbnb-search-scraper) for stays at the other end of the trip
- [Booking.com Search Scraper](https://apify.com/cirkit/booking-search-scraper) for hotel rates by city and date
- [Agoda Hotel Search Scraper](https://apify.com/cirkit/agoda-search-scraper) for Asia-Pacific hotel pricing
- [Tripadvisor Hotels Scraper](https://apify.com/cirkit/tripadvisor-hotels-scraper) for hotel ratings and reviews

### Changelog

**0.1** (2026-09-23) First release. One-way and round-trip search, city and airport codes, four cabin classes, stop filters, multi-passenger parties, any currency and market, per-segment detail, layovers, emissions and Google's own price insights.

# Actor input Schema

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

Departure airports as 3-letter IATA codes. City codes work too and cover every airport in the metro: NYC for JFK, LGA and EWR, LON for Heathrow, Gatwick, Stansted and Luton.

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

Arrival airports as 3-letter IATA codes. City codes work here too.

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

Dates as YYYY-MM-DD, or a relative offset such as +30d meaning 30 days from today. Relative dates keep a saved input and a scheduled run working forever instead of going stale.

## `returnDates` (type: `array`):

Leave empty for one-way searches. One value applies to every departure date, which is how you price a fixed-length trip across a whole month. A relative offset here counts from its own departure date, so +7d means a 7-night trip.

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

Which cabin to price. Business and first return far fewer itineraries on most routes.

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

Filter applied by Google before it builds the result set, so a nonstop-only search costs far fewer rows than filtering afterwards.

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

Adult passengers. Fares are the total for the whole party, exactly as Google shows them.

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

Passengers aged 2 to 11.

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

Under 2, travelling in their own seat.

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

Under 2, travelling on an adult's lap.

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

3-letter currency code for every price in the output, for example USD, EUR, GBP, JPY. Google converts server side, so no rate is applied afterwards.

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

2-letter country code for the Google Flights market. Fares and available carriers differ by point of sale.

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

2-letter language code for airport and airline names in the output.

## `includeOtherFlights` (type: `boolean`):

On by default: return every itinerary Google lists, typically 30 to 160 per search. Turn it off to return only the handful Google ranks as best flights, which cuts the cost of a monitoring run by roughly 95 percent.

## `maxItems` (type: `integer`):

Hard cap on rows across every search in the run. Leave empty for no cap.

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

Apify Proxy settings. The datacenter pool is enough for Google Flights; residential is not required.

## Actor input object example

```json
{
  "origins": [
    "JFK",
    "EWR"
  ],
  "destinations": [
    "LAX",
    "SFO"
  ],
  "departureDates": [
    "2026-12-20",
    "+45d"
  ],
  "returnDates": [
    "+7d"
  ],
  "cabinClass": "economy",
  "maxStops": "any",
  "adults": 1,
  "children": 0,
  "infantsInSeat": 0,
  "infantsOnLap": 0,
  "currency": "USD",
  "country": "us",
  "language": "en",
  "includeOtherFlights": true,
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `flights` (type: `string`):

Every itinerary this run collected as the Overview table: route, date, fare, airline, stops, duration and times.

## `priceWatch` (type: `string`):

The same itineraries reduced to the pricing columns, with each fare next to the typical price for that route, for deciding whether today is a good day to book.

## `itineraryDetail` (type: `string`):

Flight numbers, per-segment schedules, aircraft, layover airports and durations, and CO2 against the route average.

## `flightsCsv` (type: `string`):

The full result set as CSV, ready for a spreadsheet or a BI tool.

## `consoleRun` (type: `string`):

The Apify Console page for this run, including the live log.

# 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 = {
    "origins": [
        "JFK"
    ],
    "destinations": [
        "LAX"
    ],
    "departureDates": [
        "+30d"
    ],
    "cabinClass": "economy",
    "maxStops": "any",
    "adults": 1,
    "currency": "USD",
    "country": "us",
    "includeOtherFlights": true,
    "maxItems": 100,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("cirkit/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 = {
    "origins": ["JFK"],
    "destinations": ["LAX"],
    "departureDates": ["+30d"],
    "cabinClass": "economy",
    "maxStops": "any",
    "adults": 1,
    "currency": "USD",
    "country": "us",
    "includeOtherFlights": True,
    "maxItems": 100,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("cirkit/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 '{
  "origins": [
    "JFK"
  ],
  "destinations": [
    "LAX"
  ],
  "departureDates": [
    "+30d"
  ],
  "cabinClass": "economy",
  "maxStops": "any",
  "adults": 1,
  "currency": "USD",
  "country": "us",
  "includeOtherFlights": true,
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call cirkit/google-flights-scraper --silent --output-dataset

```

## MCP server setup

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