Google Flights Scraper avatar

Google Flights Scraper

Under maintenance

Pricing

Pay per usage

Go to Apify Store
Google Flights Scraper

Google Flights Scraper

Under maintenance

Scrape Google Flights itineraries as flat rows: live price, airlines, departure/arrival times, duration, stops, layovers, aircraft, CO2 estimate, and a shareable deep link. One-way or round-trip, any cabin class or currency. Pay only for delivered rows - failed fetches cost nothing.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

Aaron S

Aaron S

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

4 days ago

Last modified

Categories

Share

Get live Google Flights prices as flat, ready-to-use rows - one row per itinerary, with airlines, times, duration, stops, layovers, aircraft, and CO2 estimates. One-way or round-trip, any cabin class, any currency. No charge for failed fetches.

Try it

Paste this into the input editor and hit Run:

{
"origin": "LHR",
"destination": "JFK",
"departDate": "2026-09-25",
"returnDate": "",
"adults": 1,
"cabinClass": "economy",
"currency": "GBP",
"maxItems": 50
}

Input fields

FieldTypeValuesNotes
originstring3-letter IATA code, e.g. LHR, JFK, NYCAirport codes and metro/city codes both work
destinationstring3-letter IATA codeSame as origin
departDatestringYYYY-MM-DDMust be today or later
returnDatestringYYYY-MM-DD or emptyEmpty = one-way. When set, rows are departing-flight options priced as round-trip totals (how Google Flights itself works)
adultsinteger1-9Default 1
cabinClassstringeconomy | premium_economy | business | firstDefault economy
currencystringISO code, e.g. USD, GBP, EURPrices returned in this currency
maxItemsintegere.g. 50Caps rows delivered before the run stops
proxyGroupsarraye.g. ["RESIDENTIAL"]RESIDENTIAL (default) recommended - Google blocks datacenter IPs on the Flights surface

One query returns the complete result set for that route and date (typically 10-30 itineraries) in a single request - there is no pagination to pay for.

Output

Flat rows, one per itinerary. No nested objects to unpack - multi-leg details come as compact |-delimited strings. Real example row (LHR-JFK one-way, economy):

{
"origin": "LHR",
"destination": "JFK",
"departDate": "2026-09-25",
"returnDate": "",
"cabinClass": "economy",
"adults": 1,
"currency": "GBP",
"fetchedAt": "2026-08-26T12:00:00.000Z",
"category": "best",
"price": 602,
"priceCurrency": "GBP",
"airlineCodes": "B6",
"airlineNames": "JetBlue",
"departureAirport": "LHR",
"departureTime": "2026-09-25 08:15",
"arrivalAirport": "JFK",
"arrivalTime": "2026-09-25 11:19",
"durationMinutes": 484,
"stops": 0,
"layovers": "",
"flightNumbers": "B62220",
"legs": "B62220 LHR 2026-09-25 08:15 -> JFK 2026-09-25 11:19",
"aircraft": "Airbus A321neo",
"co2Grams": 537000,
"co2TypicalGrams": 484000,
"deepLink": "https://www.google.com/travel/flights/search?tfs=GhoSCjIwMjYtMDktMjVqBRIDTEhScgUSA0pGS0IBAUgBmAEC&hl=en&curr=GBP"
}

A connecting itinerary fills the multi-leg fields:

{
"airlineNames": "Tap Air Portugal",
"price": 519,
"stops": 1,
"layovers": "LIS 490m",
"flightNumbers": "TP1363 | TP209",
"legs": "TP1363 LHR 2026-09-25 06:00 -> LIS 2026-09-25 08:45 | TP209 LIS 2026-09-25 16:55 -> JFK 2026-09-25 20:05",
"durationMinutes": 1145
}
  • category is best (Google's ranked picks) or other (the rest of the result set).
  • deepLink opens the exact same search in Google Flights - hand it to users for booking.
  • co2Grams is Google's per-passenger CO2e estimate for the itinerary; co2TypicalGrams is the route-typical value it is compared against.

Queries that fail after retries are logged to a separate google-flights-errors dataset (origin, destination, departDate, reason, fetchedAt) instead of leaving a silent gap in your results.

Coming from fast-flights?

The fast-flights Python library proves this route works - but you run it, patch it when Google changes internals, and supply your own unblocked IPs. This actor is the same server-rendered ?tfs= route as a managed service: residential proxy rotation, session-scoped cookies, retries with identity rotation, block detection, and flat rows with layovers and flight numbers already extracted.

fast-flightsThis actor
FlightData(date=..., from_airport="LHR", to_airport="JFK")"origin": "LHR", "destination": "JFK", "departDate": ...
Passengers(adults=2)"adults": 2
seat="business""cabinClass": "business"
trip="round-trip" + second FlightDatajust set "returnDate"
bring your own proxyresidential rotation built in
Result.flights[n].priceflat rows with price, layovers, flight numbers, CO2

How this compares

This actorTypical Flights actors on the Store
Charge on failed queriesNever - only delivered rows are billedOften bill per run or per started query
Actor startFree - no per-run feeSome charge a flat fee before any data lands
Output shapeFlat rows, one per itineraryFrequently nested per-search JSON you have to unpack
Reliability approachSession rotation (Crawlee session pool), bounded retries with identity rotation, block detectionNot usually documented in the listing

Pricing

Pay-per-event, priced on delivered rows: you're billed only once itinerary rows land in your dataset. Starting a run costs nothing. If a query fails after retries, it goes to the errors dataset instead, and you pay nothing for it.

Using the API

Apify API (HTTP)

curl "https://api.apify.com/v2/acts/meticulous_ground~google-flights-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"origin": "LHR",
"destination": "JFK",
"departDate": "2026-09-25",
"currency": "GBP"
}'

JavaScript (apify-client)

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('meticulous_ground/google-flights-scraper').call({
origin: 'LHR',
destination: 'JFK',
departDate: '2026-09-25',
returnDate: '2026-10-02',
cabinClass: 'economy',
currency: 'GBP',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python (apify-client)

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("meticulous_ground/google-flights-scraper").call(run_input={
"origin": "EDI",
"destination": "LHR",
"departDate": "2026-09-25",
"currency": "GBP",
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)

Run one query per Actor call - each call returns that route and date's complete itinerary set.