# Google Flights Scraper - Flight Prices & Price Calendar (`alom/google-flights-scraper`) Actor

Google Flights API alternative: every flight for your route and dates with price, airlines, flight numbers, times, stops, layovers and CO2, one-way or round trip, any cabin. Cheapest fare per date (price calendar), many routes per run, and price-drop monitoring.

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

## Pricing

from $0.25 / 1,000 flights

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 - Flight Prices & Price Calendar

Scrape **Google Flights** for any route and date: every itinerary Google lists, with the **price**, airlines,
**flight numbers**, departure and arrival times (with time zones), duration, **stops and layovers**, aircraft,
legroom and **CO2 emissions**, one-way or round trip, in any cabin class and currency. Or get Google's **price
calendar**: the cheapest fare for every departure date over the next weeks or months. Run many routes at once, and
schedule it to get **only the prices that changed**.

- **Pure HTTP against Google's own data**, no browser. Fast (about 1,600 flights from 12 routes in 35 seconds) and
  cheap to run.
- **Honest runs.** Bad input is caught before the run starts, unknown airports are named in the status message,
  and a run that could not deliver says "partial" or "failed" instead of "succeeded with 0 results".
- **Built for monitoring.** Relative dates (`+30`) keep schedules valid, and the monitor mode delivers only new or
  changed prices with the previous price.

### What can you use Google Flights data for?

- **Fare tracking and alerts:** watch a route every day and get a row only when the price moves.
- **Finding the cheapest dates:** the price calendar shows the lowest fare for each departure date in one run.
- **Travel apps, AI agents and dashboards:** clean JSON for your app, Google Sheets, BI tool or LLM workflow.
- **Market and route research:** which airlines fly a route, how often, nonstop or not, at what price and CO2.
- **Travel agencies and corporate travel:** compare options for many routes and dates in one run.

### Two modes

- **Flights** (default): what you see on Google Flights after searching a route and a date. One row per
  itinerary. For round trips Google first lists outbound flights priced as the cheapest **round-trip total**; turn on
  `includeReturnFlights` to also get the return flight that makes up that price.
- **Price calendar:** the cheapest fare per departure date, starting at your departure date, for `calendarDays`
  days (up to about 11 months, as far as Google sells). For round trips the trip length is kept (e.g. always 7 nights).
  One row per date.

### Input

| Field | What it is |
|---|---|
| `origin`, `destination` | Airport code (`JFK`), several (`JFK,EWR`), a city or country name (`New York`, `Japan`), or a metro code (`NYC`, `LON`) |
| `departureDate`, `returnDate` | `2026-11-20`, or relative (`+30` = 30 days from today, `tomorrow`). No return date = one-way |
| `routes` | More routes in the same run: `[{"origin": "LHR", "destination": "JFK", "departureDate": "+45"}]` |
| `mode`, `calendarDays` | `flights` or `calendar`; number of dates for the calendar (default 60) |
| `adults`, `children`, `infantsInSeat`, `infantsOnLap` | Passengers (max 9). Prices are the total for everyone |
| `cabinClass` | `economy`, `premium_economy`, `business`, `first` |
| `maxStops` | `any`, `0` (nonstop), `1`, `2` |
| `airlines` | Only these airlines (`DL`, `BA`) or alliances (`ONEWORLD`, `SKYTEAM`, `STAR_ALLIANCE`) |
| `sortBy`, `maxResults` | `best`, `price`, `duration`, `departure`, `arrival`, `emissions`; flights per route (max 300) |
| `currency`, `country`, `language` | e.g. `EUR`, `DE`, `de` |
| `onlyNewSinceLastRun`, `monitorName` | Monitoring: deliver only new or changed prices |

```json
{
    "origin": "New York",
    "destination": "LHR",
    "departureDate": "+30",
    "returnDate": "+37",
    "adults": 2,
    "cabinClass": "economy",
    "maxStops": "1",
    "maxResults": 50,
    "includeReturnFlights": true,
    "currency": "USD"
}
```

### What data does Google Flights Scraper extract?

#### Flight rows

