Flight Price Tracker — Cheapest Day to Fly & Airfare Alerts
Pricing
$4.00 / 1,000 fare row (cheapest of the day)s
Flight Price Tracker — Cheapest Day to Fly & Airfare Alerts
Flight price tracker for Google Flights: the cheapest fare for every departure day in your window, one row per day with price, airline, stops and times, ranked so the cheapest day to fly is row one. Set a max price and only days under it are delivered and billed. Pay per fare row.
Pricing
$4.00 / 1,000 fare row (cheapest of the day)s
Rating
0.0
(0)
Developer
Tedj MEABIOU
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 hours ago
Last modified
Categories
Share
A flight price tracker that reads Google Flights and returns the cheapest fare for every departure day in your window — one row per route and day, with the airline, stops, times and duration behind that price. Run it once to see the cheapest day to fly; schedule it and you have airfare price tracking you own, with a maxPrice line that turns any run into a flight price alert. No API key, no login, no browser.
It is a different product from an itinerary scraper. An itinerary scraper bills every fare Google lists for a day (usually 10–35). This bills one row per day, so a 30-day window on a route is 30 rows — cheap enough to run every morning.
Last verified working: 2026-08-29.
What does the flight price tracker do?
You give it routes, a first departure day and a window length. For each route it searches every day in the window, keeps the cheapest itinerary of each day, ranks the days, and delivers:
farerows — one per route and departure day:pricefor all passengers,airlineandairlines,stops,depart_time/arrive_time,durationandduration_minutes, everylayover,co2_kg, thegoogle_urlthat reproduces the search,itineraries_seen(how many fares Google listed that day), and two ranking fields:rank_in_window(1 = the cheapest day of the window) andcheapest_in_window(trueon exactly one day per route).statusrows — one per route:days_searched,faresdelivered,filtered(days overmaxPrice),no_results,errors, the window'scheapestfare and itscheapest_date. Never charged.
Round trips are priced the way Google shows them: set tripLengthDays and every day becomes a round trip returning that many days later, with price as the total for both legs and round_trip_total: true.
Cheapest day to fly, one row per day
The question most people bring to Google Flights is not "what is the fare" but "which day should I leave". Google answers it with a calendar you have to read by eye. This answers it as data: the fare row with cheapest_in_window: true is the day, and rank_in_window orders the rest — so "the three cheapest departures in October" is a filter on one column, not a spreadsheet exercise.
A seven-day window on one route is seven searches and at most seven rows. A month is 30. Two routes over a month is 60 rows, and the two status rows tell you which route and day won overall. Sort by price, or by depart_date to see the shape of the month; every row also says what it beat, in itineraries_seen.
The ranking is computed over the whole window before any maxPrice filter, so a filtered run still tells you that the day you kept was, say, the second-cheapest of the month.
Airfare price tracking on a schedule
Google's own tracker emails you when a fare moves, on the routes and dates it chooses, and keeps the history to itself. Scheduling this run gives you the same signal as rows you keep:
- Every row carries
fetched_at, so a flight price history for your routes falls out of the dataset — one series per route and departure day, growing by one point per run. - Relative dates (
"30 days","6 weeks") mean a scheduled run always looks the same distance ahead. It never goes stale, and it never prices a day that has passed. - The window moves with the calendar, so yesterday's rank 1 can be compared with today's: that is flight price monitoring for a route, not a one-off snapshot.
- The
statusrows give you a one-line summary per route per run —cheapestandcheapest_date— which is usually all a daily message needs.
At one row per day, the arithmetic of tracking is simple: a daily run on three routes over a 30-day window is 90 rows a day, about 2,700 a month. The price per row is on this page's pricing tab; the compute behind a run that size is a fraction of a cent.
Flight price alerts: maxPrice filters before billing
Set maxPrice and the run delivers only the days whose cheapest fare is at or under that number. Days over the line are dropped before billing — an alert run that finds nothing costs nothing, and the status row still tells you how many days were filtered and what the window's cheapest was, so you can see how far off the line you are.
That makes a flight price drop alert a two-node automation: schedule the run with maxPrice, and send a message when the dataset has any fare row. You do not need to store the previous price or diff anything — the filter is the comparison. Because you keep every row, the alert can be smarter than Google's: "nonstop under 400 on any of these three routes, any day next month" is one input.
{ "routes": ["JFK-LHR", "EWR-LHR"], "departDate": "14 days", "days": 30, "maxStops": "nonstop", "maxPrice": 400, "currency": "USD" }
Nothing under 400? Zero fare rows, zero charge, two status rows with the real minimum in cheapest.
Google Flights price tracker vs this actor
Google's tracker, Hopper, Kayak alerts and the airline apps all do one thing well: tell you when their pick of dates moves. What none of them gives you is the table — every day, with the fare and the itinerary behind it, in a format you can join, chart, or feed to an automation. The comparison in practice:
| Google's price tracking | This actor | |
|---|---|---|
| Which days | The dates you saved, or Google's suggestion | Every day of a window you set, 1–60 days |
| Output | An email | A dataset row per day: price, airline, stops, times, rank |
| History | Google keeps it | You keep it — fetched_at on every row |
| Alert condition | Google decides what counts as a drop | Your maxPrice, per route, with stops and cabin filters |
| Integration | None | Apify API, n8n, Make, Zapier, MCP for AI agents |
| Cost | Free, unexportable | Per delivered row, nothing for empty or filtered days |
If what you want is cheap flights on a route as a one-off, Google's page is fine. If you want to track flight prices across dates over weeks, feed them to a sheet or a bot, or watch a line and act when a fare crosses it, that needs rows, and rows are what this returns.
Input
| Field | What it does |
|---|---|
routes | Routes as airport codes, one per line: LIS-LHR, JFK-LAX. Google's city codes work too — NYC-LON searches every New York and London airport. Written LIS-LHR, lis > lhr or JFK to LAX, all the same. |
departDate | The first day of the window: 2026-10-05, or relative so schedules never go stale: 30 days, 6 weeks, tomorrow. Past dates are rejected. |
days | How many consecutive departure days to price, 1–60. One search and at most one billed row per day. Default 14. |
tripLengthDays | 0 = one-way. N = every day is a round trip returning N days after departure, priced for both legs. |
seat | economy, premium_economy, business, first. |
adults | Up to 9. Prices are the total for everyone travelling. |
maxStops | any, nonstop, one_or_fewer, two_or_fewer — applied before picking the day's cheapest fare. |
maxPrice | 0 = deliver every day. N = deliver only days at or under N in currency; the rest are dropped before billing. |
currency | Any ISO code for every price, e.g. USD, EUR, GBP. |
market | Two-letter country code for the Google market (gl). Fares and airlines differ by market. |
sessions, perIp | Parallel proxy sessions and the pace of each. Leave alone unless a run is throttled. |
proxyConfiguration | Apify Proxy. Required — Google blocks datacentre traffic that is not rotated. |
Example: the cheapest day to fly in the next month, two routes
{ "routes": ["LIS-LHR", "LIS-CDG"], "departDate": "tomorrow", "days": 30, "currency": "EUR", "market": "pt" }
Example: a daily nonstop business-class watch, week-long round trips
{ "routes": ["JFK-LHR"], "departDate": "14 days", "days": 21, "tripLengthDays": 7, "seat": "business", "maxStops": "nonstop" }
Example: an alert line for a family of four
{ "routes": ["LHR-JFK"], "departDate": "45 days", "days": 14, "adults": 4, "maxPrice": 1800, "currency": "GBP", "market": "gb" }
Output
One fare row per route and day:
{"type": "fare", "route": "LIS-LHR", "origin": "LIS", "destination": "LHR", "trip": "one_way","depart_date": "2026-10-05", "return_date": null, "seat": "economy", "adults": 1, "currency": "USD","price": 127, "price_display": "127 US dollars", "round_trip_total": false,"airline": "Tap Air Portugal", "airlines": ["Tap Air Portugal"], "stops": 0,"depart_time": "8:00 PM", "arrive_time": "10:55 PM", "depart_day": "Monday, October 5", "arrive_day": "Monday, October 5","duration": "2 hr 55 min", "duration_minutes": 175,"layovers": null, "layover_airports": null, "overnight_layover": false, "co2_kg": 123,"google_url": "https://www.google.com/travel/flights?tfs=...","itineraries_seen": 12, "cheapest_in_window": true, "rank_in_window": 1,"fetched_at": "2026-08-29T06:25:14+00:00"}
A day whose cheapest fare has a connection carries it:
{"stops": 1, "duration_minutes": 785,"layovers": [{ "index": 1, "of": 1, "minutes": 550, "airport": "Aéroport de Paris-Charles de Gaulle", "city": "Paris" }],"layover_airports": ["Aéroport de Paris-Charles de Gaulle"]}
And one status row per route:
{"type": "status", "route": "LIS-LHR", "trip": "one_way", "seat": "economy", "currency": "USD","depart_date": "2026-10-05", "return_date": null,"days_searched": 7, "fares": 7, "filtered": 0, "no_results": 0, "errors": 0,"cheapest": 127, "cheapest_date": "2026-10-05", "status": "ok", "error": null,"fetched_at": "2026-08-29T06:25:20+00:00"}
duration_minutes exists so you can sort without parsing "13 hr 5 min"; rank_in_window and cheapest_in_window exist so you never have to compute the minimum yourself. The dataset has three views in the Console — Overview, Cheapest fare by day and Run status — and exports to CSV, Excel or JSON.
How much does it cost?
Pay per event, one event per delivered fare row — at most one per route and departure day. Days on which Google lists nothing, days dropped by maxPrice, failed days and status rows are free, and nothing a spending limit refused is ever delivered.
Some worked sizes at the listed per-row price:
- One route, 7 days: 7 rows.
- One route, 30 days: 30 rows.
- Three routes, 30 days, daily for a month: 90 rows a run, about 2,700 a month.
- An alert run with
maxPricethat finds nothing: 0 rows, $0 beyond a fraction of a cent of compute.
The verified runs behind this listing used $0.0002–$0.003 of platform compute each. Exact per-row pricing is on this page's pricing tab.
How to use it from Python, JavaScript, curl, n8n, Make or an AI agent
Run it and read the dataset. In Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("kestrel/flight-price-tracker").call(run_input={"routes": ["LIS-LHR"], "departDate": "30 days", "days": 14, "currency": "EUR",})for row in client.dataset(run["defaultDatasetId"]).iterate_items():if row["type"] == "fare":print(row["rank_in_window"], row["depart_date"], row["price"], row["airline"], row["stops"])
In JavaScript (Node):
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('kestrel/flight-price-tracker').call({routes: ['JFK-LHR'], departDate: '14 days', days: 21, tripLengthDays: 7, maxStops: 'nonstop',});const { items } = await client.dataset(run.defaultDatasetId).listItems();const best = items.find((i) => i.type === 'fare' && i.cheapest_in_window);console.log(best.depart_date, best.price, best.airline);
With curl, synchronously, getting the dataset straight back:
curl -X POST "https://api.apify.com/v2/acts/kestrel~flight-price-tracker/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \-H 'Content-Type: application/json' \-d '{"routes":["LIS-LHR"],"departDate":"30 days","days":7,"maxPrice":150,"currency":"EUR"}'
For n8n and Make (and Zapier), the whole alert is three steps: a Schedule trigger, an HTTP Request to the run-sync-get-dataset-items URL above with the JSON body, and a message step that fires when the returned array has any row with type: "fare". With maxPrice set, an empty array means "nothing under the line today". Map depart_date, price, airline and google_url into the message and the recipient can book from it.
For AI agents, the actor is callable over Apify's MCP server, so an agent asked "when is it cheapest to fly Lisbon to London next month" can run it and read the cheapest_in_window row back with no glue code.
Is it legal to track prices from Google Flights?
This reads the same public result page a visitor sees, with no login and no account, and it collects no personal data — a fare is a price, an airline and two timestamps. In the EU and the US, reading public pages that contain no personal data is broadly accepted, and hiQ v. LinkedIn is the usual reference point for public data specifically.
That is not the whole story: Google's Terms of Service discourage automated access, so this is a terms question rather than a criminal one, and the responsibility sits with the operator of the run. Prices are facts and facts are not copyrightable, but a database can attract sui generis protection in the EU, so do not redistribute the raw dataset as a product. If you are unsure how any of this applies to your use, ask a lawyer — this is not legal advice.
Limits and honest notes
- One row per day means one itinerary per day. The row is the cheapest fare Google lists for that day under your cabin and stop filters. If you need every itinerary — to compare airlines on the same day, or to see the second-cheapest option — use the Google Flights Scraper, which bills per itinerary instead.
- Google's list is what you get. Fares visible only after login, in corporate channels or on airline sites Google does not index are not in it.
- Results are read in English. The parser reads Google's English accessibility labels, which is why there is no language input;
currencyandmarketare the two inputs that change the fares themselves. - Prices include what Google shows — taxes and carrier fees as Google presents them. Baggage and seat fees are not in the number.
- A currency swap is an error, not a row. Some markets ignore the requested currency; a day priced in another one is reported in
statusrather than billed. - The window is capped at 60 days per run. For a longer horizon, run twice with different
departDatevalues. - Ties go to the earlier day. When two days share the lowest fare, the earlier departure takes rank 1.
FAQ
Does it need a Google Flights API key?
No. There is no public Google Flights API to hold a key for, and this uses none. No login, no cookies, no browser — it builds the same tfs query parameter Google puts in its own URLs and reads the page Google returns. If you want a flight price tracking api shape, call it synchronously through Apify's API (the curl example above) and treat the rows as the response.
How do I find the cheapest day to fly on Google Flights?
Set departDate to the first day you could leave and days to how far you are flexible. The fare row with cheapest_in_window: true is the answer; rank_in_window orders the alternatives. The status row repeats it as cheapest and cheapest_date if you only want the headline. That is the cheapest day to fly google flights search, as one input and one column.
Can I get flight price history?
Not retroactively — Google does not publish history, and neither can this. What you can do is build it: schedule a daily run with a relative departDate, and every row lands with fetched_at. Two weeks of that is two weeks of history per route and departure day that is yours to keep and chart — a flight price calendar over time, not just across dates.
How do I set up Google Flights price alerts with it?
Set maxPrice, schedule the run, and send a message whenever the dataset contains a fare row. Because filtering happens before billing, a quiet day costs nothing. Google flights price alerts in their native form only cover the dates you saved; this covers every day of the window and any stop or cabin filter you set.
Does it do round trips?
Yes. tripLengthDays: 7 prices every day of the window as a week-long round trip; price is the total for both legs and round_trip_total is true. Round trip flight prices across a window are how most leisure searches actually look, and that is one input here.
What about nonstop-only, or business class?
maxStops: "nonstop" restricts every day's search to nonstop itineraries before the cheapest is picked, so the row is the cheapest nonstop that day — a nonstop flight search per day rather than one that a cheap connection would otherwise win. seat: "business" prices business class fares the same way; expect a different, smaller market than economy rather than a fixed multiple of it.
Why do prices differ from what I see in my browser?
Three usual reasons: your market differs from your browser's country, your currency differs, or the fare moved — airline pricing changes through the day. Set market and currency explicitly and re-run to compare like for like; each row carries the google_url that reproduces the exact search.
How many routes and days can one run track?
Up to 60 days per route, any number of routes; each route is searched in parallel across sessions. A 30-day window on five routes is 150 searches and, with no filter, 150 rows. Larger horizons are two runs with different departDate values.
Is it a scraper for Skyscanner or Kayak?
No — it reads Google Flights. Those sites and Google draw on largely the same carriers and online travel agents, so for airline ticket prices on a route the numbers move together and you get them from one source on one schedule. For the full itinerary list from the same source, the google flights scraper linked below is the sibling listing.
Is there a free tier?
Empty days, filtered days, failed days and status rows are always free, and Apify's free plan includes monthly platform credit you can spend on the paid rows. A run that finds nothing under your maxPrice costs nothing beyond a fraction of a cent of compute.
Related scrapers
Need every itinerary, not just the cheapest? The Google Flights Scraper is the same engine billing per itinerary row — use it when you want to compare airlines and times on the same day; use this one when you want the cheapest flights by date across a window.
The rest of the trip, from the same publisher, with the same pay-per-delivered-row billing:
- Google Hotels Prices Scraper — hotel prices and every booking site's rate for a stay, for the same dates you just priced the fare for.
- Airbnb Scraper — Airbnb prices, availability calendars and occupancy.
- Airbnb Reviews Scraper — every guest review of an Airbnb listing.
- Agoda Reviews Scraper — Agoda hotel reviews with separate positives and negatives.
All of them bill per delivered row, never charge for rows a filter or a spending limit removed, and write an Apify dataset you can export to CSV, Excel or JSON.