How to Scrape Google Flights Prices Without a Browser (2026)
Build route comparisons, flexible-date fare scans, and scheduled Google Flights price alerts with a request-only Apify Actor.

Google Flights is useful precisely because it combines routes, dates, airlines, stops, and live prices in one search. That also makes it awkward to automate. A browser-based scraper pays for a full rendering engine before it extracts a single fare, then repeats that cost for every route and date.
Thirdwatch's Google Flights Scraper takes a request-only route. It builds the Google Flights query, reads the public fare payload, and writes structured flight choices to an Apify dataset. There is no browser startup in the hot path.
Skip the setup: run a 14-day London to New York fare scan on Apify. The saved Task uses relative dates, so it remains useful after today.
What the Actor returns
Each row represents one unique priced flight choice and includes:
- price and requested currency;
- origin, destination, departure, and arrival;
- airlines, primary airline code, stops, and duration;
- every returned flight segment with airport names and aircraft type;
- carbon emissions when Google supplies them;
- a stable
itinerary_idfor incremental monitoring; - a
google_flights_urlthat reopens the same search.
The contract is deliberately explicit for round trips. The initial Google response prices an outbound choice against a requested return date; it does not select the inbound flight. Those rows carry trip_type: "round-trip", both requested search_legs, return_date, and segments_scope: "outbound_selection". This prevents an outbound segment list from masquerading as a complete booked itinerary.
One route, one request
Use an explicit date when you need a reproducible query:
{
"origin": "JFK",
"destination": "LAX",
"departureDate": "2026-09-15",
"maxStops": 1,
"maxResults": 100
}Or call the Actor through the Apify API:
import os
import requests
response = requests.post(
"https://api.apify.com/v2/acts/thirdwatch~google-flights-scraper/"
"run-sync-get-dataset-items",
params={"token": os.environ["APIFY_TOKEN"]},
json={
"origin": "JFK",
"destination": "LAX",
"departureInDays": 30,
"maxResults": 100,
},
timeout=900,
)
response.raise_for_status()
fares = response.json()
print(sorted(fares, key=lambda row: row["price"])[:5])departureInDays keeps a saved Task reusable. A value of 30 always searches 30 days from the run date instead of expiring when a hard-coded date passes.
Scan routes and flexible dates together
The route/date matrix is where a request-only design pays off. This input performs 42 searches: three airport pairs across 14 departure dates.
{
"routes": ["JFK-LAX", "EWR-LAX", "JFK-SFO"],
"departureInDays": 30,
"dateRangeDays": 14,
"dateStepDays": 1,
"currency": "USD",
"maxResultsPerSearch": 100,
"maxResults": 3000
}The Actor caps a run at 120 route/date searches and 10,000 result rows. These bounds prevent a typo from turning one comparison into an unplanned crawl.
Monitor fares without republishing everything
Set monitorMode to price-changes, put the input in an Apify Schedule, and keep the search inputs stable:
{
"origin": "SFO",
"destination": "JFK",
"departureInDays": 30,
"dateRangeDays": 14,
"monitorMode": "price-changes",
"monitorStoreName": "rolling-sfo-jfk-30-to-43-days",
"maxResults": 1000
}The first run emits newly observed fares. Later runs publish only new fare IDs or rows whose price changed, adding change_type and previous_price. The rolling 14-day window overlaps from one day to the next, so the watch can detect changes on the 13 retained dates while introducing the new final date.
Automatic monitoring keys include every fare-affecting input. Economy and business-class watches for the same route cannot overwrite one another, while operational changes such as retry count do not fork the watch state.
Reliability and cost behavior
An empty payload is ambiguous: it can mean no matching flights, or it can mean an upstream block. The Actor therefore retries empty responses and fails the run by default if a route/date still cannot be fetched. Multi-search runs also fail on partial errors unless you explicitly opt out. That makes Schedules and webhooks trustworthy: green means the requested matrix completed.
The network strategy is cost-aware:
- try direct HTTP;
- retry direct responses before paying for proxy bandwidth;
- use a country-matched residential proxy only after the direct budget is exhausted.
In the release benchmark, four searches returned 81 complete, unique rows for 0.000656 USD and used zero residential bandwidth. That is about 0.0081 USD of infrastructure cost per 1,000 results. At the $0.12/1K GOLD price, the projected contribution margin is roughly 91.6% after Apify's 20% fee.
Pricing
You pay for dataset rows, not attempts:
| Apify plan | Price per 1,000 results |
|---|---|
| FREE | $0.25 |
| BRONZE | $0.18 |
| SILVER | $0.15 |
| GOLD | $0.12 |
Failed requests, retries, deduplicated fares, and unchanged monitoring runs do not create result events.
Limits worth knowing
This is fare research, not ticketing. Google can change availability between the scrape and checkout. The Actor does not claim baggage allowances, fare rules, seat inventory, airline/OTA checkout links, or a guaranteed bookable price. Use google_flights_url to reopen the search and confirm the final itinerary before purchase.
Multi-city extraction is also intentionally absent. The current public response does not expose the same stable result list as one-way and round-trip searches, so advertising it would make the output contract less reliable.
Frequently asked questions
Does Google Flights have a public search API?
Google's published Flights Search integration is for airline and OTA partners. Its public Travel Impact Model API covers emissions, not general fare shopping. This Actor reads the public fare-search response without opening a browser.
Can the Actor compare flexible dates?
Yes. Supply an explicit date range or a relative window such as 14 days starting 30 days from each run. Every route is searched against every selected departure date, up to 120 searches per run.
Can it monitor price changes?
Yes. Stable fare IDs and a dedicated key-value store let scheduled runs emit only new fares or fares whose price changed. Unchanged runs write no dataset items.
Does a round-trip row include both selected flights?
No. Google's first round-trip response is a priced outbound choice for the requested return date. The output includes both requested search legs and the return date, while segments_scope explicitly marks the returned segments as outbound_selection.
What does it cost?
Pricing starts at $0.25 per 1,000 results on FREE and falls to $0.12 per 1,000 on GOLD. Retries, failed searches, duplicate fares, and unchanged monitoring runs are not result charges.
Related
100 free credits, no credit card.
About 30 real searches. Add the MCP to Claude or Cursor in two minutes.