Getting live flight prices out of Google Flights by hand is a grind. There is no public API to call, the search URL hides the whole query behind an opaque tfs
blob, and the page renders its results with JavaScript that fights simple scripts. I'll show the manual way and where it breaks, then a faster path, and a repo you can clone. The faster path uses the Google Flights API on Apify, which turns a route and a date into structured JSON.
Disclosure: the Apify links in this post are affiliate links. If you run the Actor, I may earn a referral commission at no extra cost to you.
No. Google retired QPX Express in 2018 and has never shipped a public Google Flights API. There is no key to request and no endpoint to call, which is why a search for "google flights api" mostly turns up scraping libraries and hosted scrapers. So in practice a Google Flights API means a scraper you consume like an API: send a route and a date, get flights and prices back as JSON.
The Google Flights API returns every itinerary for a route as structured JSON: price, airlines, stops, duration, departure and arrival times, plus a price insight for the route and optional direct booking links.
| Field | Example | Notes |
|---|---|---|
price |
||
299 |
||
| Per the search currency | ||
airlines |
||
AA |
||
| Operating carriers on the itinerary | ||
stops_label |
||
Nonstop |
||
With stops as an integer too |
||
duration |
||
5h 30m |
||
| Total travel time | ||
price_insights |
||
{ "price_level": "typical", "typical_price_range": [299, 450] } |
||
| Today's fare against a normal band | ||
booking_url |
||
https://www.jetblue.com/booking/... |
||
| Direct link, one-way only |
Each dataset item is one page of results holding many flights, and the flat all_flights
array gives you one row per itinerary for easy into a table.
Travel aggregators building fare comparison, indie developers tracking a route for a trip, analysts collecting pricing trends, and anyone wiring live fares into an AI agent.
The DIY route is to build the Google Flights URL yourself, render the page in a headless browser, and parse the result cards. It works in a quick local test, then falls over. The tfs
parameter is a Base64 blob you have to reverse-engineer for every filter. The results load through JavaScript, so a plain HTTP request comes back nearly empty. And the layout shifts often enough that your selectors rot within a few weeks. Add proxies and retries on top, and you're maintaining infrastructure instead of shipping your feature.
You send a documented JSON input and get a documented JSON output, with nothing to keep alive.
Apify Console
departure_id
, arrival_id
, and outbound_date
.REST
curl -X POST "https://api.apify.com/v2/acts/johnvc~Google-Flights-Data-Scraper-Flight-and-Price-Search/runs?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "departure_id": "JFK", "arrival_id": "LHR", "outbound_date": "2026-11-25", "max_pages": 1 }'
Run endpoint reference: the Apify API docs.
Call the Actor with apify-client
. The flat all_flights
array is one row per itinerary:
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("johnvc/Google-Flights-Data-Scraper-Flight-and-Price-Search").call(
run_input={
"departure_id": "JFK",
"arrival_id": "LHR",
"outbound_date": "2026-11-25",
"max_stops": 0,
"currency": "USD",
"max_pages": 1,
}
)
for page in client.dataset(run["defaultDatasetId"]).iterate_items():
insights = page.get("price_insights") or {}
print(insights.get("lowest_price"), insights.get("price_level"))
for flight in page.get("all_flights", []):
print(flight["route"], flight["price"], flight["airlines"], flight["stops_label"], flight["duration"])
There is a ready-to-run version in the published task Get Google Flights Prices in Python by API.
A single search answers one question. The value comes from running the same search on a schedule and watching the fare move. Save the run as a task, attach an Apify schedule with a cron expression like 0 7 * * *
, and each run appends a fresh page with its own search_timestamp
and price_insights
, which gives you a fare history you can export. The worked example is the task Track NYC to London flight prices by API.
Both departure_id
and arrival_id
accept comma-separated codes, so CDG,ORY
searches every Paris airport in one run. For multi-leg trips, pass multi_city_json
with a list of legs and the Actor prices the whole itinerary the way Google Flights does, including open-jaw routings. See the task Find cheap flights from NYC to Europe by API.
Apify exposes the Actor through the Model Context Protocol, so Claude, Claude Code, and Cursor can run a live search mid-conversation and answer "what is the cheapest nonstop from JFK to LHR next month" with real data. The task Use Google Flights in Claude via MCP has the config, and you can read more about Claude Code at claude.ai.
The most efficient, reliable, and developer-friendly way to use the Google Flights API.
Actor page: apify.com/johnvc/Google-Flights-Data-Scraper-Flight-and-Price-Search Input schema: apify.com/johnvc/Google-Flights-Data-Scraper-Flight-and-Price-Search/input-schema
The Google Flights API searches flights and returns clean, structured JSON. Each page of results comes back with the top recommended flights and alternatives, full flight legs and timings, prices, price insights (level and historical range), airport details, and search metadata. It supports one-way, round-trip, and multi-city itineraries, single or multiple airports, filters for price, stops, airlines, and passenger counts, and can optionally resolve direct airline and OTA booking links. Localized across 29+ languages and 39+ countries.
Clone the repository
git clone https://github.com/johnisanerd/Apify-Google-Flights-API.git
cd Apify-Google-Flights-API
Install dependencies with UV
…The repo has a Python quick start, the booking-options variant, and the MCP setup, so you can go from clone to first result in a few minutes.
There is no free official API to compare against, so the honest answer is per-page billing. A typical search fits on one page and costs one page event, and max_pages
caps the spend before a run starts. New Apify accounts come with free platform credit, so early searches usually cost nothing out of pocket. The one setting that changes the math is fetch_booking_options
, since each resolved booking URL bills separately and a one-way search commonly returns 80 to 120 of them.
Call the Actor with apify-client
as shown above, then read the flat all_flights
array for one row per flight. The published Python task carries a runnable version.
Yes. Connect the Apify MCP server to Claude, Claude Code, or Cursor and the Actor appears as a callable tool that runs a live search from your prompt.
Yes, and it is the most popular way to run it. Save a task per route, attach an Apify schedule with a cron expression, and each run appends a new page of fares. Scheduling is how the price-tracking use case works, and you can start from the Google Flights API.
No, and treat anything that claims otherwise with suspicion. You get price_insights
: a price_level
for the current fare and a typical_price_range
for the route. That is a read on today's fare against a normal band, not a forecast. If you want something forward-looking, schedule the scraper and model the trend from the record you own.
You can, and for a one-off you might. The tradeoff is the tfs
blob, JavaScript rendering, proxies, and layout changes you then own forever. A hosted scraper trades a per-page fee for never touching that maintenance.
Same Actor, other angles: Give your AI agent real flight prices (Peerlist), Google Flights API for AI Agents on Medium, and the Google Flights API write-up on LinkedIn.
A flight is one leg of a trip. These related Actors return the same kind of structured JSON: Google Travel Explore API for when you know the origin but not the destination, Google Hotels Search Scraper for the nights, and Google Maps Directions API for the airport-to-hotel leg.
There's no official Google Flights API, but you can still get the same data as clean JSON without babysitting a scraper. Try the Google Flights API, or clone the example repo and point it at your own routes.