| Field | What it is |
|---|---|
| `price`, `currency`, `priceType` | Total price for all passengers; `one_way_total` or `round_trip_total` |
| `isBest`, `isCheapest`, `rank` | Google's "top flights" mark, the cheapest fare of this search, position after sorting |
| `airlines`, `airlineCodes`, `flightNumbers` | e.g. `["Delta"]`, `["DL"]`, `["DL 713"]` |
| `departureAirport`, `arrivalAirport` (+ `...Name`) | IATA codes and airport names |
| `departureDate`, `departureTime`, `arrivalDate`, `arrivalTime` | Local dates and times |
| `departureDateTime`, `arrivalDateTime` | The same with the airport's UTC offset, e.g. `2026-11-16T22:40:00-08:00` |
| `durationMinutes`, `duration`, `arrivalDayOffset` | Total travel time; +1 / +2 for overnight arrivals |
| `stops`, `layovers`, `layoverAirports` | Number of stops; each layover's airport, city, duration and change of airport |
| `segments` | Every flight: number, airline, airports, times, duration, aircraft, legroom, codeshares, CO2 |
| `co2Kg`, `co2TypicalKg`, `co2DiffPercent`, `emissionsLevel` | Google's emissions estimate vs. typical for the route |
| `typicalPriceLow`, `typicalPriceHigh` | Google's "similar trips usually cost" range |
| `returnFlight` | With `includeReturnFlights`: the return flight (same fields) that makes up the round-trip price |
| `googleFlightsUrl`, `searchUrl` | The itinerary on Google Flights (booking page when the trip is complete) and the search |
| `route`, `tripType`, `searchOrigin`, `searchDestination`, `cabinClass`, `passengers`, `country`, `language` | Context |
| `previousPrice`, `priceChange` | Monitoring mode: the price in the previous run |

```json
{
  "type": "flight", "route": "JFK -> LAX 2026-11-06", "rank": 1, "isBest": true, "isCheapest": true,
  "price": 204, "currency": "USD", "priceType": "one_way_total",
  "airlines": ["Delta"], "flightNumbers": ["DL 701"], "departureAirport": "JFK", "arrivalAirport": "LAX",
  "departureDateTime": "2026-11-06T14:00:00-05:00", "arrivalDateTime": "2026-11-06T17:12:00-08:00",
  "duration": "6 hr 12 min", "stops": 0, "layovers": [], "co2Kg": 240, "co2TypicalKg": 324, "emissionsLevel": "lower",
  "typicalPriceLow": 90, "typicalPriceHigh": 260,
  "googleFlightsUrl": "https://www.google.com/travel/flights/booking?tfs=..."
}
```

#### Price calendar rows

| Field | What it is |
|---|---|
| `departureDate`, `weekday`, `returnDate`, `tripLengthDays` | The date (and the return date for round trips) |
| `price`, `currency`, `priceType` | Cheapest fare Google has for that date, total for all passengers |
| `isCheapest` | The cheapest date of the range |
| `googleFlightsUrl` | That date's search on Google Flights |

Every run also saves a free **RESULTS_FLAT.csv** (one line per row, lists joined) in the run's key-value store,
handy for Excel and Google Sheets.

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

Pay per result, platform usage included. Failed, duplicate and unchanged (monitoring) rows are never charged.

| Apify plan | Flights per 1,000 | Price-calendar dates per 1,000 |
|---|---|---|
| Free | $0.50 | $0.20 |
| Starter (Bronze) | $0.40 | $0.15 |
| Scale (Silver) | $0.30 | $0.12 |
| Business (Gold) and above | $0.25 | $0.10 |

A **flight** row is one itinerary with all its details (with `includeReturnFlights`, its return flight included at no
extra charge). A **calendar** row is one date's cheapest fare. Examples on the Free plan: 50 flights for one route =
$0.025; a 90-day price calendar = $0.018.

### Switching from another Google Flights scraper?

Common input names from other Google Flights actors and from SerpApi-style APIs are accepted, so most inputs work
as they are:

| You may have used | Here |
|---|---|
| `origin` / `destination`, `from` / `to`, `departure_id` / `arrival_id` | `origin` / `destination` (codes, comma lists or city names) |
| `departDate`, `outbound_date`, `date` | `departureDate` (also accepts `+30`) |
| `return_date` | `returnDate` |
| `searches` (a list of routes) | `routes` (`searches` also works; each entry may use `departureDate` or `departDate`) |
| `tripType: "one-way"` | leave `returnDate` empty (`tripType: "one-way"` is honoured too) |
| `travel_class` 1-4, `cabinClass` | `cabinClass` (`economy` ... `first`, or 1-4) |
| `max_stops` / `maxStops` 0, 1, 2 | `maxStops` (`0` = nonstop) |
| `infants` | `infantsOnLap` (and `infantsInSeat`) |
| `gl`, `hl`, `market` | `country`, `language` |
| `maxItems` | `maxResults` (per route) |
| `priceGraphDays` | `mode: "calendar"` + `calendarDays` |
| `deltaMode` | `onlyNewSinceLastRun` + `monitorName` |

What you get on top: ISO times with time zones, CO2 vs. typical, Google's best/cheapest marks, run-wide dedup
across routes, a price calendar in the same actor, and monitoring that only charges for changed prices. Not here
(yet): booking options per airline / travel agency, multi-city trips, explore / "anywhere" destinations.

### How to use it

1. Click **Try for free**.
2. Type the route (`JFK` -> `LAX`, or `New York` -> `London`) and the departure date (`+30` = in 30 days). Add a
   return date for a round trip.
