# Google Flights Deal Finder (`axlymxp/google-flights-deal-finder`) Actor

Scan many Google Flights routes across months of dates and get the fares below Google's usual price, with savings, best flight and a booking-search link. Monitor mode reports only new deals and price drops. No login or proxy needed.

- **URL**: https://apify.com/axlymxp/google-flights-deal-finder.md
- **Developed by:** [axly](https://apify.com/axlymxp) (community)
- **Categories:** Travel, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 dataset items

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Google Flights Deal Finder

Find the cheap fares on many routes at once. Give it a list of routes (or origins × destinations) and a date window;
it scans Google Flights' price for **every departure day** on each route, checks the cheapest days against **Google's
own usual price** for that trip, and returns the fares that are genuinely cheap: how much below the usual price,
how they compare with the other days in your window, the best flight (airline, flight numbers, stops, times) and a
link that opens the exact search on Google Flights.

Built for flight-deal newsletters and sites, travel agents and tour operators, travel bloggers, and anyone watching a
few routes. Run it on a schedule with **monitor mode** to get only new deals and price drops.

### What you get (one row per checked fare)

| Field | Description |
| --- | --- |
| `route`, `origin`, `destination`, `tripType` | The route and trip type |
| `departureDate`, `returnDate` | Dates of the fare |
| `price`, `currency` | Lowest price Google shows for those dates |
| `usualPrice`, `savingsVsUsualPercent` | Google's usual price for that trip and how far below it this fare is |
| `usualRangeLow`, `usualRangeHigh`, `priceLevel` | Google's usual price range and whether this fare is low, typical or high |
| `windowMedianPrice`, `savingsVsWindowPercent`, `rankInWindow`, `daysInWindow`, `cheapestDayInWindow` | How the fare compares with every other day you scanned |
| `isDeal` | At least your threshold below the usual price (or below the window median when Google gives no usual price), or rated low by Google |
| `airlines`, `flightNumbers`, `stops`, `durationMinutes`, `departureTime`, `arrivalTime`, `arrivalDate`, `layovers` | The best flight for that fare |
| `cheapestToBookUntil` | Google's hint for how long prices usually stay this low, when shown |
| `googleFlightsUrl` | Opens this exact search on Google Flights |
| `previousPrice`, `priceDropPercent`, `monitorStatus` | Monitor mode: `new`, `dropped` or `unchanged` against the last run |

### How it works

1. For each route, one request returns Google's lowest fare for every departure day in the window (up to ~70 days per
   request; longer windows take a few).
2. The cheapest days (5 by default) are searched in full to get the best flight and Google's usual price for that trip.
3. Each fare is scored; with **Only output deals** on, only fares at least your threshold (15 % by default) below the
   usual price are saved.

Google's "prices are low" label is strict: on most routes even the cheapest days read "typical". The savings
percentage against the usual price and against your own window is the more useful number, so both are returned.

### Use cases

- **Deal newsletters and sites:** scan your 100 departure-city × destination combinations every morning and publish
  the fares 20 %+ below usual.
- **Travel agents and tour operators:** find the cheapest weeks to price a package; compare origins for a group trip.
- **Fare alerts:** schedule it hourly or daily with monitor mode and send new deals to Slack, email or a webhook.
- **Research:** collect daily fare curves for routes and compare seasons.

### Input

| Field | What it does |
| --- | --- |
| `routes` | `JFK-LAX`, `NYC-LON`, `SFO-NRT` … (IATA airport or city codes) |
| `origins` + `destinations` | Every combination, up to 200 routes |
| `tripType`, `tripLengthDays` | Round trip (default, 7 days) or one way |
| `daysAhead` + `windowDays`, or `dateFrom` / `dateTo` | The departure window (up to 330 days) |
| `minSavingsPercent` | Deal threshold, default 15 % |
| `candidatesPerRoute` | Cheapest days checked per route, default 5 |
| `onlyDeals` | Default on; off = every checked fare |
| `monitor`, `monitorDropPercent` | Only new fares and drops of at least N % since the last run with the same settings |
| `maxStops`, `cabin`, `adults`, `currency`, `country` | Flight options and point of sale |

Example input:

```json
{
    "origins": ["JFK", "BOS", "ORD"],
    "destinations": ["LHR", "CDG", "CUN", "HNL"],
    "tripType": "round_trip",
    "tripLengthDays": 7,
    "daysAhead": 14,
    "windowDays": 90,
    "minSavingsPercent": 20,
    "monitor": true
}
```

### Example output (values illustrative)

```json
{
    "route": "SFO-NRT",
    "tripType": "round_trip",
    "departureDate": "2026-12-03",
    "returnDate": "2026-12-10",
    "price": 709,
    "currency": "USD",
    "usualPrice": 1180,
    "savingsVsUsualPercent": 39.9,
    "usualRangeLow": 640,
    "usualRangeHigh": 2150,
    "priceLevel": "typical",
    "windowMedianPrice": 1003,
    "savingsVsWindowPercent": 29.3,
    "rankInWindow": 1,
    "daysInWindow": 60,
    "isDeal": true,
    "airlines": ["ZIPAIR Tokyo"],
    "flightNumbers": ["ZG 25"],
    "stops": 0,
    "durationMinutes": 680,
    "departureTime": "15:35",
    "arrivalTime": "19:55",
    "googleFlightsUrl": "https://www.google.com/travel/flights?tfs=...",
    "monitorStatus": "new"
}
```

