Google Flights Scraper – Airfare Data, $0.80/1,000 Flights avatar

Google Flights Scraper – Airfare Data, $0.80/1,000 Flights

Pricing

from $0.50 / 1,000 flights

Go to Apify Store
Google Flights Scraper – Airfare Data, $0.80/1,000 Flights

Google Flights Scraper – Airfare Data, $0.80/1,000 Flights

Turn a list of routes into a sheet of live Google Flights fares. Every row is one flight with its price, airline, flight number, local times, stops, layover airports and CO2. Pair origins with destinations, scan up to 60 departure dates, pull return legs. Searches with no fares cost nothing.

Pricing

from $0.50 / 1,000 flights

Rating

0.0

(0)

Developer

Dustin Griffie

Dustin Griffie

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Security

Limited permissions

Share

Google Flights Scraper: airfare data at $0.80 per 1,000 flights

Give this Actor a few routes, or a few hundred, and it hands back Google Flights results as tidy rows you can sort, filter and chart. Each flight comes with what you would check before booking: the fare, the airline and flight number, when it leaves and lands in local time, how long it takes, where it stops and how much CO2 it burns compared with the usual flight on that route. Times come in local and UTC, and each flight lists its codeshare numbers, onboard Wi-Fi and power, and a link to its Google Flights booking page. A price calendar mode prices every departure day for up to 330 days in a single call per route. It runs on plain HTTP with no browser, and you pay only when a flight lands in your dataset.

What does this Google Flights scraper do?

You describe trips; the Actor asks Google Flights about each one and writes down what comes back.

A search is one route on one departure date (plus a return date for round trips). You can feed searches in three ways, and mix them:

  • Routes such as SEA-LAX, JFK-LHR or NYC-TYO. City codes (NYC, LON, PAR, TYO) cover every airport in that metro area.
  • Origins × destinations. List 3 origins and 4 destinations and you get all 12 pairs without typing them out.
  • Date ranges. Pick a first date (a fixed day or "N days from today"), how many dates to try (up to 60) and the gap between them. A 30-day scan of one route is 30 searches.

For every search the Actor:

  1. Asks Google Flights' own data feed (the one its web app uses) for the whole flight list of that trip. On our test routes that is 70–200 flights in about half a second.
  2. If Google declines that request, it tries again from a fresh IP a few times, then falls back to reading the results page plus one airline-filtered page per carrier and merging them. That fallback is slower and finds fewer flights (35–60 on busy routes). Each row's source field says which way it was collected. Duplicates are dropped either way, so a flight never appears (or bills) twice.
  3. For round trips, picks the cheapest outbound options and fetches the return flights that pair with them.
  4. Writes one row per flight, plus one free summary row per search with the cheapest fare, Google's verdict on the price, the usual price band and Google's daily fare history for roughly the last two months.

Switch mode to calendar and the job changes: each route returns one row per departure day with the cheapest fare Google knows for that day, up to 330 days ahead, and round trips use a fixed stay length.

Rows come out as JSON, CSV, Excel, XML or HTML from the dataset tab, or straight through the Apify API.

Which flight data do I get?

There are three kinds of rows, told apart by recordType.

Flight rows (recordType: "flight", billed)

