Google Flights Scraper — Flight Prices & Fares (Any Market)
Pricing
from $0.45 / 1,000 flight results
Google Flights Scraper — Flight Prices & Fares (Any Market)
Scrape Google Flights with structured search tokens, not text queries — every market returns results without a country proxy. Fares, airlines, layovers, CO2 and Google's own fare-history insights. Batch 50 routes per run, no browser. Hotel search included via searchType.
Pricing
from $0.45 / 1,000 flight results
Rating
0.0
(0)
Developer
jy-labs
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
9 days ago
Last modified
Categories
Share
Google Flights Scraper
Flight prices and fares from Google Flights, in any market and currency,
over plain HTTP — no browser, no country proxy. Hotel search rides along in the
same Actor: switch searchType and the same run scrapes the other side of
Google Travel.
- ✈️ Flights — fares, airlines, flight numbers, layovers, aircraft, legroom, CO₂, and Google's own fare history, for up to 50 routes in a single run.
- 🏨 Hotels — room rates, stay totals, star ratings, review counts and coordinates, for up to 50 hotel searches in a single run.
No login. No cookies. Datacenter proxy is enough for every market.
One line per route
LAX-JFK +30ICN-CDG +30..+37CDG-NRT +90
ORIGIN-DESTINATION date for one way, date..date for a return. A date is
either YYYY-MM-DD or +N — N days from today in UTC, up to +330 — so a
saved or scheduled input keeps searching ahead instead of going stale. Dates in
the past are rejected up front. Paste a column
straight from a spreadsheet. Fifty routes are one run, one job, one result set —
not fifty runs to launch and stitch back together.
Why searches do not come back empty
Most Google Flights scrapers ask Google in prose —
?q=Flights to NRT from CDG on 2026-09-22Measured 2026-08-20, same route, same date, same minute:
| Request | Locale | Itineraries |
|---|---|---|
?q=Flights to NRT from CDG on 2026-09-22 | hl=fr gl=fr | 0 |
?q=Flights to NRT from CDG on 2026-09-22 | hl=en gl=us | 13 |
| structured search (this Actor) | hl=fr gl=fr | 10 |
| structured search (this Actor) | hl=de gl=de | 12 |
| structured search (this Actor) | hl=ko gl=kr | 12 |
| structured search (this Actor) | hl=ja gl=ja | 12 |
This Actor never sends a text query. It builds Google's own structured search token, which carries the route as data and has no language to get wrong.
Across a 14-case sweep — 12 markets, one-way and return, 8 currencies — the structured form returned results 14 out of 14 times; the prose form managed 7 of 8 on the same routes.
Any market without a proxy in that country
market, language and currency are request parameters, not a function of
where your proxy exits. A US datacenter exit asking for market: de,
currency: EUR returned the same fare, 145 EUR, as a residential exit
inside Germany. Residential proxy is never required.
Verified currencies: USD, EUR, GBP, JPY, KRW, CAD, AUD, BRL, SGD, AED and more. Airport and hotel names come back in the language you asked for.
What one flight row looks like
{"query": "LAX-JFK 2026-09-22","origin": "LAX", "destination": "JFK","market": "fr", "currency": "EUR", "price": 145,"airline": "JetBlue", "airlineCode": "B6","stops": 0, "totalDurationMinutes": 330,"departure": "2026-09-22T08:00", "arrival": "2026-09-22T16:30","legs": [{"origin": "LAX", "destination": "JFK","originName": "Aéroport international de Los Angeles","flightNumber": "524", "aircraft": "Airbus A320", "legroom": "84 cm"}],"layovers": [],"emissions": { "grams": 417000, "routeAverageGrams": 344000, "percentVsAverage": 21 },"bookingToken": "CjRIYm1acEdIM3llVzBBQm10MEFCRy0t…","section": "best"}
stops is derived from the legs, never read from Google's own stop field —
that field was observed null on itineraries that plainly had a connection.
query echoes the route line as typed, so it can read LAX-JFK +30;
departDate / returnDate carry the resolved dates — key on those when
deduplicating daily runs.
Fare history, free
Every route also yields one flight-price-insights row carrying Google's
cheapest current fare, its typical fare, the typical range, and roughly 60
days of fare history as date/price pairs. Useful when you are watching a route
rather than booking today. It is not charged as a result.
{ "searchType": "flight-price-insights", "query": "LAX-JFK 2026-09-22","lowestPrice": 119, "typicalPrice": 136,"typicalRangeLow": 85, "typicalRangeHigh": 165,"priceHistory": [{ "date": "2026-06-21", "price": 134 }, … ] }
Hotels, in the same Actor
Set searchType to hotels and fill queries instead of routes:
{ "searchType": "hotels", "queries": ["hotels in Berlin", "hotels in Seoul"],"adults": 2, "market": "de", "language": "de", "currency": "EUR" }
With checkIn / checkOut left empty the search rolls with the calendar:
check-in tomorrow, one night. To pin a stay, set both as YYYY-MM-DD; dates in
the past are rejected.
Each row carries the hotel name, nightly rate, stay total, guest rating, review count and coordinates. Note that Google's hotel search page serves only sponsored listings to a plain request; this Actor reads the organic list the way the page itself does, so a Berlin search returns well over a hundred properties rather than eight adverts.
Pricing, and what happens when a search finds nothing
| Event | Charged | Free tier | Paid tiers |
|---|---|---|---|
| Search | once per route or hotel query the Actor actually runs | $3.00 / 1,000 | from $2.70 |
| Flight result | per itinerary with a fare written to the dataset | $0.50 / 1,000 | from $0.45 |
| Hotel result | per hotel written to the dataset | $0.80 / 1,000 | from $0.72 |
| Fare-history row | never | — | — |
| Itinerary Google lists without a fare | never — delivered with price: null | — | — |
Paid Apify plans get 5–10% off every per-unit price.
A search that returns nothing is charged as a search and nothing else — you are never billed per-result for rows you did not receive. And an empty answer is not taken at face value: the search is retried once on a different exit first, because Google sometimes answers a throttled request with an empty page in well under a second. The search is still charged only once, however many attempts it takes.
If every search in a run comes back empty, the run exits non-zero and shows red, instead of finishing as a green run with an empty dataset.
Platform usage is included. Apify compute, data transfer and proxy for a run are covered by the per-unit prices above; nothing is billed to your plan separately.
Every run writes a RUN_SUMMARY record to the key-value store listing each
search, its row count, and why it failed if it did — so a disappointing run can
be diagnosed without paying to repeat it.
Limits worth knowing before you buy
- 50 searches per run. Split larger jobs across runs.
- Fares are what Google shows, including the basic-economy fares Google
lists. This Actor does not resolve OTA booking pages;
bookingTokenis provided so you can. - Google's result count varies by route. A busy domestic route returned 30
itineraries; a thin long-haul one returned 8.
maxResultsPerSearchcaps the top end, not the bottom. - Hotel rows carry no OTA price comparison. For per-OTA hotel pricing across 30+ booking sites, use a dedicated Google Hotels Actor.
- A hotel with no rooms left for your dates still returns a row, with its
name, rating, review count and coordinates but a
nullprice. Google itself shows the property without a rate; filter onprice !== nullif you only want bookable ones. - Calling from the API, mind the case.
marketandlanguagetake lowercase codes (de,ko) andcurrencytakes uppercase (EUR,KRW). The Console dropdowns handle this for you; a raw API call withis rejected by the platform before the run starts."market": "DE" - Google changes these payloads without notice. When a field starts arriving empty, that is usually why.
Input reference
| Field | Applies to | Default | Notes |
|---|---|---|---|
searchType | both | flights | flights or hotels |
routes | flights | — | one route line each, max 50 |
queries | hotels | — | one hotel search each, max 50 |
adults / children | both | 1 / 0 | children are flights-only |
cabinClass | flights | economy | economy, premium-economy, business, first |
maxStops | flights | any | 0 for nonstop only |
checkIn / checkOut | hotels | tomorrow, +1 night | YYYY-MM-DD |
market / language / currency | both | us / en / USD | independent of proxy country. market and language are lowercase (de), currency is uppercase (EUR) |
maxResultsPerSearch | both | 50 | caps rows per search |
includePriceInsights | flights | true | the free fare-history row |