# Google Flights Scraper (`schnellscrapers/google-flights-price-monitor`) Actor

Extract Google Flights search URLs into one fare row per itinerary with price, airline, route, times, duration, stops, and CO₂ emissions. Filter by maximum price, stop count, or airline before writing results. Schedule recurring route checks with no login or API key required.

- **URL**: https://apify.com/schnellscrapers/google-flights-price-monitor.md
- **Developed by:** [Nate Schnell](https://apify.com/schnellscrapers) (community)
- **Categories:** Travel, Automation, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.35 / 1,000 itineraries

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### What does Google Flights Scraper do?

Google Flights Scraper turns saved Google Flights search-result URLs into clean fare rows for travel teams, route analysts, affiliate workflows, and scheduled price checks. Each itinerary is written as one record with its price, airline, airports, dates, times, duration, stops, and carbon estimate, so repeated runs can be compared in an Apify dataset.

### What data can you extract from Google Flights?

- Fare — displayed price and currency from the saved search URL
- Route — departure airport, arrival airport, outbound date, return date, and trip type
- Schedule — local departure time, arrival time, total duration in minutes, and stop count
- Carrier — airline display name and IATA airline code when the page exposes it
- Environmental signal — Google's carbon-emissions estimate and intermediate stop airports
- Provenance — the source search URL, stable itinerary ID, and scrape timestamp

The actor reads the result page you created in Google Flights, so the saved URL retains the route, travel dates, cabin, passenger count, market, and language choices that matter to your workflow.

### How to use Google Flights Scraper

1. Open Google Flights and create the exact route and dates you want to monitor.
2. Copy the browser URL after Google shows the search results.
3. Open this actor, paste one or more URLs into Google Flights search URLs, and choose a result cap or filters.
4. Click Run. The actor fetches each saved page and writes matching itinerary rows.
5. Download JSON, CSV, or Excel from the dataset, or connect the dataset API to your monitoring workflow.

### How much does it cost?

The actor uses pay-per-itinerary pricing: a matching itinerary written to the dataset is one billable result. Use the default maximum of 100 rows to validate a URL on the free tier or with your available Apify credits. Filters run before dataset writes, so a maximum fare, stop-count limit, or airline filter can reduce billed results. The initial price is `$0.35 per 1,000 itineraries`, based on a deployed direct-mode smoke cost of about `$0.105 per 1,000`.

### Input

`searchUrls` is required. Add one or more saved Google Flights search-result URLs. `maxItems` caps rows across all URLs; `maxPrice`, `maxStops`, and `airlines` narrow the result set before billing. Set `dryRun` to true to validate a new URL without writing dataset rows.

```json
{
  "searchUrls": [
    {
      "url": "https://www.google.com/travel/flights/search?tfs=CBwQAhooEgoyMDI2LTEwLTMwagwIAhIIL20vMF9scjFyDAgCEggvbS8wNWpibhooEgoyMDI2LTExLTA1agwIAhIIL20vMDVqYm5yDAgCEggvbS8wX2xyMUABSAFwAYIBCwj___________8BmAEB&tfu=CsABQ2pSSWQzQnFVRkpCUzFCeGMxRkJSV3h0U2xGQ1J5MHRMUzB0TFMwdExYbHBZbXRrTWtGQlFVRkJSM0F5UlVWelJsVXhlVU5CRWtOamFHVmhjR1Z6ZEZKdmRXNWtWSEpwY0MwdmJTOHdYMnh5TVMwdmJTOHdOV3BpYmkxSFUxQXRRazVCTFRBdE1qQXlOaTB4TUMwek1DMHlNREkyTFRFeExUQTFHZ3NJK01NQkVBSWFBMVZUUkRndmNQakRBUT09EgYIABAAGAA&hl=en&gl=us&curr=USD"
    }
  ],
  "maxStops": 1,
  "airlines": ["WN", "Southwest"],
  "maxItems": 20
}
```

### Output

Each output object is one fare option. Prices are numeric, dates use `YYYY-MM-DD`, and optional source values are `null` when Google does not expose them.

```json
{
  "id": "3326e161-ck1j5c",
  "price": 251,
  "currency": "USD",
  "airline": "Southwest",
  "airlineCode": "WN",
  "departureAirport": "GSP",
  "arrivalAirport": "BNA",
  "departureDate": "2026-10-30",
  "returnDate": "2026-11-05",
  "departureTime": "6:25 AM",
  "arrivalTime": "6:40 AM",
  "durationMinutes": 75,
  "stops": 0,
  "stopAirports": [],
  "carbonEmissionsKg": 78,
  "tripType": "round trip",
  "sourceUrl": "https://www.google.com/travel/flights/search?tfs=CBwQAhooEgoyMDI2LTEwLTMwagwIAhIIL20vMF9scjFyDAgCEggvbS8wNWpibhooEgoyMDI2LTExLTA1agwIAhIIL20vMDVqYm5yDAgCEggvbS8wX2xyMUABSAFwAYIBCwj___________8BmAEB&tfu=CsABQ2pSSVFUbFhRMTlzTldGc1lUQkJSSG95TFhkQ1J5MHRMUzB0TFMwdGVXeHZOaTF1TWtGQlFVRkJSM0F5UlMxRlRFWm5jMUZCRWtOamFHVmhjR1Z6ZEZKdmRXNWtWSEpwY0MwdmJTOHdYMnh5TVMwdmJTOHdOV3BpYmkxSFUxQXRRazVCTFRBdE1qQXlOaTB4TUMwek1DMHlNREkyTFRFeExUQTFHZ3NJK01NQkVBSWFBMVZUUkRndmNQakRBUT09EgYIABAAGAA&hl=en&gl=us&curr=USD",
  "scrapedAt": "2026-08-07T16:00:00.000Z"
}
```

### Integrations

Use Apify schedules to run the same saved URLs daily or hourly, webhooks to notify a fare-drop service, and the [Apify API](https://docs.apify.com/api/v2) from Python or Node.js to read the default dataset. The resulting JSON and CSV rows also fit Make, n8n, Zapier, and spreadsheet workflows.

### Related actors

- [Tripadvisor Reviews Scraper](https://apify.com/schnellscrapers/tripadvisor-review-monitor) — monitor another travel-data source when fare changes are only part of a destination workflow.
- [Full Website Downloader](https://apify.com/schnellscrapers/full-website-downloader) — archive a public page when a scheduled snapshot needs the source document as well as normalized rows.

### FAQ

#### How does Google Flights Scraper work?

It fetches the public search-result page behind each saved Google Flights URL and reads the itinerary rows that Google renders there. No separate account, API key, or browser session is required for the saved URL.

#### Can I use Google Flights Scraper as an API?

Yes. Start the actor through the [Apify API](https://docs.apify.com/api/v2/actor-runs), pass `searchUrls` in the input JSON, and read the default dataset from the run response or dataset API.

#### Can I use Google Flights Scraper in Python or Node.js?

Yes. Use the official `apify-client` package to start a run and download its dataset items.

```js
const run = await client.actor("schnellscrapers/google-flights-price-monitor").call({ searchUrls });
const rows = await client.dataset(run.defaultDatasetId).listItems();
```

#### Is it legal to scrape Google Flights?

This actor accesses the public search-result pages you provide. You are responsible for deciding how your use of the returned fare data fits your project, agreements, and applicable rules.

#### Why does the actor ask for a saved search URL?

The URL preserves the route, dates, cabin, passenger count, currency, country, and language settings you selected. It also lets a schedule repeat the same fare check without rebuilding the search each run.

#### Why did a URL return no rows?

Google can return an empty result page, change the page shape, or vary availability by request location. Check the URL in a browser, run once with `dryRun`, and review the actor log. Invalid URLs and failed pages are skipped without discarding results from other inputs.

### Your feedback

Please report a source-layout change or request a filter through the Issues tab on the actor page. Examples with the saved URL shape and the affected fields make fixes much faster.

# Actor input Schema

## `searchUrls` (type: `array`):

Paste saved URLs from Google Flights search-result pages. Create a route, date, cabin, or passenger search in Google Flights, copy the `/travel/flights/search?...` URL, and add it here.

## `maxItems` (type: `integer`):

Hard cap on itinerary rows written across all URLs. Start with `20` for a small fare check; the default cap is 100.

## `maxPrice` (type: `number`):

Keep fares at or below this amount in the currency shown by each saved URL. Leave at `0` for no price filter.

## `maxStops` (type: `integer`):

Keep nonstop or connecting itineraries up to this stop count. Use `0` for nonstop only, or `-1` for no stop filter.

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

Keep only matching airline names or IATA codes, such as `Southwest`, `Delta`, `WN`, or `DL`. Leave empty for all airlines.

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

Direct HTTP is the default and is the lowest-cost path. If Google returns an empty result shell, enable Apify Proxy with the RESIDENTIAL group; proxy transfer can affect run cost.

## `dryRun` (type: `boolean`):

Fetch and filter flight rows without writing dataset records. Logs show matched versus written counts; use this to validate a new saved URL.

## Actor input object example

```json
{
  "searchUrls": [
    {
      "url": "https://www.google.com/travel/flights/search?tfs=CBwQAhooEgoyMDI2LTEwLTMwagwIAhIIL20vMF9scjFyDAgCEggvbS8wNWpibhooEgoyMDI2LTExLTA1agwIAhIIL20vMDVqYm5yDAgCEggvbS8wX2xyMUABSAFwAYIBCwj___________8BmAEB&tfu=CsABQ2pSSWQzQnFVRkpCUzFCeGMxRkJSV3h0U2xGQ1J5MHRMUzB0TFMwdExYbHBZbXRrTWtGQlFVRkJSM0F5UlVWelJsVXhlVU5CRWtOamFHVmhjR1Z6ZEZKdmRXNWtWSEpwY0MwdmJTOHdYMnh5TVMwdmJTOHdOV3BpYmkxSFUxQXRRazVCTFRBdE1qQXlOaTB4TUMwek1DMHlNREkyTFRFeExUQTFHZ3NJK01NQkVBSWFBMVZUUkRndmNQakRBUT09EgYIABAAGAA&hl=en&gl=us&curr=USD"
    }
  ],
  "maxItems": 100,
  "maxPrice": 0,
  "maxStops": -1,
  "airlines": [],
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "dryRun": false
}
```

# Actor output Schema

## `records` (type: `string`):

Normalized Google Flights itinerary rows ready for fare monitoring and route comparison.

# 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 = {
    "searchUrls": [
        {
            "url": "https://www.google.com/travel/flights/search?tfs=CBwQAhooEgoyMDI2LTEwLTMwagwIAhIIL20vMF9scjFyDAgCEggvbS8wNWpibhooEgoyMDI2LTExLTA1agwIAhIIL20vMDVqYm5yDAgCEggvbS8wX2xyMUABSAFwAYIBCwj___________8BmAEB&tfu=CsABQ2pSSWQzQnFVRkpCUzFCeGMxRkJSV3h0U2xGQ1J5MHRMUzB0TFMwdExYbHBZbXRrTWtGQlFVRkJSM0F5UlVWelJsVXhlVU5CRWtOamFHVmhjR1Z6ZEZKdmRXNWtWSEpwY0MwdmJTOHdYMnh5TVMwdmJTOHdOV3BpYmkxSFUxQXRRazVCTFRBdE1qQXlOaTB4TUMwek1DMHlNREkyTFRFeExUQTFHZ3NJK01NQkVBSWFBMVZUUkRndmNQakRBUT09EgYIABAAGAA&hl=en&gl=us&curr=USD"
        }
    ],
    "airlines": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("schnellscrapers/google-flights-price-monitor").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 = {
    "searchUrls": [{ "url": "https://www.google.com/travel/flights/search?tfs=CBwQAhooEgoyMDI2LTEwLTMwagwIAhIIL20vMF9scjFyDAgCEggvbS8wNWpibhooEgoyMDI2LTExLTA1agwIAhIIL20vMDVqYm5yDAgCEggvbS8wX2xyMUABSAFwAYIBCwj___________8BmAEB&tfu=CsABQ2pSSWQzQnFVRkpCUzFCeGMxRkJSV3h0U2xGQ1J5MHRMUzB0TFMwdExYbHBZbXRrTWtGQlFVRkJSM0F5UlVWelJsVXhlVU5CRWtOamFHVmhjR1Z6ZEZKdmRXNWtWSEpwY0MwdmJTOHdYMnh5TVMwdmJTOHdOV3BpYmkxSFUxQXRRazVCTFRBdE1qQXlOaTB4TUMwek1DMHlNREkyTFRFeExUQTFHZ3NJK01NQkVBSWFBMVZUUkRndmNQakRBUT09EgYIABAAGAA&hl=en&gl=us&curr=USD" }],
    "airlines": [],
}

# Run the Actor and wait for it to finish
run = client.actor("schnellscrapers/google-flights-price-monitor").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 '{
  "searchUrls": [
    {
      "url": "https://www.google.com/travel/flights/search?tfs=CBwQAhooEgoyMDI2LTEwLTMwagwIAhIIL20vMF9scjFyDAgCEggvbS8wNWpibhooEgoyMDI2LTExLTA1agwIAhIIL20vMDVqYm5yDAgCEggvbS8wX2xyMUABSAFwAYIBCwj___________8BmAEB&tfu=CsABQ2pSSWQzQnFVRkpCUzFCeGMxRkJSV3h0U2xGQ1J5MHRMUzB0TFMwdExYbHBZbXRrTWtGQlFVRkJSM0F5UlVWelJsVXhlVU5CRWtOamFHVmhjR1Z6ZEZKdmRXNWtWSEpwY0MwdmJTOHdYMnh5TVMwdmJTOHdOV3BpYmkxSFUxQXRRazVCTFRBdE1qQXlOaTB4TUMwek1DMHlNREkyTFRFeExUQTFHZ3NJK01NQkVBSWFBMVZUUkRndmNQakRBUT09EgYIABAAGAA&hl=en&gl=us&curr=USD"
    }
  ],
  "airlines": []
}' |
apify call schnellscrapers/google-flights-price-monitor --silent --output-dataset

```

## MCP server setup

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

```

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/Nlud5clYx5YY2txKp/builds/Vnq79iZQCnc52YCVu/openapi.json