### Scheduling and integrations

Create a schedule (daily is typical) with monitor mode on, and add a webhook or the Slack / email / Google Sheets
integration to the run. Monitor memory is kept per set of settings, so a moving window (`daysAhead`) keeps working.

### Use it from AI assistants

Call it through the Apify MCP server from Claude, ChatGPT or other agents: "find round trips from Boston under the
usual price to anywhere in Europe in January" becomes one run.

### FAQ

**Are these the prices I will pay?** They are the lowest prices Google Flights shows at run time for one search per
fare; airlines change fares often. Open `googleFlightsUrl` to book.

**Why is a fare marked typical but still a deal?** Google's typical range is wide. A fare can sit inside it and still
be 30 % below Google's usual price for that trip.

**Does it return every flight for every day?** No. It returns the lowest fare per day for the scan, and the best
flight for the cheapest days. For full flight lists on one date, use a regular Google Flights scraper.

**Do I need a proxy?** No. Leave it off; the actor uses Apify Proxy by itself when Google limits a request.

**How long does a run take?** Usually about a second per route. When Google rate-limits the server the run moves to
rotating proxy IPs and slows to roughly 5 routes a minute. A route Google refuses even then is retried once at the end
and, if it still fails, reported in the log and not charged.

**Is this legal?** The actor reads publicly shown prices without logging in. Check that your use complies with the
laws and terms that apply to you.

# Actor input Schema

## `routes` (type: `array`):

One route per line as ORIGIN-DESTINATION with 3-letter IATA airport or city codes, e.g. JFK-LAX, NYC-LON, SFO-NRT.

## `origins` (type: `array`):

Instead of listing routes: every origin is paired with every destination below (up to 200 routes).

## `destinations` (type: `array`):

Used together with Origins.

## `tripType` (type: `string`):

Round trip prices the outbound and return together; one way prices a single flight.

## `tripLengthDays` (type: `integer`):

Round trips: return this many days after departure.

## `daysAhead` (type: `integer`):

Relative window start, handy for scheduled runs. Ignored when 'Earliest departure' is set.

## `windowDays` (type: `integer`):

How many departure days to scan per route. Ignored when 'Latest departure' is set.

## `dateFrom` (type: `string`):

YYYY-MM-DD. Overrides 'Start the window N days from today'.

## `dateTo` (type: `string`):

YYYY-MM-DD. Overrides 'Window length'.

## `minSavingsPercent` (type: `integer`):

A fare is a deal when it is at least this much below Google's usual price for that trip (or below the route's median fare in the window when Google gives no usual price), or when Google rates it low.

## `candidatesPerRoute` (type: `integer`):

The cheapest N days of each route are checked against Google's usual price and get the best flight details.

## `onlyDeals` (type: `boolean`):

Turn off to get every checked cheap day, deal or not.

## `monitor` (type: `boolean`):

For scheduled runs: remember the last price per route and date, and output only fares not seen before or that dropped by at least the percentage below.

## `monitorDropPercent` (type: `integer`):

Monitor mode: a known fare is reported again when it is at least this much cheaper than last time.

## `maxStops` (type: `string`):

Limit the number of stops per direction.

## `cabin` (type: `string`):

Cabin class for the fare.

## `adults` (type: `integer`):

Number of adult passengers; prices are for the whole party.

## `currency` (type: `string`):

3-letter code, e.g. USD, EUR, GBP.

## `country` (type: `string`):

2-letter code; prices can differ by country.

## `maxConcurrency` (type: `integer`):

How many routes are scanned at the same time.

## `proxyConfiguration` (type: `object`):

Leave off: Google answers Apify's servers directly, and its fare calendar refuses residential and many datacenter proxies.

## Actor input object example

```json
{
  "routes": [
    "JFK-LAX",
    "SFO-NRT"
  ],
  "tripType": "round_trip",
  "tripLengthDays": 7,
  "daysAhead": 7,
  "windowDays": 60,
  "minSavingsPercent": 15,
  "candidatesPerRoute": 5,
  "onlyDeals": true,
  "monitor": false,
  "monitorDropPercent": 5,
  "maxStops": "any",
  "cabin": "economy",
  "adults": 1,
  "currency": "USD",
  "country": "US",
  "maxConcurrency": 4,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "routes": [
        "JFK-LAX",
        "SFO-NRT"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axlymxp/google-flights-deal-finder").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "routes": [
        "JFK-LAX",
        "SFO-NRT",
    ],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("axlymxp/google-flights-deal-finder").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "routes": [
    "JFK-LAX",
    "SFO-NRT"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call axlymxp/google-flights-deal-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,axlymxp/google-flights-deal-finder"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/8pyXeUD1895Wz3vbT/builds/LLbzrQWL2NTAxKmIp/openapi.json
