Here is a thing I got wrong for a long time: a cheap flight and a good deal are not the same thing. Pull the cheapest destinations from any airport and the top of the list is mostly short-haul, cheap because it is close, not because the fare is unusual. The ones worth chasing are priced below their own norm. The Google Flights Deals API on Apify answers that by attaching a typical-price baseline to every result, sourced from Google Flights.
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.
Is there an API for Google Flights deals?
No. Google retired QPX Express in 2018 and has never shipped a public flights API, deals tab included. What exists is a scraper you consume like an API: send an airport code, get structured JSON back. The framing matters because the deals feed is not a search: you give it a departure point and it tells you where is cheap right now, a different query from the point-to-point search most flight APIs answer.
What the Google Flights Deals API returns
The Google Flights Deals API returns the thirty cheapest destinations from an airport as structured JSON, each carrying its price, what that route typically costs, and a flag for whether it beats the baseline.
| Field | Example | Notes |
|---|---|---|
price |
312 |
Fare in the requested currency |
average_price |
498 |
What this route typically costs |
savings_percent |
37.3 |
The gap, as a percentage |
is_below_typical |
true |
The one field that separates bargains from short-hauls |
outbound_date |
2026-09-12 |
Exact dates for the specific itinerary |
flight_link |
https://www.google.com/travel/flights/... |
Booking link |
You also get name, country, a description and thumbnail, plus route, airline, stops, and flight_duration in minutes.
Stated plainly: this returns a snapshot with a baseline. It does not track prices over time, keep history, or send alerts. It is the data layer you build those on, not the alerting product.
Who this is for
Travel affiliates who need better than a list sorted by price. Fare newsletters picking five destinations a week and justifying each. Developers building a price-alert product on a source with a reference price attached. AI travel agents answering "where can I go cheaply from here".
The manual way, and where it breaks
Google Flights encodes its whole query into an opaque URL blob you reverse-engineer per filter, and results render through JavaScript, so a plain HTTP request comes back nearly empty. Worse, the typical-price figure is not printed next to each card as a number. Getting a baseline out of the DOM means parsing a comparative phrase rendered differently across locales, the kind of thing that silently returns None three weeks after it shipped.
The faster way: run the Google Flights Deals API
One airport code in, thirty scored destinations out.
Apify Console
- Open the Google Flights Deals API and click Try for free.
- Put a 3-letter IATA code in
departureId. No arrival field, by design. - Run it and download the dataset as JSON, CSV, or Excel.
REST
curl -X POST "https://api.apify.com/v2/acts/johnvc~google-flights-deals-api/runs?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "departureId": "JFK", "maxDealsPerAirport": 30, "currency": "USD" }'
Run endpoint reference: the Apify API docs.
Find flight bargains in Python
Filter on the flag rather than sorting by price:
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("johnvc/google-flights-deals-api").call(
run_input={"departureId": "JFK", "maxDealsPerAirport": 30, "currency": "USD"}
)
items = list(client.dataset(run.default_dataset_id).iterate_items())
deals = [i for i in items if i.get("result_type") == "deal"]
bargains = [d for d in deals if d.get("is_below_typical")]
for deal in sorted(bargains, key=lambda d: -(d.get("savings_percent") or 0)):
print(deal["name"], deal["price"], "vs", deal["average_price"],
f"({deal['savings_percent']}% below)", deal["outbound_date"])
Measured across three hubs during the build, between 6 and 30 percent of the feed clears its own baseline on a given day. That is the honest yield, and why the flag earns its place: sorting by price and taking the top five hands you the wrong five. The runnable version is Find Genuine Flight Bargains From Your Airport.
Build your own fare history
The Actor keeps no history, which sounds like a limitation and is really a design line: it hands you a fare and a reference price per row, and you decide what to keep. Save a task, attach a schedule, store rows keyed on departure, arrival, and date. After a few weeks you own a fare record nobody can revoke, every row carrying what that route normally cost that day. Start from Fare Data With a Typical-Price Baseline, which takes several airports at once.
Narrow it to the trip you would actually take
The filters map to how people search: maxStops: nonstop for direct routes, in Nonstop Flight Bargains From Any Airport; travelDuration: weekend for short trips, in Find Cheap Weekend Trips From Your Airport; travelClass: business for the premium cabin, in Cheap Business Class Deals From an Airport. Non-English locales work the same way: 查询从上海出发的低价机票目的地.
One filter behaves differently, and the Actor logs a warning when you set it: maxDurationMinutes makes the source stop returning the baseline, switching off savings and is_below_typical. I found that the hard way by changing several inputs at once and blaming the wrong one. Isolate variables.
Use it from Claude and other MCP clients
Apify exposes the Actor over the Model Context Protocol, so Claude, Claude Code, and Cursor can run a live lookup mid-conversation and answer "where can I fly cheaply from Chicago next month, and which are below normal" with current fares. More on Claude Code at claude.ai.
The example repo
✈️ Google Flights Deals API: cheap destinations as clean JSON
Give it an airport and get back the thirty cheapest destinations you can fly to from there, as structured JSON. Each one comes with the price, the typical price for that route, exact dates, airline, stops, duration, a photo, and a booking link.
The part nobody else gives you: which of them are actually bargains. A cheap fare and a good deal are not the same thing.
Actor: Google Flights Deals API on Apify Store
Video Walkthrough
https://www.youtube.com/watch?v=jREWahDGhJM
Quick Start
git clone https://github.com/johnisanerd/Apify-Google-Flights-Deals-API.git
cd Apify-Google-Flights-Deals-API
cp .env.example .env # paste your Apify token
uv sync
uv run google-flights-deals-api-example.py
Get a free Apify API key at apify.com.
Why Use This Google Flights Deals API?
-
Bargain detection, not just cheap fares. Every row carries
average_price, what that route typically costs, plussavings,savings_percent, and anis_below_typicalflag. - One…
Python quick start, filter variants, and MCP setup for Claude, Cursor, and ChatGPT.
FAQ about scraping Google Flights deals
Is this flight deals scraper free, and what does it cost?
Billing is per deal returned, plus a small run start fee, so a thirty-destination sweep is thirty billed rows with nothing hidden behind it. maxDealsPerAirport caps the count before a run starts. New Apify accounts come with free credit, so early runs usually cost nothing.
How do flight price alerts work, and can this scraper send them?
It cannot, and any tool claiming otherwise on top of this feed is doing the alerting itself. An alert is two pieces: a repeated observation and a rule about when to notify. This scraper is the observation half, and a good one, because each row arrives with a reference price, so your rule can be "below typical" rather than a threshold you guessed.
Can this scraper find deals without me picking dates?
Yes, and it is the default. Leave outboundDate blank and the feed picks cheap dates, returning the exact outbound_date and return_date it found. That is the opposite of a normal flight search, and why this answers "when should I go" as well as "where".
What does the scraper mean by "below typical price"?
It compares the fare to what that route usually costs, not to the other destinations in your results, so a $312 flight can be below typical while a $190 one is not. Negative savings mean a route is priced above its own norm, and those rows are useful too: they say what to skip.
Can this scraper run from Claude or another MCP client?
Yes. Connect the Apify MCP server and it becomes a callable tool in Claude, Claude Code, or Cursor, so an agent pulls live deals from a prompt.
Can an AI agent pay for this scraper in USDC with x402?
Yes. The Google Flights Deals API supports agentic payments via the x402 protocol, so AI agents and MCP clients can pay for runs in USDC on Base with no Apify account or API token. Point your agent at the Apify MCP server and it can discover, pay for, and run the scraper autonomously; the Apify x402 announcement has the details.
More from Truffle Pig Data
Same kind of JSON: Google Travel Explore API for ideas with hotel prices, Google Flights Data Scraper for point-to-point search, Google Hotels Search Scraper for the nights, and Google Maps Photos API for where you land.
Wrapping up
Cheapest and best-value are different sorts, and only one belongs in front of a reader. Try the Google Flights Deals API, or clone the example repo and point it at your own home airport.
Top comments (0)