# Google Flights Scraper — Fares, Itineraries & Price Insights (`tortuga/google-flights-scraper`) Actor

Google Flights itineraries for any route and dates: total and per-person fares, airlines, flight numbers, segments, layovers, CO2, price insights and booking options.

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

## Pricing

from $10.00 / 1,000 flight searches

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 — Fares, Itineraries & Price Insights

Scrape **Google Flights** for any route and dates: every itinerary Google shows with its **total and per-passenger
fare**, airlines and **flight numbers**, every segment (airports, local departure and arrival times, duration,
aircraft, legroom), **layovers** (airport, length, overnight, change of airport), **CO2 emissions vs. typical**, the
**"Top flights"** flag and a Google Flights link, plus Google's **price insights** for the search: whether prices
are currently **low, typical or high**, the **typical price range** and the **60-day price history**. Round trips
come as complete itineraries (outbound + return) at Google's exact round-trip total. Optionally get each
itinerary's **booking options** (airline or travel agency, price, fare name).

Use it for fare tracking and price alerts, route and airline market research, travel-deal sites, corporate travel
budgeting and flight price datasets.

### What data does it extract?

| Field | Example | Notes |
|---|---|---|
| `price`, `priceExact`, `pricePerPassenger`, `currency` | `817`, `816.39`, `817`, `USD` | `price` as Google shows it (total for all passengers, rounded up); `priceExact` from Google's fare token |
| `tripType`, `isBest`, `position` | `round_trip`, `true`, `1` | `isBest` = in Google's "Top flights" |
| `airlines`, `airlineCodes`, `flightNumbers` | `["American", "British Airways"]`, `["AA", "BA"]`, `["AA 100", "BA 177"]` | all legs |
| `departureAirport`, `arrivalAirport` (+ `...Name`) | `JFK`, `LHR` | outbound leg |
| `departureTime`, `arrivalTime`, `duration`, `durationMinutes`, `stops` | `2026-11-10T18:25`, `2026-11-11T06:20`, `6 hr 55 min`, `415`, `0` | local airport times |
| `returnDepartureTime`, `returnArrivalTime`, `returnDurationMinutes`, `returnStops` | `2026-11-17T12:55`, ... | round trips |
| `legs[]` | `direction`, airports, times, duration, stops, `segments[]`, `layovers[]` | full detail per direction |
| `legs[].segments[]` | `flightNumber`, `airline`, airports, times, `durationMinutes`, `aircraft`, `legroom`, `seatType`, `arrivesNextDay`, `alsoSoldAs` (codeshares), `emissionsKg` | one per flight |
| `legs[].layovers[]` | `{"airport": "FLL", "city": "Fort Lauderdale", "durationMinutes": 93, "overnight": false, "changeOfAirport": false}` | |
| `emissionsKg`, `typicalEmissionsKg`, `emissionsDifferencePercent` | `549`, `344`, `60` | Google's CO2 estimate vs. a typical flight on the route |
| `priceLevel`, `lowestPrice`, `typicalPriceLow`, `typicalPriceHigh` | `high`, `720`, `480`, `690` | Google's price insights for the search |
| `priceHistory` | `[{"date": "2026-10-11", "price": 720}, ...]` | lowest price per day, last ~60 days |
| `googleFlightsUrl`, `searchUrl`, `bookingToken` | `https://www.google.com/travel/flights/booking?tfs=...` | open the itinerary or the search on Google Flights |
| `itineraryId` | `2026-11-10 AA100 / 2026-11-17 BA177 / economy / 1-0-0-0` | dates + flight numbers + cabin + passengers |
| `searchComplete` | `true` | `false` when Google never finished pricing the search (see Limitations) |
| `origin`, `destination`, `departureDate`, `returnDate`, `cabinClass`, `adults`, `children`, `infantsOnLap`, `infantsInSeat` | | the search |
| `bookingOptions` | `[{"seller": "American", "isAirline": true, "price": 817, "fareName": "Basic Economy", "website": "www.aa.com"}, ...]` | with **Include booking options** |

### How to scrape Google Flights

1. Enter **From** and **To**: airport codes (`JFK`, `LHR`), cities (`New York`, `Tokyo`), metro codes (`NYC`) or
   several airports (`JFK, EWR`). Add more routes in **More routes**, or paste Google Flights URLs.
2. Set the **departure date** (`2026-12-20`, or `+30 days` for a rolling date) and, for a round trip, the
   **return date**.
3. Choose passengers, **cabin class**, **stops**, airlines to include or exclude, a **max price**, the
   **currency** and the **country** Google prices for, and the **sort order**.
4. Run. Download JSON, CSV or Excel, or read the dataset through the API.

