Google Flights Scraper avatar

Google Flights Scraper

Pricing

$0.30 / 1,000 results

Go to Apify Store
Google Flights Scraper

Google Flights Scraper

Search public flight fares by route and date. Export priced itineraries, airlines, schedules, stops, segments, and emissions to CSV or JSON.

Pricing

$0.30 / 1,000 results

Rating

0.0

(0)

Developer

MLG Data

MLG Data

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Categories

Share

Search Google Flights by airport pair and travel date, then export flight prices and schedules as structured CSV or JSON. Each saved row represents one priced itinerary, making this a practical Google Flights data source for fare comparisons, route monitoring, and travel analysis.

The scraper collects the initial public search results for a one-way or round-trip query. It records the displayed fare, operating airlines, departure and arrival times, journey duration, connections, segment details, and estimated emissions. Set a return date for a round-trip search, or leave it empty for a one-way search. Results are observations at the time of the run; fares and availability can change after collection.

What data can you extract from Google Flights?

The default dataset has one row per priced itinerary. You can sort, filter, and export the rows directly. An itinerary may contain several flight segments; legs retains the segment details while the top-level fields make route comparisons simple.

FieldDescriptionExample
flightIdIdentifier derived from route, date, flight numbers, and timesf78661ac50c1e099ab60
tripTypeRequested trip typeoneWay
resultCategoryPosition group shown in the search resultsbest
departureAirportOrigin airport codeLAX
departureAirportNameFull origin airport nameAirport name
arrivalAirportDestination airport codeJFK
arrivalAirportNameFull destination airport nameAirport name
outboundDateRequested outbound date2026-10-26
returnDateRequested return date or nullnull
departureTimeLocal departure date and time2026-10-26T16:30
arrivalTimeLocal arrival date and time2026-10-27T00:52
durationMinutesOutbound journey duration, including connections322
stopsNumber of connections0
stopAirportsConnection airport codes in travel order[]
layoverMinutesConnection durations when the page exposes them[]
airlinePrimary operating airline nameAirline name
airlineCodePrimary airline codeB6
airlinesDistinct operating airline namesArray of names
airlineCodesDistinct operating airline codes["B6"]
flightNumbersFlight numbers in travel order["B61024"]
priceDisplayed itinerary fare for the requested adults249
currencyCurrency of priceUSD
passengersNumber of adults used in the search1
emissionsKgEstimated carbon dioxide equivalent in kilograms421
emissionsComparisonPercentDifference from typical flight emissions25
legsSegment records with carrier, airports, local times, duration, and aircraftArray of objects
bookingTokenOpaque search token, not a booking URLString or null
searchUrlPublic search page for the querySearch page URL
searchedAtCollection timestamp in UTCISO timestamp

Times are local to their respective airports and intentionally omit a timezone offset. An arrival on the next calendar day is represented by the next date in arrivalTime. durationMinutes is the elapsed itinerary duration provided by the search result, so it is the appropriate value for comparing flights across time zones. The emissions fields are estimates from the search page, not measured emissions. When a source value is unavailable, its field is null or an empty array as appropriate.

How to scrape Google Flights

  1. Enter a single departure airport code and a single arrival airport code. Use standard three-letter airport codes, such as LAX and JFK.
  2. Choose an outbound date in YYYY-MM-DD format. Add return_date when you want a round-trip fare search. Leave it empty for one-way fares.
  3. Set currency, country, and language if the defaults do not fit your market. Add optional limits for price, stops, airline codes, or number of saved rows.
  4. Run the scraper. Open the output dataset to inspect each priced itinerary as a separate row.
  5. Download the dataset in CSV or JSON for analysis, repeated monitoring, or a downstream workflow.

The route and date are checked against the page's own search state before any rows are saved. If the site interprets the query as a different route or trip type, the run fails clearly instead of returning mislabeled fares. Price, stop, and airline filters are applied to the itineraries exposed by the initial search page.

Input

ParameterTypeDefaultDescription
departure_idstringRequiredOne three-letter departure airport code.
arrival_idstringRequiredOne three-letter arrival airport code.
outbound_datestringOptionalOutbound date in YYYY-MM-DD format. Defaults to 30 days from today; past dates are shifted forward.
return_datestringEmptyAdd a later date for a round-trip search.
adultsinteger1Number of adult travelers, from 1 to 9.
currencystringUSDThree-letter currency code for displayed fares.
hlstringenSearch page language code.
glstringusSearch page country code.
max_priceintegerEmptySave only returned fares at or below this amount.
max_stopsintegerEmptySave only itineraries with at most this many connections; 0 means nonstop.
airlinesstringEmptyComma-separated operating airline codes, such as AA,DL.
maxItemsinteger100Maximum rows to save. 0 keeps all itineraries exposed by the initial page.
proxyConfigurationobjectEnabledConnection settings for requests.