FieldWhat it holds
price, currency, priceTypeTotal fare for all passengers you entered. priceType says whether it is a one-way or round-trip total.
airlines, flightNumbersEvery carrier and flight number on the itinerary, e.g. ["UA 1833", "UA 1583"].
departureAirport, arrivalAirportIATA codes of the first and last airport.
departureTime, arrivalTimeLocal times at each airport, ISO format without offset (2026-12-04T08:00).
departureTimeUtc, arrivalTimeUtc, departureUtcOffset, arrivalUtcOffset, departureTimeZone, arrivalTimeZoneThe same moments in UTC, with each airport's offset and IANA zone, worked out offline from a built-in table of about 7,900 airports (daylight saving included). null for the rare airport missing from the table.
durationMinutes, durationDoor-to-door time, as minutes and as text.
stops, layoverAirports, layoversStop count, the connecting airports and each layover's length.
emissionsKg, typicalEmissionsKg, emissionsDiffPercentGoogle's CO2 estimate for this itinerary and for a typical one on the route.
aircraft, operatedByPlane types and the carrier actually flying the plane, when it differs.
codeshareFlightNumbersOther airlines' numbers sold on the same flights, e.g. ["AF 9656", "DL 5996"].
wifiOnAllLegs, powerOnAllLegs, inSeatVideoOnAllLegstrue when Google lists Wi-Fi, seat power or a seatback screen on every segment. false means Google did not list it, not that the plane surely lacks it.
bookingUrlOpens this exact itinerary on Google Flights' booking page, where the airline and agency offers are listed. Filled on one-way rows and round-trip return rows (both directions are known there).
pricePerAdultprice divided by the number of adults, when every passenger is an adult; otherwise null.
legsOne entry per flight segment with airport names, local and UTC times, airline code, aircraft, legroom, codeshares, an amenities object (wifi: free/paid, power: outlet/USB, video, seatType) and segment CO2 (turn off with includeLegs).
resultRank, isBestFlightPosition in Google's order, and whether Google flagged it as a "best" pick.
source, listSourceHow the row was collected: api (Google's full list, listSource: "full_list"), page or page_airline_fanout (results page, listSource results_page or airline_filter).
priceLevel, lowestPriceForSearch, typicalPriceLow, typicalPriceHighGoogle's price insight for this search, copied onto every row so a flat CSV is still useful.
legType, returnDate, outboundFlightNumbers, outboundPriceFor round trips: outbound or return, and on return rows the outbound flight (numbers, airlines, times, stops) they pair with.
googleFlightsUrlOpens the same search on Google Flights.
search inputsorigin, destination, departureDate, cabinClass, passengers, country, scrapedAt.

Here is a real nonstop row from a run on 4 Nov 2026 (legs trimmed to one):

{
"recordType": "flight",
"route": "JFK-LHR",
"price": 300,
"currency": "USD",
"priceType": "one way total for 1 passenger(s)",
"resultRank": 1,
"isBestFlight": true,
"source": "api",
"listSource": "full_list",
"pricePerAdult": 300,
"airlines": ["Virgin Atlantic"],
"flightNumbers": ["VS 26"],
"codeshareFlightNumbers": ["AF 9656", "DL 5996", "KL 2505"],
"departureTime": "2026-12-04T08:00",
"arrivalTime": "2026-12-04T20:10",
"departureTimeUtc": "2026-12-04T13:00:00Z",
"arrivalTimeUtc": "2026-12-04T20:10:00Z",
"duration": "7 hr 10 min",
"stops": 0,
"emissionsKg": 369,
"typicalEmissionsKg": 434,
"emissionsDiffPercent": -15,
"aircraft": ["Airbus A330-900neo"],
"wifiOnAllLegs": true,
"powerOnAllLegs": true,
"legs": [{ "flightNumber": "VS 26", "aircraft": "Airbus A330-900neo", "legroom": "31 inches",
"amenities": { "wifi": "paid", "power": "outlet_and_usb", "video": "on_demand", "seatType": "average" } }],
"priceLevel": "typical",
"typicalPriceLow": 170,
"typicalPriceHigh": 470,
"bookingUrl": "https://www.google.com/travel/flights/booking?tfs=…",
"cabinClass": "economy",
"departureDate": "2026-12-04"
}

Search summary rows (recordType: "search", never billed)

One per search, turned on by includeSearchSummary. Searches that fail, find nothing or are invalid always get one, so you can see what happened to every search in the same table.

FieldWhat it holds
status, statusMessageok, no_results, invalid, failed, or a max-cost stop, with a plain-English reason.
flightsFound, flightsSaved, nonstopFlights, airlinesFoundHow big the route is.
cheapestPrice, cheapestAirlines, cheapestFlightNumbers, cheapestDepartureTime, cheapestStopsThe best fare in one place.
priceLevelGoogle's label: low, typical or high.
usualPrice, typicalPriceLow, typicalPriceHighThe price band Google considers normal for this trip.
priceHistoryAbout 61 daily points ({date, price}) for the lowest fare on this exact search over the last two months.
priceHistoryMin, priceHistoryMax, priceHistoryDays, priceHistoryFirstDate, priceHistoryLastDateThat history condensed into numbers you can filter on.
source, apiAttempts, extraPagesFetchedWhich method served the search, how many data-feed requests it took, and how many airline-filtered pages the fallback opened.

From the same run, trimmed to the last three history points:

{
"recordType": "search",
"route": "JFK-LHR",
"departureDate": "2026-12-04",
"status": "ok",
"flightsFound": 108,
"nonstopFlights": 19,
"cheapestPrice": 298,
"cheapestAirlines": ["Aer Lingus"],
"cheapestFlightNumbers": ["EI 104", "EI 152"],
"priceLevel": "typical",
"usualPrice": 298,
"typicalPriceLow": 170,
"typicalPriceHigh": 470,
"priceHistoryDays": 61,
"priceHistoryMin": 291,
"priceHistoryMax": 321,
"priceHistory": [
{ "date": "2026-11-02", "price": 298 },
{ "date": "2026-11-03", "price": 298 },
{ "date": "2026-11-04", "price": 298 }
],
"source": "api",
"apiAttempts": 1,
"charged": false
}

Price calendar rows (recordType: "calendar-day", calendar mode)

Set mode to calendar and calendarDays to how many departure days you want (1–330). Each route then gives one row per day that Google has a price for, plus a summary row with cheapestDate, cheapestPrice, highestPrice, medianPrice and daysWithPrice. It works for single journeys and for return trips, which keep the stay fixed at tripLengthDays. Stops, airline, cabin and passenger filters apply. A 330-day calendar took a few seconds per route in our runs. Each saved day costs $0.0001, so 60 days is $0.006 and a full 330 days $0.033 per route; days Google has no price for are not saved and cost nothing. Google's calendar stops about 330 days from today, and the exact last day can shift by one around midnight. If your range runs past it, the Actor ends the range on Google's last day instead of failing, and the summary row shows rangeShortenedToGoogleLimit: true with the dates it covered.

A real row from 4 Nov 2026:

{
"recordType": "calendar-day",
"route": "JFK-LHR",
"tripType": "one_way",
"departureDate": "2026-11-25",
"dayOfWeek": "Wed",
"price": 304,
"currency": "USD",
"isCheapestDay": false,
"priceVsCheapestPercent": 18.8,
"charged": true
}

The same run's summary row found the cheapest day 144 days out: $256 on 29 March 2027, against a median of $300 across the 330 days.

The dataset has five views: Flights (one line per flight), Search summary & price history, Price calendar, Price by date (handy for date scans) and Legs, layovers & price insights (segments, UTC times, codeshares, amenities, booking links). Filter on recordType when you export if you want only one kind.

Ready-to-run examples

Each of these is a saved task you can open, tweak and run. All of them use relative dates, so they keep working on a schedule.

TaskWhat it shows
Cheapest departure day: scan 30 days of fares on one routeOne route for each of the next 30 days, cheapest flights plus a daily summary
Transatlantic round trips priced with their return flightsNYC and Boston to London, Paris and Dublin, ten nights, with return legs
Long-haul business class fares to watch every weekFour long-haul business routes with aircraft and legroom per segment
Nonstop flights for every origin × destination pairThree origins × three destinations, nonstop only
Fares from one home airport to a dozen popular citiesOne home airport to 12 cities; cheapest fare and usual band per city
Seven-night round trips, one departure a week for 8 weeksEight weekly departure dates for a week-long round trip
Cheapest fare calendar: every day for the next 6 monthsLowest one-way fare for every day over six months on three routes
Cheap flights under a set price from one cityOnly fares under a set price from one city to several destinations
Round-trip fares for two adults and two kidsTwo adults and two kids as one booking, with return flights
Lowest round-trip fare for every departure day, 11 months outLowest round-trip fare for every departure day, 11 months out

A minimal input of your own looks like this:

{
"routes": ["SEA-LAX", "JFK-LHR"],
"departureInDays": 21,
"numberOfDates": 7,
"maxStops": "1",
"maxResultsPerSearch": 100
}

That is 14 searches: two routes on seven consecutive dates, three weeks out, at most one stop.

Scraping Google Flights in three steps

  1. Say where and when. Fill in routes (or origins and destinations), then either a departureDate or departureInDays. Round trip? Switch tripType to round_trip and add a returnDate or a tripLengthDays.
  2. Narrow it down if you like. maxStops, cabinClass (from economy up to first), airlines (two-letter codes to keep), maxPrice, passengers (adults, children, infantsInSeat, infantsOnLap), currency and country. Country matters: Google shows a slightly different market for gb than for us.
  3. Run it and export. Press Start, wait for the status line to count up, then download from the Output tab or read the dataset through the API.

A few settings change what you get back:

  • mode picks flights (default) or calendar; calendarDays sets the calendar's length.
  • completeResults (default on) asks for the route's full list. Turn it off to get only the shortlist on Google's first results page, which also keeps each search to a single page request.
  • searchMethod is auto (data feed first, page fallback) or page (always the slower results-page method).
  • maxResultsPerSearch (default 100, max 500) caps flight rows per search. Rows follow Google's order, so a cap of 20 keeps the 20 Google ranks highest. Busy routes often have more than 100 flights in the full list; raise the cap to get them all, or lower it to pay for fewer.
  • returnFlightsForCheapestOutbound (1 to 10) decides how many outbound picks get their return flights looked up.
  • includeSearchSummary adds the free summary row; includeLegs adds the per-segment detail.

Watching airfare on a schedule

Fares move several times a day, and the useful question is usually "is this cheaper than it was?". Two features make that easy.

Relative dates. Use departureInDays instead of a fixed date. A daily schedule with departureInDays: 30 always checks the trip a month out, so the series compares like with like.

History in every run. The summary row already carries about 60 days of Google's own price history for that search, plus the low / typical / high label. A single run tells you whether today's fare is near the bottom of its recent range, without you having collected anything beforehand.

To set it up, save your input as a task, open Schedules in Apify Console and pick a cron (daily at 06:00, every Monday, whatever suits). Point a webhook or an integration at the run's dataset and you can push new rows to Google Sheets, Slack, a database or email. A simple alert rule: notify when cheapestPrice is below typicalPriceLow, or when priceLevel turns low.

Scheduling costs nothing extra. Each scheduled run is billed like any other, by flights saved.

What a run costs

You pay per flight row saved to the dataset, per day saved in calendar mode, and a tiny fee each time the Actor starts. Summary rows, empty searches, invalid searches, failed searches and failed calendars are free.

Your Apify planPer flight rowPer 1,000 flightsPer calendar dayActor start
Free$0.0008$0.80$0.0001$0.00005
Starter$0.0007$0.70$0.0001$0.00005
Scale$0.0006$0.60$0.0001$0.00005
Business$0.0005$0.50$0.0001$0.00005

Some sums, on the Free plan:

  • One domestic route on one date at the default cap of 100 flights (our busy test routes all reached it): about 8 cents. With maxResultsPerSearch: 40, about 3 cents.
  • A price calendar for one route: 60 days $0.006, the full 330 days $0.033.
  • The same route checked for 30 dates with maxResultsPerSearch: 10: 300 flights, about 24 cents.
  • A daily watch of 5 routes keeping the top 20 each: 100 flights a day, about $2.40 a month.

You stay in control of the bill. maxResultsPerSearch caps every search. Max cost per run in the run options is respected too: when the budget runs low, the Actor stops early, saves only what fits and marks the affected searches or calendars partial_max_cost or stopped_max_cost in their summary rows. Rows that weren't saved are never charged. Proxy traffic and compute are included in the price.

Calling it from code, n8n, Make or an AI agent

Anything you can click in Console you can also script. A Python example:

import os
from apify_client import ApifyClient
apify = ApifyClient(os.environ["APIFY_TOKEN"])
payload = {"routes": ["BOS-SAN"], "departureInDays": 21, "maxResultsPerSearch": 50}
finished = apify.actor("griffie/google-flights-scraper").call(run_input=payload)
rows = apify.dataset(finished["defaultDatasetId"]).list_items().items
flights = [r for r in rows if r["recordType"] == "flight"]
summary = next(r for r in rows if r["recordType"] == "search")
print(len(flights), "flights; cheapest", summary["cheapestPrice"], summary["priceLevel"])

The JavaScript client (apify-client) works the same way. For a one-shot HTTP call, POST your input JSON to https://api.apify.com/v2/acts/griffie~google-flights-scraper/run-sync-get-dataset-items with your token, and the response body is the result rows.

No-code tools. n8n, Make and Zapier all have Apify modules: choose "Run Actor", pick this one, paste your input and map the dataset fields onward. AI agents. Apify's MCP server exposes this Actor as a tool, which lets an assistant such as Claude or Cursor run it ("find me nonstop fares from SFO to Tokyo next month") and read the rows back. Keep maxResultsPerSearch modest for agents so the answer fits in context; the summary row alone is often enough.

Planning the hotel too? The sister Actor Google Hotels Prices Scraper returns nightly rates for the same kind of bulk city and date list.

Limits worth knowing

  • The data feed is not always available. Google answers it from some IPs and declines from others. The Actor retries on fresh IPs with pauses between tries, and if Google keeps declining across a run it stops asking and uses the results-page method for the rest. That keeps the run going, at about 20 times the time per search and with fewer flights. Calendar mode has no page fallback, so a calendar that is still declined after several tries gets a failed summary row and costs nothing.
  • Speed. In our 20-search tests on 4 Nov 2026 (512 MB) every search was served by the data feed. A run of 7 one-way searches took 4–16 seconds, depending on how often Google declined the first try, and 6 round trips with their returns took 8–12 seconds. A fallback search takes 15–60 seconds.
  • Booking links, not seller prices. bookingUrl opens Google's booking page for the itinerary, where the airline and agencies are listed. The Actor does not read those individual offers.
  • City codes. Common metro codes (NYC, LON, PAR, TYO, CHI, WAS and about 15 more) go through the data feed. Other city codes use the results-page method.
  • Children and infants. On some routes Google returns fewer fares, or none, once children or lap infants are added. Try adults only if a search comes back empty.
  • No multi-city yet. One-way and round trips only.
  • Prices are a snapshot. Fares can change between the run and a booking, and Google sometimes shows slightly different prices by country and currency.

FAQ

Are prices per person? price is the total for everyone you entered, as Google shows it, and priceType says so. When all passengers are adults, pricePerAdult gives the per-person figure. With children or infants their fares differ, so it is left empty.

How do round trips work? Outbound rows carry the round-trip total. The Actor then takes the cheapest outbound options (how many is up to you) and fetches the returns for each. Each return row repeats the full itinerary's total and names its outbound flight.

How do I find the cheapest day to fly? Use calendar mode: "mode": "calendar" with calendarDays: 90 gives up to 90 rows, one per day, for $0.009, and the summary row names the cheapest. Sixty days costs $0.006 and the full 330 days $0.033 per route. When you also want the flights behind each day, use a date range instead (numberOfDates: 30, dateStepDays: 1) and sort the summary view by cheapestPrice.

How many flights per search? Up to maxResultsPerSearch, which is 100 unless you change it. In our 4 Nov 2026 test of 20 searches with the cap raised to 200, domestic routes averaged about 155 flights per search, long-haul ones about 118 and round trips about 91 (outbound plus returns). With the page method alone the same routes gave 37–44.

Does it need residential proxies? No. It runs on Apify's datacenter proxy by default and retries on fresh IPs when Google hesitates. A residential fallback switch exists for unusually strict runs.

Can I change currency and market? Yes. currency takes any ISO code (EUR, GBP, JPY) and country a two-letter market (de, gb, jp).

Are times local? departureTime and arrivalTime are local at each airport, as Google shows them, so a red-eye can arrive "earlier" than it left. departureTimeUtc and arrivalTimeUtc give the same moments in UTC, so you can sort or subtract them directly.

What happens with a typo in an airport code? That search gets a free summary row with status no_results or invalid and a short explanation; the rest of the run carries on.

The Actor reads only public fare and schedule information, the same thing anyone sees on Google Flights, and collects no personal data. Even so, you are responsible for how you use the results: check Google's terms and the rules in your country, and ask a lawyer if your use case is unusual. Questions, odd routes or a missing field? Tell us in the Issues tab and we'll look into it.