3. Optionally set passengers, cabin class, stops, airlines, currency.
4. Click **Start** and download JSON, CSV or Excel, or read the dataset via API.

#### Price calendar input

```json
{
    "mode": "calendar",
    "origin": "LHR",
    "destination": "BCN",
    "departureDate": "+7",
    "returnDate": "+11",
    "calendarDays": 120
}
```

#### Monitoring: only changed prices

Set `onlyNewSinceLastRun: true` and a `monitorName`, then create a schedule. Each run delivers only flights or dates
that are new or whose price changed since the previous run with that name, with `previousPrice` and `priceChange`.
If nothing changed, the run says so ("empty: no price changed since the previous run...") and costs nothing.

Tip: to watch **one trip**, use fixed dates (`2026-12-20`). Relative dates move every day, so each day is a new
search and everything counts as new. To watch a **season**, use the price calendar with fixed or relative dates:
each date keeps its own price history.

### Google Flights API in Python, JavaScript, Make, Zapier, n8n and AI agents

Run it from the Apify API with the Python or JavaScript client, schedule it, or connect it to Make, Zapier, n8n and
Google Sheets. AI agents can call it through the Apify MCP server. See the **API** tab for ready-made code.

```python
from apify_client import ApifyClient  # pip install "apify-client>=3"

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("alom/google-flights-scraper").call(run_input={
    "origin": "JFK", "destination": "LHR", "departureDate": "+30", "returnDate": "+37", "maxResults": 20,
})
for f in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f["price"], f["airlines"], f["departureDateTime"], f["stops"])
```

### Limitations

- **Prices are what Google Flights shows** at the moment of the run. Fares change constantly, and the price on the
  airline's site can differ (fare rules, bags, seat selection).
- **Up to 300 flights per route and date**, Google's complete list. If Google refuses the full list from the proxy
  IPs for a while, the run still delivers Google's default list (the top 10-35 flights) and logs it.
- **Round trips:** the outbound rows carry the cheapest round-trip total. Return flights are an extra request per
  row (`includeReturnFlights`), so those runs take longer (about 1 second per row).
- **Not included:** booking options per airline / agency ("Book with"), baggage fees, seat maps, multi-city trips,
  explore ("anywhere") searches, and Google's price-level label (low / typical / high). The "usually costs" range is
  included.
- **Country and language** localise names and links. In our tests the fares themselves did not change with the
  country; the **currency** is what changes the numbers.
- Google Flights sells up to about 11 months ahead; later dates are refused with a clear message.

### FAQ

**Is there an official Google Flights API?** No. Google shut down its QPX Express flight API in 2018, and there is no
public API for Google Flights results. This Actor returns what the Google Flights website shows, as structured data.

**Is it legal to scrape Google Flights?** The Actor reads publicly available flight information without logging in.
You are responsible for how you use the data.

**Why is the price different on the airline's website?** Fares move all the time and Google's price may include or
exclude some fees for some airlines. Use the `googleFlightsUrl` to open the itinerary and its booking options.

**Can I search a whole city or country?** Yes: `New York` covers JFK, LGA and EWR; `Japan` covers every Japanese
airport Google offers for the route.

### More scrapers from the same developer