A one-way input used for a successful run:

{
"departure_id": "LAX",
"arrival_id": "JFK",
"outbound_date": "2026-10-26",
"adults": 1,
"currency": "USD",
"hl": "en",
"gl": "us",
"maxItems": 100
}

For a round trip, add a later return_date, for example 2026-11-02. The displayed price on a round-trip result is the fare shown for the outbound choice in that round-trip search. The first result page does not contain a confirmed return segment for each outbound choice. A return itinerary is selected in a later interaction on the site, so treat these rows as priced outbound options for the requested round trip rather than complete two-way tickets.

Use max_stops: 0 for a nonstop comparison. Set max_price only after choosing the desired currency, since the amount is evaluated in the displayed currency. airlines accepts codes separated by commas; an itinerary is kept if at least one operating airline matches. This is useful when comparing service involving a preferred carrier, including itineraries with more than one carrier. A filter can reduce the output to zero rows if no initial result matches.

Output example

The successful one-way LAX to JFK run on 2026-09-27 saved 34 priced itineraries. The following is a shortened selection of fields from its first row. The omitted fields follow the table above.

{
"flightId": "f78661ac50c1e099ab60",
"tripType": "oneWay",
"resultCategory": "best",
"departureAirport": "LAX",
"arrivalAirport": "JFK",
"outboundDate": "2026-10-26",
"returnDate": null,
"departureTime": "2026-10-26T16:30",
"arrivalTime": "2026-10-27T00:52",
"durationMinutes": 322,
"stops": 0,
"stopAirports": [],
"airlineCode": "B6",
"airlineCodes": ["B6"],
"flightNumbers": ["B61024"],
"price": 249,
"currency": "USD",
"passengers": 1,
"emissionsKg": 421,
"emissionsComparisonPercent": 25
}

A row with a connection has stops greater than zero and includes each flight in legs. This lets you compare the overall fare and elapsed time without losing the details of the individual segments. Exported CSV is convenient for flat comparisons; JSON preserves the full segment array. The fare is a snapshot, so a later run may show a different amount for the same flightId.

Use cases

  • Fare monitoring: Save repeated searches for the same route and date, then compare price alongside searchedAt. This can reveal when a displayed fare changes. Keep the timestamp because a search result has no guaranteed validity period.
  • Departure time comparison: Filter a dataset by departureTime and arrivalTime to identify schedules that fit a meeting, connection, or arrival window. Use durationMinutes for elapsed travel time.
  • Nonstop route checks: Set max_stops to 0 to collect only nonstop options already present in the initial search result set. Compare airline codes and fares across dates.
  • Connection analysis: Inspect stopAirports, layoverMinutes, and legs to understand whether a lower fare involves longer travel or a particular connecting airport.
  • Emissions comparison: Place emissionsKg next to fare and duration when evaluating alternatives. The figure is an estimate supplied with the search result.
  • Market sampling: Run the same query with different country and currency settings to collect fare displays for the markets you serve. Keep those settings with your own saved search definitions when comparing results.

How much does it cost to scrape Google Flights?

The configured result event is $0.30 per 1,000 saved flight rows, or $0.0003 per row. The successful 34-row example therefore represents $0.0102 in result events. A 100-row set represents $0.03; 5,000 rows collected across many searches represent $1.50. A single query typically exposes far fewer than 5,000 rows, so larger datasets require multiple routes or dates.

Charges follow saved rows, not search attempts or result pages. maxItems caps how many rows are saved in a run. A strict price, stop, or airline filter can reduce the charged row count because unmatched itineraries are not saved. Check the current event price shown in the run interface before planning a large schedule; listed rates may change over time. The run also uses the platform resources needed to execute the search.

Tips for best results

Start with one airport pair and a date that has published schedules. The search source accepts one origin code and one destination code per run; use separate runs when comparing several airports. Dates farther in the future can return fewer options if schedules or fares have not been released. Past dates are not useful for live fare collection.

Run the query without filters first if you need to understand the range of fares and connection counts. Then add max_price, max_stops, or airlines to narrow the saved dataset. These filters act on the initial rows returned by the site; they do not trigger an exhaustive search for more matching flights. In particular, filtering for a rare airline may leave only a few rows even when the site has more options behind later interactions.