```json
{
  "origin": "New York",
  "destination": "London",
  "departureDate": "2026-12-18",
  "returnDate": "2027-01-04",
  "adults": 2,
  "cabinClass": "economy",
  "stops": "nonstop",
  "sortBy": "cheapest",
  "currency": "USD",
  "maxResultsPerSearch": 10
}
```

Example output (abridged, real data for JFK -> LHR, Nov 10-17):

```json
{
  "itineraryId": "2026-11-10 AA100 / 2026-11-17 BA177 / economy / 1-0-0-0",
  "tripType": "round_trip",
  "isBest": true,
  "price": 817,
  "priceExact": 816.39,
  "pricePerPassenger": 817,
  "currency": "USD",
  "airlines": ["American", "British Airways"],
  "flightNumbers": ["AA 100", "BA 177"],
  "departureAirport": "JFK",
  "arrivalAirport": "LHR",
  "departureTime": "2026-11-10T18:25",
  "arrivalTime": "2026-11-11T06:20",
  "duration": "6 hr 55 min",
  "stops": 0,
  "returnDepartureTime": "2026-11-17T12:55",
  "returnArrivalTime": "2026-11-17T16:00",
  "legs": [
    {"direction": "outbound", "flightNumbers": ["AA 100"], "segments": [{"flightNumber": "AA 100",
      "aircraft": "Boeing 777", "legroom": "31 in", "seatType": "Average legroom", "arrivesNextDay": true,
      "alsoSoldAs": ["IB 4218", "BA 1511", "AY 3772"], "emissionsKg": 398}], "layovers": []},
    {"direction": "return", "flightNumbers": ["BA 177"], "...": "..."}
  ],
  "emissionsKg": 716,
  "typicalEmissionsKg": 775,
  "emissionsDifferencePercent": -8,
  "priceLevel": "high",
  "lowestPrice": 720,
  "typicalPriceLow": 480,
  "typicalPriceHigh": 690,
  "priceHistory": [{"date": "2026-10-10", "price": 714}, {"date": "2026-10-11", "price": 720}],
  "googleFlightsUrl": "https://www.google.com/travel/flights/booking?tfs=...&hl=en&gl=us&curr=USD"
}
```

### One-way, round trip and multi-city

- **One way**: leave the return date empty. One request returns every itinerary Google shows for the day
  (typically 20-40), with the Top flights first.
- **Round trip**: Google first lists outbound flights priced as round-trip totals. For each outbound flight the
  actor asks Google for its return flights and outputs the best (or cheapest, per **Sort by**) **Return flights per
  outbound** as complete itineraries at Google's exact round-trip total. Set it to 0 to get only the outbound list.
- **Multi-city** searches are not supported: Google loads them through a streaming channel this actor does not use.

### Track flight prices: monitor changes on a schedule

Turn on **Only new or changed items**, set **fixed dates** for the trip you want to watch and save the input as a
task with a **Schedule** (e.g. daily at 8:00). Each run then outputs only itineraries that are new for this search
or whose **price changed**; unchanged itineraries are not output and not charged (the search itself is). New items
carry `changeType: "new"`, changed ones `changeType: "changed"` and `previousValues` with the old price
(`{"price": 817}`), so you can send an alert or a webhook only when a fare moves. An itinerary is identified by its
dates and flight numbers (plus cabin and passengers). With a relative date (`+30 days`) the travel date moves every
day, so every run reports the day's fares as new - good for a rolling daily fare feed, not for a change watch.
Give each watch its own **Monitoring key** if several schedules search the same route.

### Price insights: is now a good time to buy?

Every itinerary row carries Google's insights for its search: `priceLevel` (`low`, `typical` or `high`, the label
Google shows as "Prices are currently ..."), the **typical price range** (`typicalPriceLow`-`typicalPriceHigh`,
what this trip usually costs) and `priceHistory` - the lowest price for these dates on each of the last ~60 days.
Insights come with Google's default ranking and are the same for every row of a search.

### Does it need a login, an API key or a special proxy?

No. It reads Google Flights the way the Google Flights page does, through Apify's standard datacenter proxy: no
Google account, no API key, no paid SERP or residential proxy. A search is one ~75 KB request; a round trip adds
one per outbound flight; booking options add one per itinerary.

### Pricing

Pay per event: **$0.01 per search** (one route and its dates, including the price insights) plus **$0.0004 per
itinerary**. A full one-way search of ~30 itineraries costs about $0.022; ten complete round trips about $0.014.
**Include booking options** adds **$0.002 per itinerary** that has booking options. Platform usage (compute,
datacenter proxy) is billed by Apify and is a fraction of a cent per search.

### Limitations

- Google returns a curated set of itineraries per search (usually 20-40) and the actor outputs all of them.
  Sorting by price or duration re-orders that set (a price-sorted request to Google returned the same set).
- Amenity icons (Wi-Fi, power, entertainment) come as unlabeled codes and are not exported; legroom and seat type
  are.
