# Google Flights API (`arceus15/google-flights-api`) Actor

Scrape flight prices, airlines, durations, stops and times from Google Flights. Supports one-way, round-trip and multi-city searches. Outputs structured flight records and an Excel export.

- **URL**: https://apify.com/arceus15/google-flights-api.md
- **Developed by:** [Rajas Samarth](https://apify.com/arceus15) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 70.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 flight results

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

### What is Google Flights Scraper?

**Google Flights Scraper** turns a Google Flights search into a clean, structured dataset you can filter, export, and monitor.

Give it an origin, a destination and a date — or a list of multi-city legs — and it returns **one row per flight** with the **price, airline, departure and arrival times, duration, stops, airports, cabin class and a link back to Google Flights**.

It supports **one-way, round-trip and multi-city** trips, **economy through first class**, multiple passengers, and the filters fare trackers actually use: airline, total price, **price per person**, maximum duration, departure-time window and result order.

Because it runs on Apify, you also get **scheduling, run monitoring, proxy rotation, an API and integrations** without maintaining a server.

### What data can you extract?

| Field | Example | Meaning |
|---|---|---|
| `airline` | `IndiGo` | Operating airline |
| `dep_airport` / `arr_airport` | `BOM` / `DEL` | Origin and destination airports |
| `dep_time` / `arr_time` | `08:00 AM` / `10:10 AM` | Local departure and arrival times |
| `flight_date` | `2026-12-01` | Flight date |
| `duration` / `duration_min` | `2h 10m` / `130` | Total journey time |
| `stops` | `0` | Number of stops |
| `price` / `currency` | `5480.0` / `INR` | Price Google displays for the search |
| `cabin_class` | `economy` | Cabin searched |
| `trip_type` | `one-way` | Trip type searched |
| `booking_link` | `https://www.google.com/travel/flights/...` | Google Flights search URL for that leg |
| `detail_status` | `Complete` | Whether the detail view was read |
| `price_missing` | `false` | True when Google showed "price unavailable" |

Each run also writes:

- **Dataset** — one row per flight, ready for CSV, Excel, Sheets, BigQuery or an API.
- **`SUMMARY`** — search metadata, row counts, parsed price range, price history and any filter warning.
- **`OUTPUT`** — a formatted **Excel workbook** built from the same data.

### Why use this Actor?

- **Excel included.** Every run stores a ready-to-open `.xlsx` in `OUTPUT`, not just JSON rows.
- **Built-in price alerts.** Persist the minimum price per route and POST a Discord, Slack or generic JSON message when the price drops by your threshold — or when the run fails.
- **Per-person budgets.** Google shows the **total for all passengers**. `max_price_per_person` lets you filter by the number you actually care about, without mental math.
- **Filter safety.** If your filters remove every row, the Actor does **not** silently return an empty run. It reports the real parsed price range in `filter_warning` and returns the unfiltered results so you can see what went wrong.
- **Relative dates.** `depart_days_ahead` and `trip_length_days` keep scheduled searches moving forward instead of pointing at a date that has already passed.
- **Real browser.** It reads the same JavaScript-rendered results a person sees on Google Flights, including fares that appear after the first page load.
- **Apify Proxy on by default.** Browser traffic is routed through Apify Proxy, the main lever against Google returning empty results to datacenter IPs.
- **Sorting built in.** Keep Google's ranking, or sort by price, duration, departure time or arrival time.

### How to use it

1. Enter the **origin** and **destination** as three-letter IATA codes, for example `BOM` and `DEL`.
2. Set an **outbound date** in `YYYY-MM-DD`, or use **`depart_days_ahead`** to search relative to the run day.
3. Choose the **trip type**, **cabin class**, **passengers** and **currency**.
4. Optionally add filters: airline, total price, price per person, maximum duration, departure window and sort order.
5. Run the Actor and open the **Dataset** tab, or download the **`OUTPUT` Excel workbook** from the key-value store.
6. For monitoring, attach a **schedule** and a **webhook** so you get notified when the price drops.

No Google account, login or API key is required.

### Inputs

| Input | Type | What it does |
|---|---|---|
| `departure` | string | Origin IATA code, e.g. `BOM` |
| `destination` | string | Destination IATA code, e.g. `DEL` |
| `outbound_date` | string | Departure date, `YYYY-MM-DD` |
| `return_date` | string | Return date for round-trip |
| `depart_days_ahead` | integer | Depart this many days after the run starts; overrides `outbound_date` |
| `trip_length_days` | integer | Return this many days after departure; switches the search to round-trip |
| `legs` | array | Multi-city legs: `{origin, destination, date}` objects |
| `trip_type` | enum | `one-way`, `round-trip` or `multi-city` |
| `cabin_class` | enum | `economy`, `premium`, `business` or `first` |
| `adults` | integer | 1–9 |
| `children` | integer | 0–8 |
| `infants` | integer | 0–4 |
| `currency` | string | Three-letter code, e.g. `USD`, `EUR`, `INR` |
| `stops` | enum | `any`, `nonstop`, `1-stop` or `2-stops` |
| `max_results` | integer | 1–500 rows |
| `force_fresh` | boolean | Skip the short-lived cache and scrape live |
| `airlines` | array | Keep flights whose airline matches any name (substring, case-insensitive) |
| `max_price` | number | Keep flights at or below this **total** price |
| `max_price_per_person` | number | Keep flights whose price ÷ passengers is at or below this value |
| `max_duration_minutes` | integer | Keep flights at or below this total duration |
| `departure_time_from` / `departure_time_to` | string | Departure-time window, e.g. `06:00` and `22:00` |
| `sort_by` | enum | `google`, `price`, `duration`, `departure` or `arrival` |
| `proxyConfiguration` | object | Apify Proxy settings; Apify Proxy is used by default |
| `usePlaywrightSource` | boolean | Use the live browser scraper (default `true`) |
| `trackPriceHistory` | boolean | Persist the per-route minimum price across runs |
| `priceDropAlertPercent` | number | Alert threshold, default `10` (%) |
| `alertWebhookUrl` | string | Discord, Slack, Make, n8n or any JSON endpoint |
| `alertWebhookFormat` | enum | `json`, `slack` or `discord` |
| `alertOnFailure` | boolean | Send a webhook when the run fails |

### Example inputs

**One-way, cheapest first**

```json
{
  "departure": "BOM",
  "destination": "DEL",
  "outbound_date": "2026-12-01",
  "trip_type": "one-way",
  "cabin_class": "economy",
  "adults": 1,
  "currency": "INR",
  "max_results": 50,
  "sort_by": "price"
}
```

**Round-trip, nonstop, with a per-person budget**

```json
{
  "departure": "BOM",
  "destination": "DEL",
  "outbound_date": "2026-12-01",
  "return_date": "2026-12-08",
  "trip_type": "round-trip",
  "adults": 2,
  "currency": "INR",
  "stops": "nonstop",
  "max_price_per_person": 6000,
  "sort_by": "price",
  "max_results": 100
}
```

**Multi-city**

```json
{
  "trip_type": "multi-city",
  "legs": [
    { "origin": "BOM", "destination": "DEL", "date": "2026-12-01" },
    { "origin": "DEL", "destination": "BOM", "date": "2026-12-08" }
  ],
  "adults": 1,
  "currency": "INR",
  "max_results": 100
}
```

**Daily price watch (relative dates plus a Discord alert)**

```json
{
  "departure": "BOM",
  "destination": "DEL",
  "depart_days_ahead": 30,
  "trip_length_days": 7,
  "adults": 2,
  "currency": "INR",
  "max_results": 100,
  "trackPriceHistory": true,
  "priceDropAlertPercent": 10,
  "alertWebhookUrl": "https://discord.com/api/webhooks/...",
  "alertWebhookFormat": "discord"
}
```

`trip_length_days` automatically turns this into a round-trip search.

### Output

#### Dataset

One row per flight. Rows keep Google's order unless you set `sort_by`. Unpriced or partially read rows are still returned but flagged with `price_missing` or `detail_status`, so you can filter them out downstream.

```json
{
  "airline": "IndiGo",
  "dep_airport": "BOM",
  "arr_airport": "DEL",
  "dep_time": "08:00 AM",
  "arr_time": "10:10 AM",
  "flight_date": "2026-12-01",
  "duration": "2h 10m",
  "duration_min": 130,
  "stops": 0,
  "price": 5480.0,
  "currency": "INR",
  "cabin_class": "economy",
  "trip_type": "one-way",
  "booking_link": "https://www.google.com/travel/flights/...",
  "detail_status": "Complete",
  "price_missing": false
}
```

#### `SUMMARY`

A compact JSON record with the search parameters, `total_available`, `returned`, `raw_total`, `price_stats`, `filter_warning`, and — when price history is on — `current_min_price`, `previous_min_price`, `price_change_percent` and `best_min_price`.

#### `OUTPUT`

An `.xlsx` workbook with the same rows, ready to download and open.

### Price tracking and alerts

When `trackPriceHistory` is enabled (the default), the Actor stores the minimum price for the route, cabin, passenger mix and currency in a persistent key-value store. On the next run it compares the new minimum with the previous one.

- `price_change_percent` is negative when the price fell.
- A webhook is sent when the drop is at least `priceDropAlertPercent`.
- `best_min_price` keeps the lowest price ever seen for that exact search.
- Set `alertWebhookFormat` to `discord` or `slack` for incoming webhooks; leave it on `json` for Make, n8n, Zapier or your own endpoint.
- Set `alertOnFailure` to also receive a message when a run fails.
- To test the webhook immediately, set `priceDropAlertPercent` to `0` for one run, then restore it.

Changing the passengers, cabin or currency starts a **new** price baseline, because the comparison would otherwise be misleading.

### Scheduling

Create a schedule in **Apify Console → Schedules** and point it at this Actor. Use **relative dates** so the search stays current:

```json
{
  "departure": "BOM",
  "destination": "DEL",
  "depart_days_ahead": 30,
  "trip_length_days": 7,
  "adults": 2,
  "currency": "INR",
  "trackPriceHistory": true,
  "priceDropAlertPercent": 10
}
```

A daily run at 08:00 with a 10% threshold gives you a simple fare-watch service without any server.

### How much does it cost?

This Actor is paid **per result**, with a small per-run start fee:

| Event | Price |
|---|---|
| Flight result | **$1 per 1,000 rows** ($0.001 per row) |
| Actor start | **$0.0025 per GB** — about **$0.005 per run** at the default 2 GB |

A typical **100-row run costs about $0.11**; a 500-row run costs about $0.51. The per-result price includes the dataset rows, the Excel workbook and price-history tracking. Apify platform usage is included in the per-event price.

- You are charged only for rows that are saved to the dataset.
- A run that returns no rows is charged only the start fee.
- Set **`max_results`** to cap the cost of a run.
- Apify's **Maximum charge** setting caps your spend per run. If the cap is reached, the Actor stops saving rows and skips the Excel export, so you are not charged for data you did not receive.
- Cached results are still billed per row, because they are still returned to you.

### FAQ

#### Do I need a proxy?

Apify Proxy is on by default and recommended. Google sometimes serves empty results or a consent screen to datacenter IPs. If a run returns nothing, retry, switch the proxy group, or run without a proxy from a residential IP.

#### Why did I get zero rows?

The most common causes are a proxy/IP block, a Google consent screen, or a filter that removed everything. Check the run log and `SUMMARY.filter_warning`. The Actor deliberately returns unfiltered results with a warning instead of an empty dataset when filters are the cause.

#### Is the price per person or for all passengers?

Google shows the **total for all selected passengers**. Use `max_price` for the total, or `max_price_per_person` for a per-seat budget. The raw `price` field is the total Google displayed.

#### How many results can I get?

Set `max_results` up to **500**. Google typically exposes roughly 100–200 itineraries for a busy route, and fewer for thin routes. The Actor returns what the page provides.

#### Does multi-city price the whole trip as one ticket?

No. Multi-city returns flight options **for each leg**. Group rows by `dep_airport`, `arr_airport` and `flight_date` to reconstruct the itinerary. It does not produce a single through-ticket price the way Google's multi-city booking flow does.

#### Can I sort by price or duration?

Yes. Set `sort_by` to `price`, `duration`, `departure` or `arrival`. The default, `google`, keeps Google's own ranking.

#### Can I use relative dates?

Yes. `depart_days_ahead` searches N days from the run day. `trip_length_days` sets the return date N days later and switches to round-trip. Both are ignored for multi-city, whose legs carry explicit dates.

#### Does it support business or first class?

Yes. Set `cabin_class` to `premium`, `business` or `first`.

#### Can I get return flights, a price graph or booking options?

Not currently. This Actor focuses on the flight results list, filters, Excel export and price alerts. Return-flight lists, a date/price graph and per-OTA booking options are not part of this version.

#### Can I call it from Python, JavaScript or an automation tool?

Yes. Every Apify Actor has a REST API and official Python and JavaScript clients. You can also connect it to Make, n8n, Zapier or the Apify MCP server for AI agents. Results land in the dataset and key-value store either way.

#### Is this an official Google API?

No. It reads publicly available Google Flights search results. It is **not affiliated with, endorsed by or sponsored by Google LLC**. "Google Flights" is a trademark of Google LLC, used here only to describe the data source.

#### Is scraping Google Flights legal?

That depends on your jurisdiction and your use. You are responsible for complying with Google's Terms of Service and applicable data-protection law. Use the data for legitimate research, market intelligence or your own travel planning, and do not overload Google's infrastructure.

#### Does it book tickets?

No. It only reads search results. Booking, payment, seat selection, hotels and car hire are out of scope.

#### Why is it slower than a pure-HTTP scraper?

It drives a real browser, which renders the same page a person sees. That is more robust to JavaScript-only content but slower than calling an internal API directly.

### Limitations

- **Browser-based** — slower and heavier than pure-HTTP scrapers.
- **Google UI changes** can break selectors; retries and diagnostics are built in, but a major redesign may require an update.
- **Prices are snapshots** — Google updates fares continuously.
- **Multi-city is per leg**, not a single through-ticket price.
- **No booking, seat selection, hotels or car hire.**
- **Result depth is limited** to what Google exposes for the route and date.
- **Flight numbers and per-layover details are not extracted** — `stops` is, so you can filter nonstop versus connecting flights.
- **Not every row has a price** — Google sometimes shows "price unavailable"; those rows are flagged.

### Support

Found a bug or need an extra field? Open an issue on the Actor's **Issues** tab in Apify Console and include:

- your input JSON (remove secrets),
- the run ID,
- what you expected versus what you got.

### Disclaimer

This Actor accesses publicly available flight search data for legitimate research, market-intelligence and business-analysis purposes. It is not affiliated with, endorsed by or sponsored by Google LLC. Use it in compliance with Google's Terms of Service and all applicable laws, including data-protection regulations. The publisher is not responsible for misuse. No warranty is provided; verify prices before making travel decisions.

### Keywords

Google Flights scraper, Google Flights API, flight price scraper, airfare scraper, flight data API, flight price tracker, fare monitoring, price drop alerts, Google Flights Excel export, multi-city flight scraper, round-trip flight scraper, one-way flight scraper, business class flight data, nonstop flight scraper, airline price comparison, travel data, Apify flight scraper, Google Flights dataset, flight itinerary data, cheapest flight finder.

# Actor input Schema

## `departure` (type: `string`):

Origin IATA code, e.g. BOM.

## `destination` (type: `string`):

Destination IATA code, e.g. DEL.

## `outbound_date` (type: `string`):

Departure date in YYYY-MM-DD format.

## `return_date` (type: `string`):

Return date (YYYY-MM-DD). Required only for round-trip searches.

## `depart_days_ahead` (type: `integer`):

Optional. Depart this many days after the run starts instead of a fixed outbound date. Ideal for schedules: the search keeps moving forward. Ignored for multi-city.

## `trip_length_days` (type: `integer`):

Optional. Return this many days after departure and switch to round-trip. Works with 'Depart in (days)' or a fixed outbound date. Ignored for multi-city.

## `legs` (type: `array`):

Optional. Use for multi-city trips instead of departure/destination/outbound_date. Requires trip_type='multi-city' and at least 2 legs.

## `trip_type` (type: `string`):

One-way, round-trip or multi-city.

## `cabin_class` (type: `string`):

Cabin class to search in.

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

Number of adult passengers (1-9).

## `children` (type: `integer`):

Number of child passengers (0-8).

## `infants` (type: `integer`):

Number of infant passengers (0-4).

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

3-letter currency code for prices, e.g. USD, INR, EUR.

## `stops` (type: `string`):

Maximum number of stops to allow.

## `max_results` (type: `integer`):

Maximum number of flights to return.

## `force_fresh` (type: `boolean`):

Ignore the short-lived result cache and scrape live. Prices change every few minutes.

## `airlines` (type: `array`):

Optional. Keep only flights whose airline matches one of these names (case-insensitive substring, e.g. 'IndiGo', 'Air India').

## `max_price` (type: `number`):

Optional. Keep only flights at or below this price (in the chosen currency). Google shows the total for all passengers, so set this generously or leave empty.

## `max_price_per_person` (type: `number`):

Optional. Keep only flights whose price divided by the number of passengers is at or below this value. Use this when Google shows a total for all passengers.

## `max_duration_minutes` (type: `integer`):

Optional. Keep only flights whose total duration is at or below this many minutes (e.g. 300 = 5 hours).

## `departure_time_from` (type: `string`):

Optional. Earliest departure time, e.g. '06:00' or '6:00 AM'.

## `departure_time_to` (type: `string`):

Optional. Latest departure time, e.g. '22:00' or '10:00 PM'.

## `sort_by` (type: `string`):

Order of the returned flights. 'Google ranking' keeps Google's own order.

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

Proxy used for browser traffic. Apify Proxy is used by default. Disable it to run directly from the Actor's IP.

## `usePlaywrightSource` (type: `boolean`):

When enabled (default), scrapes Google Flights live with a real browser. Disable to use the synthetic data source (useful for testing).

## `trackPriceHistory` (type: `boolean`):

Persist the minimum price per route across runs in the 'price-history' key-value store and compute price changes.

## `priceDropAlertPercent` (type: `number`):

Send a webhook alert when the minimum price drops by at least this percentage versus the previous run.

## `alertWebhookUrl` (type: `string`):

Optional. HTTP endpoint (Slack, Discord, Make, n8n, etc.) that receives JSON on price drops and run failures.

## `alertWebhookFormat` (type: `string`):

Payload shape for the alert webhook. Generic JSON works with Make/n8n/Zapier; pick Slack or Discord for incoming-webhook compatibility.

## `alertOnFailure` (type: `boolean`):

Send a webhook notification when the run fails. Requires an alert webhook URL.

## Actor input object example

```json
{
  "departure": "BOM",
  "destination": "DEL",
  "outbound_date": "2026-12-01",
  "trip_type": "one-way",
  "cabin_class": "economy",
  "adults": 1,
  "children": 0,
  "infants": 0,
  "currency": "USD",
  "stops": "any",
  "max_results": 50,
  "force_fresh": false,
  "sort_by": "google",
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "usePlaywrightSource": true,
  "trackPriceHistory": true,
  "priceDropAlertPercent": 10,
  "alertWebhookFormat": "json",
  "alertOnFailure": true
}
```

# Actor output Schema

## `flights` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `excel` (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 = {
    "departure": "BOM",
    "destination": "DEL",
    "outbound_date": "2026-12-01"
};

// Run the Actor and wait for it to finish
const run = await client.actor("arceus15/google-flights-api").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 = {
    "departure": "BOM",
    "destination": "DEL",
    "outbound_date": "2026-12-01",
}

# Run the Actor and wait for it to finish
run = client.actor("arceus15/google-flights-api").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 '{
  "departure": "BOM",
  "destination": "DEL",
  "outbound_date": "2026-12-01"
}' |
apify call arceus15/google-flights-api --silent --output-dataset

```

## MCP server setup

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

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/5R4NSePZNT57MAgRN/builds/0DVQfay3kBSMyU6FY/openapi.json
