DEV Community

Ocius Data
Ocius Data

Posted on Fully Autonomous

Track flight prices daily with a scheduled API call (Google Flights data, Python)

Disclosure: I build and maintain the Apify Actor used in this tutorial (ocius-data/google-flights-prices). The tracking logic (a CSV with one row per check) works with any data source; the code below uses ours.

Google Flights has price alerts, but they live in your inbox, they cover one route at a time and you cannot export the history. If you want to decide when to buy a ticket, compare several routes, or feed fares into a spreadsheet or a dashboard, you need the prices as data, collected at the same time every day.

Google does not offer a public Google Flights API (the QPX Express API was shut down in 2018). This tutorial uses an Apify Actor that reads the same results page you see in the browser and returns each itinerary as JSON: airlines, flight numbers, times, stops, layovers, CO2 and the price in your currency.

We will build a small Python script that:

  1. searches one route and set of dates,
  2. appends the cheapest price (and the cheapest nonstop price) to a CSV file,
  3. prints the change since the previous check,

and then run it once a day.

What you need

  • Python 3.11 or later.
  • A free Apify account and its API token (Console, Settings, API and Integrations).
  • The official client, version 3.x: pip install "apify-client>=3".

Step 1: one search

import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])

run = client.actor("ocius-data/google-flights-prices").call(run_input={
    "origin": "BOG",
    "destination": "MIA",
    "departureDate": "2026-12-15",
    "returnDate": "2026-12-22",
    "currency": "USD",
    "maxResults": 20,
})

flights = list(client.dataset(run.default_dataset_id).iterate_items())
for f in flights[:5]:
    print(f["price"], f["currency"], f["airlines"], f["stops"], "stop(s)", f["departureTime"])
Enter fullscreen mode Exit fullscreen mode

A few details that matter for a price tracker:

  • origin and destination accept airport codes (BOG) or city names ("New York"). A city searches all of its airports.
  • With a returnDate, price is Google's lowest round-trip total that starts with that outbound flight (priceType: "round_trip_total"). Leave returnDate empty for one-way prices.
  • Prices are totals for all passengers, taxes included.
  • country sets the market you search from. Fares can differ by market, so keep it fixed across checks.
  • Google lists its "best" flights first, not the cheapest. The cheapest price you compute is the lowest among the itineraries you saved, so a higher maxResults covers more of the results page.

Step 2: keep a history

The full script is in the examples repository: python/flight_price_tracker.py. The core is short: take the cheapest itinerary, append one row to a CSV and compare it with the last row of the same search.

from datetime import datetime, timezone

cheapest = min(flights, key=lambda r: r["price"])
nonstop = [r["price"] for r in flights if r.get("stops") == 0]
row = {
    "checkedAt": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
    "origin": "BOG", "destination": "MIA",
    "departureDate": "2026-12-15", "returnDate": "2026-12-22",
    "currency": cheapest["currency"],
    "itineraries": len(flights),
    "cheapestPrice": cheapest["price"],
    "cheapestAirlines": " + ".join(cheapest.get("airlines") or []),
    "cheapestStops": cheapest.get("stops"),
    "cheapestNonstopPrice": min(nonstop) if nonstop else "",
    "googleFlightsUrl": cheapest.get("googleFlightsUrl", ""),
}
Enter fullscreen mode Exit fullscreen mode

Run it from the command line:

export APIFY_TOKEN=your_token
python python/flight_price_tracker.py BOG MIA 2026-12-15 --return-date 2026-12-22 --max-results 20
Enter fullscreen mode Exit fullscreen mode

The output of a test run on 3 November 2026 (with --max-results 5):

BOG -> MIA, 2026-12-15 to 2026-12-22: 5 itineraries
  Cheapest: 533 USD | LATAM | 1 stop(s)
  Cheapest nonstop: 705 USD
  First check of this search. History saved to flight_prices.csv
Enter fullscreen mode Exit fullscreen mode

The second run prints the change since the previous check, for example Change since the previous check: +0.00 USD (was 533.0). Every row also stores googleFlightsUrl, which opens Google Flights with that flight selected, so you can book from the alert.

Step 3: run it every day

You have two options:

  • On your own machine or server: cron (0 8 * * * cd /path/to/repo && python python/flight_price_tracker.py BOG MIA 2026-12-15 --return-date 2026-12-22) or Windows Task Scheduler. The CSV stays local.
  • On Apify: save the input as a task in Apify Console and add a schedule (daily at 08:00, for example). Each run keeps its own dataset, and a webhook or the Google Sheets integration can collect the results. In that case you compute the change in the destination, not in a local CSV.

Run the check at the same hour every day. Fares move during the day, and comparing a morning price with an evening price adds noise to the history.

Step 4: find the cheapest day in a date range

If your dates are flexible, the date grid mode returns the cheapest price for each departure date in a range of up to 62 days, instead of a list of itineraries:

run = client.actor("ocius-data/google-flights-prices").call(run_input={
    "origin": "BOG",
    "destination": "MIA",
    "dateGrid": True,
    "dateGridStart": "2026-12-14",
    "dateGridEnd": "2026-12-16",
    "tripLengthDays": 7,
    "currency": "USD",
})
for day in client.dataset(run.default_dataset_id).iterate_items():
    print(day["departureDate"], day["returnDate"], day["price"], day["currency"],
          "nonstop" if day["nonstopAvailable"] else "with stops")
Enter fullscreen mode Exit fullscreen mode

Leave tripLengthDays empty for one-way prices. Each row also includes cheapestFlight (airline, flight numbers and times) and cheapestNonstopPrice.

Cost

At the time of writing: USD 0.001 per itinerary saved and USD 0.01 per date in date grid mode. A daily check of one route with 20 itineraries costs about USD 0.02 per day; a 31-day date grid costs about USD 0.31. Searches without flights and failed requests are not charged. Check the Actor page for current pricing.

Limits worth knowing

  • Prices change constantly and depend on the market, the currency and the moment of the search, as on Google Flights itself. The airline's booking page can show a slightly different final price.
  • Baggage fees and fare families (basic, main, flex) appear only on Google's booking page and are not included.
  • Infants and multi-city trips are not supported.

Try it: Google Flights API on Apify. The script used here is in the examples repository. Feature requests are welcome in the Actor's Issues tab.

Top comments (0)