- Fares are what Google shows for the country and currency you choose; booking sites can price differently.
- Searches **with children** (and now and then other multi-passenger round trips) are priced more slowly by
  Google: its quick answer often holds a single airline. The actor notices that (Google flags a finished search)
  and switches to the streaming request the Google Flights page itself uses, which takes 20-50 s per request; a
  round trip then needs that time per outbound flight too. Searches for adults only usually answer in under a
  second.

### Is it legal to scrape Google Flights?

The actor collects publicly visible fares and flight schedules without logging in, at a modest request rate. Flight
numbers, schedules and prices are business information, not personal data. Check the terms that apply to your use
of the data, especially for republishing.

# Actor input Schema

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

Where you fly from: an airport code (JFK), a city or metro area (New York, NYC, London) or several airports separated by commas (JFK, EWR, LGA). City names are resolved by Google itself.

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

Where you fly to: an airport code (LAX), a city (Paris, Tokyo) or several airports separated by commas.

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

YYYY-MM-DD, or relative to today like "+30 days" or "in 2 weeks" (a rolling date for scheduled runs). Empty = 30 days from today. Use a fixed date to watch one trip's fares.

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

Leave empty for a one-way search. For a round trip: YYYY-MM-DD or relative to today ("+37 days").

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

Optional: several searches in one run, e.g. \[{"origin": "SFO", "destination": "Tokyo", "departureDate": "2026-12-20", "returnDate": "2027-01-03"}]. Dates left out use the dates above. Passengers, cabin and filters below apply to every route. Clear From/To above to search only these.

## `startUrls` (type: `array`):

Optional: Google Flights search URLs (google.com/travel/flights/search?tfs=... or ?q=...). The route, dates, passengers, cabin and filters set in the URL are used. One-way and round trips.

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

Adult passengers (prices are totals for all passengers).

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

Child passengers aged 2-11.

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

Infants under 2 with their own seat.

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

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

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

Seat class to price.

## `stops` (type: `string`):

Maximum number of stops per direction.

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

Two-letter airline codes (BA, DL, LH) or alliances (STAR_ALLIANCE, ONEWORLD, SKYTEAM). Sent to Google like its airline filter. Empty = all airlines.

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

Two-letter airline codes to leave out (any flight segment by that airline drops the itinerary).

## `maxPrice` (type: `integer`):

Total price limit for all passengers in the chosen currency. Sent to Google and checked again on every itinerary.

## `sortBy` (type: `string`):

Order of the itineraries: Google's "Top flights" ranking (best first), cheapest, shortest, earliest departure or earliest arrival. For round trips it also picks which return flights are taken.

## `returnFlightsPerOutbound` (type: `integer`):

Round trips: for each outbound flight, how many return flights to output as complete itineraries priced at Google's exact round-trip total (one extra request per outbound flight). 0 = outbound flights only, with Google's cheapest round-trip total.

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

Optional cap per route (e.g. the 10 best or cheapest). Empty = every itinerary Google shows (usually 20-40).

## `includeBookingOptions` (type: `boolean`):

For each itinerary, also get Google's booking options: airline or travel agency, price and fare name (one extra request and a small extra charge per itinerary).

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

ISO currency code for all prices, e.g. USD, EUR, GBP, INR, JPY.

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

Two-letter country code Google prices for (gl), e.g. us, gb, de, in. Fares and booking options can differ by country.

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

Language of airport and airline names (hl), e.g. en, de, fr, es.

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

Stop after this many itineraries in total (all routes). Keeps cost predictable.

## `onlyNewOrChanged` (type: `boolean`):

Remember what earlier runs of this search returned and output only new items or items whose price/status changed. Use with a Schedule; unchanged items are not charged.

## `monitoringKey` (type: `string`):

Name for this watch, so several schedules on the same search stay separate; defaults to a key derived from the search input

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

Apify's standard datacenter proxy works (no paid SERP or residential proxy needed).

## Actor input object example

```json
{
  "origin": "JFK",
  "destination": "LAX",
  "departureDate": "+30 days",
  "adults": 1,
  "children": 0,
  "infantsInSeat": 0,
  "infantsOnLap": 0,
  "cabinClass": "economy",
  "stops": "any",
  "sortBy": "best",
  "returnFlightsPerOutbound": 1,
  "includeBookingOptions": false,
  "currency": "USD",
  "country": "us",
  "language": "en",
  "maxItems": 100,
  "onlyNewOrChanged": false,
  "proxyConfiguration": {
    "useApifyProxy": 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 = {
    "origin": "JFK",
    "destination": "LAX",
    "departureDate": "+30 days",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("tortuga/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",
    "departureDate": "+30 days",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("tortuga/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",
  "departureDate": "+30 days",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call tortuga/google-flights-scraper --silent --output-dataset

```

## MCP server setup

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