- [Google Hotels Scraper & Price Tracker](https://apify.com/alom/google-hotels-scraper): hotels with live prices for your dates, every booking site's rate, price calendars and guest reviews - the companion to this Actor for trip planning and travel data
- [Google Trends API & Scraper](https://apify.com/alom/google-trends-scraper): interest over time, regions, related queries and Trending Now, a pytrends alternative
- [YouTube Scraper](https://apify.com/alom/youtube-scraper): videos, channels, Shorts, comments, subtitles and community posts without the API quota
- [Threads Scraper](https://apify.com/alom/threads-scraper): posts, profiles, replies and keyword search on Meta Threads, no login
- [Bilibili Scraper](https://apify.com/alom/bilibili-scraper): videos, creators, full comment threads and danmaku from B站, no login
- [Google Ads Transparency Scraper](https://apify.com/alom/google-ads-transparency-scraper): every Google ad a competitor runs, with the real ad copy
- [Threads Account Finder](https://apify.com/alom/threads-lead-finder): Threads accounts by keyword with followers, bio links and the contacts they list
- [Threads Hashtag & Keyword Monitor](https://apify.com/alom/threads-keyword-monitor): only the new posts for your keywords and #hashtags, for scheduled runs
- [YouTube Comments Scraper](https://apify.com/alom/youtube-comments-scraper): comments and replies of any YouTube video or Short
- [YouTube Channel Scraper](https://apify.com/alom/youtube-channel-scraper): every video of a channel with views, likes, dates and channel stats
- [YouTube Shorts Scraper](https://apify.com/alom/youtube-shorts-scraper): Shorts by channel or keyword with views and likes

### Feedback

Missing a field, found a bug, or need a feature? Open an issue in the **Issues** tab and I'll take a look. If this
Actor saved you time, a short review on the Store page helps other people find it.

# Actor input Schema

## `mode` (type: `string`):

<b>Flights</b>: every itinerary Google Flights lists for the route and date (price, airlines, flight numbers, times, stops, layovers, CO2). <b>Price calendar</b>: the cheapest fare for each departure date from the departure date on, for <code>calendarDays</code> days (Google's date grid / price graph), one row per date.

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

Airport code (<code>JFK</code>), several airports (<code>JFK,EWR,LGA</code>) or a city / country name as you would type it on Google Flights (<code>New York</code>, <code>Paris</code>, <code>Japan</code>). Metro codes like <code>NYC</code> or <code>LON</code> become the city.

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

Same formats as <b>From</b>.

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

<code>2026-11-20</code>, or relative: <code>+30</code> = 30 days from today, <code>tomorrow</code>. Relative dates keep scheduled runs valid. Default <code>+30</code>. In <b>price calendar</b> mode this is the first date of the range.

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

Leave empty for a one-way trip. Same formats as the departure date (<code>+37</code>). Round-trip prices are the total for the whole trip. In <b>price calendar</b> mode the trip length (return minus departure) is kept for every date.

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

Optional list of extra routes, each an object: <code>{"origin": "LHR", "destination": "JFK", "departureDate": "+45", "returnDate": "+52"}</code>. Dates an entry leaves out come from the fields above (an entry with its own departure date and no return date is one-way). Every other setting (passengers, cabin, filters) applies to all routes. Up to 100 routes; the same flight is never delivered twice. <code>searches</code> is accepted as another name for this field.

## `calendarDays` (type: `integer`):

Price calendar mode only: how many departure dates, starting at the departure date. Google sells about 11 months ahead, so later dates are cut off.

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

Prices are the total for all passengers, as on Google Flights.

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

Children aged 2 to 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). Google allows 9 passengers in total.

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

Seat class.

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

Google's stops filter, for every leg of the trip.

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

Only these airlines: 2-letter codes (<code>DL</code>, <code>BA</code>, <code>LH</code>) or alliances (<code>ONEWORLD</code>, <code>SKYTEAM</code>, <code>STAR_ALLIANCE</code>). Empty = all airlines.

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

Order of the flight rows of each route. Every row also says whether Google marked it as a top (best) flight and whether it is the cheapest.

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

Flights mode: stop after this many itineraries per route (after sorting). Google's complete list ends at 300.

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

For round trips Google first lists outbound flights with the cheapest round-trip price. Turn this on to also get, for every outbound row, the return flight that makes up that price (flight numbers, times, stops). One extra request per row, so runs take longer; the row price stays the same.

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

3-letter code: USD, EUR, GBP, JPY, INR, AUD...

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

Google's country setting, e.g. <code>US</code>, <code>GB</code>, <code>DE</code>. In our tests fares did not change with the country - the currency is what matters.

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

Language of airport, city and airline names, e.g. <code>en</code>, <code>de</code>, <code>es</code>.

## `onlyNewSinceLastRun` (type: `boolean`):

For scheduled runs: deliver only flights / dates that are new or whose price changed since the previous run with the same monitor name, with <code>previousPrice</code> and <code>priceChange</code>. Unchanged prices are skipped and not charged.

## `monitorName` (type: `string`):

Separate memory per monitor, e.g. <code>nyc-lon-weekly</code>. Default: <code>default</code>.

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

Routes processed in parallel.

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

Leave the default (Apify datacenter proxies). Explicit settings here are used as given.

## Actor input object example

```json
{
  "mode": "flights",
  "origin": "JFK",
  "destination": "LAX",
  "departureDate": "+30",
  "routes": [
    {
      "origin": "LHR",
      "destination": "JFK",
      "departureDate": "+45"
    },
    {
      "origin": "Paris",
      "destination": "Tokyo",
      "departureDate": "+60",
      "returnDate": "+74"
    }
  ],
  "calendarDays": 60,
  "adults": 1,
  "children": 0,
  "infantsInSeat": 0,
  "infantsOnLap": 0,
  "cabinClass": "economy",
  "maxStops": "any",
  "sortBy": "best",
  "maxResults": 20,
  "includeReturnFlights": false,
  "currency": "USD",
  "country": "US",
  "language": "en",
  "onlyNewSinceLastRun": false,
  "maxConcurrency": 4,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

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

No description

## `calendar` (type: `string`):

No description

## `csv` (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",
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("alom/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",
    "maxResults": 20,
}

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

```

## MCP server setup

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