Keep currency consistent when tracking a route over time. A numeric fare in one currency is not directly comparable with the same number in another. Record the number of adults as well: a fare displayed for two adults should not be mixed with fares for one adult. The dataset repeats currency and passengers on every row to make accidental mixing easier to detect.

For time comparisons, read departureTime in the origin airport's local time and arrivalTime in the destination airport's local time. The timestamps do not include offsets. Use durationMinutes for elapsed time, and inspect the calendar date portion when a flight arrives after midnight. Flight numbers and times help identify a schedule, while flightId supports joins across repeated runs; it is not a reservation identifier.

Limits

Only the first public result set is collected. The site may reveal more itineraries after an interactive continuation, and there is no confirmed public continuation token in this source. On the tested one-way route, the first set held 34 priced itineraries. Other routes may return more, fewer, or none. The maxItems setting can only reduce that number.

One-way and round-trip route searches are supported. The public text query did not reliably produce a priced multi-city itinerary, so multi-city combinations are not offered. A single input also does not accept several origins or destinations. Children and infant passenger counts are not supported. The scraper rejects these unsupported values if passed programmatically, avoiding a result that silently uses a different passenger group.

A round-trip query yields priced outbound choices for the requested travel dates. It does not confirm a specific return flight or booking seller. bookingToken is an internal search value and cannot be used as a direct checkout link. No booking options, baggage fee breakdown, fare family, historical price band, or price prediction is claimed. The displayed fare may change when the itinerary is selected or when optional services are added.

The search page can change its structured data layout without notice. Route and date validation guards against one common failure mode, but a layout change can still interrupt extraction. Empty optional values are retained as null or empty arrays rather than filled with guesses. Public site access may vary by location or request volume.

Use with automated workflows

A saved search can run on a schedule and append fresh rows to a time series. For example, configure a daily LAX to JFK search for one departure date, then compare the minimum price in each run. Another workflow can run nonstop searches on several dates and export each dataset to a spreadsheet. Use searchedAt, route, date, currency, and passenger count as the grouping keys before comparing fares.

When a downstream process needs one flight at a time, read the default dataset directly. Each row is already an itinerary rather than a page containing arrays of flights. When a process needs connection detail, keep the JSON legs array or expand it into a separate segment table using flightId as the link. Check the run status before using a dataset: a failed search should not be interpreted as zero available flights.

FAQ

Is this limited to public flight results?

Yes. The scraper reads a public search page and saves displayed itinerary information. You are responsible for using collected data in accordance with applicable terms and laws. Do not use the output to imply that a fare is guaranteed or that a ticket has been held.

Do I need to configure a proxy?

The default connection setting is already enabled. You can supply your own compatible proxy configuration when needed. Requests can still be limited by the site, especially at high frequency. Space repeated runs sensibly and monitor failures rather than assuming every route always returns the same number of rows.

How quickly does a run finish?

The measured golden run completed after fetching and parsing one search page and saved 34 rows. Actual duration depends on build startup, page response time, connection routing, and platform load. The workflow makes one main search request per run, with retries only when the shared fetch layer encounters a block or error.

Can I schedule price checks?

Yes. Save a route and date as a task, schedule it, and compare datasets from successive runs. Keep the date current if your workflow should always look ahead by a fixed number of days. The input date itself is a fixed calendar date, not a rolling offset.

Can I export to a spreadsheet?

Yes. Download the dataset as CSV for a flat fare table, or use JSON when you need the full legs array. Price, airline, duration, stop count, and local times are separate fields, so you can sort or chart them without parsing a long text description.

Why is a field empty?

Some details are not supplied for every itinerary. For example, a nonstop flight has no stop airport or layover minutes, and an emissions estimate can be absent. Empty values indicate that the page did not expose a usable value for that row.

Why do I see fewer flights after adding a filter?

Filters are applied to the initial priced result set. A maximum price, nonstop limit, or airline list can remove rows. The scraper does not load every possible flight that an interactive search might reveal, so the filtered dataset is a subset of the first set, not an exhaustive market inventory.

Integrations

Use the dataset endpoint to read results from your own application, or export CSV and JSON for a reporting pipeline. Scheduled runs, webhooks, and saved tasks can connect new fare observations to alerts or recurring analysis. Include route, dates, currency, passenger count, and collection time in any downstream record so comparisons remain meaningful.

Support

Open an issue on the Issues tab; we reply within 24h and add fields on request.