# Flight Finder - Google Flights and Flexible Dates (`leadproof/flight-finder`) Actor

Find Google Flights fares across airports and flexible dates. Compare complete one-way and round-trip itineraries by price, duration and stops for your passenger group. $0.02 per successful route/date search plus usage. Baggage and checkout prices are not verified.

- **URL**: https://apify.com/leadproof/flight-finder.md
- **Developed by:** [Lead Proof](https://apify.com/leadproof) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 successful flight searches

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## Flight Finder - Google Flights and Flexible Dates

Find and compare Google Flights itineraries across departure airports, destinations and flexible travel dates. Rank complete one-way or round-trip options by **cheapest quoted fare**, **fastest journey** or **best value**. Prices are for your whole passenger group.

### Quick start

1. Enter airport IATA codes, such as LHR and FCO.
2. Select your passenger group and one-way or round-trip travel.
3. Enter dates, or leave dates empty to try the rolling example: departure 30 days from today, returning seven nights later.
4. Set your maximum charge in Apify Run options. Allow **$0.02 per planned route/date combination**, plus platform usage.
5. Start the Actor. Open the Flight comparison table and read SUMMARY for coverage and limitations.

No API key, airline login or external Actor subscription is required. Collection runs inside Flight Finder with limited permissions.

### Pricing

**$0.02 per successful flight search, plus Apify platform usage.** No subscription, startup event or per-itinerary fee.

One search means one origin/destination and one departure/return date combination, for the entire passenger group. A round trip is one search, not two. A search is charged only when collection and validation finish without errors and at least one itinerary matches your filters.

| Example | Search fee |
| --- | --- |
| One route with fixed dates | $0.02 |
| One route across 10 date pairs | $0.20 |
| Three routes across 10 date pairs | $0.60 |
| Partial, failed, empty or fully filtered search | $0 search fee |

Platform usage can still apply to unsuccessful searches. The Actor checks that the run's maximum charge covers all planned search events before collection; insufficient budgets are rejected. Results are saved before charging. BILLING records eligible and charged searches. Search fees are independent of how many top-ranked rows you choose to export.

### Example input

This example always uses future dates and performs one round-trip search:

```json
{
  "origins": ["LHR"],
  "destinations": ["FCO"],
  "tripType": "round_trip",
  "minNights": 7,
  "adults": 1,
  "maxStops": 0,
  "ranking": "best_value",
  "maxResults": 10,
  "maxSearches": 1,
  "maxSourceChargeUsd": 0.1
}
```

For fixed dates, add `departureDate` and `returnDate` as YYYY-MM-DD and remove `minNights`. For flexible dates, use `departureDate`, `departureDateEnd`, `minNights` and `maxNights` instead of a fixed return date. For example, three departure dates and three stay lengths require nine searches and up to $0.18 in search fees.

The advanced `maxSourceChargeUsd` and `sourceChargePerSearchUsd` fields are inherited planning allowances. With the included collector they generate **no extra source charge**. They are not the Apify run maximum charge or a replacement for it. Default values allow ten searches; increase the total allowance when planning more.

### Search controls

- Up to 10 origins and 10 destinations, using actual airport codes. City codes, nearby-airport expansion and worldwide destination discovery are not supported.
- Departure window up to 31 days; stays from 1 to 28 nights; travel within the next 365 days.
- Up to 30 route/date searches per run, 50 collected offers per search, and 100 ranked output itineraries.
- Adult, child, lap-infant and seated-infant counts, up to nine passengers total. Exact child ages are not supported.
- Economy, premium economy, business or first class; requested quote currency and market.
- Maximum stops, duration per direction and quoted group fare, checked again after collection.
- `searchMode=complete` rejects an oversized matrix. `sample` searches a deterministic spread and reports skipped combinations.

### Ranking

`cheapest` sorts by quoted group fare. `fastest` sorts by total travel time, including connections but excluding the stay at the destination.

`best_value` uses this transparent preference score:

`quotedFare + totalTravelHours * valuePerHour + totalStops * stopPenalty`

The score uses the quote currency and is not an extra payable fee. Defaults are 15 currency units per travel hour and 30 per stop. Every retained itinerary also has cheapest, fastest and best-value ranks.

### Output

The Dataset contains one row per retained itinerary. Export JSON for complete segments or use the CSV summary view for flat columns.

| Fields | Meaning |
| --- | --- |
| `origin`, `destination`, `departureDate`, `returnDate` | Route and dates |
| `quotedFare`, `currency`, `passengers` | Quote for the whole requested party |
| `legs`, `outboundFlightNumbers`, `returnFlightNumbers` | Complete journey and segments, with UTC offsets |
| `totalDurationMinutes`, `totalStops` | Travel time and connections |
| `cheapestRank`, `fastestRank`, `bestValueRank` | Relative ranks across collected options |
| `bookingUrl`, `bookingUrlType` | Google Flights itinerary navigation, not a verified seller offer |
| `priceComplete`, `baggageStatus`, `warnings` | Unknown costs and restrictions |
| `sourceRunId`, `sourceBuildId`, timestamps | Run and build provenance |

Key-value records:

- **SUMMARY**: search coverage, best offers, filters, errors, collection limits and billing summary.
- **BILLING**: eligible searches, confirmed event charges and any pending charge state.
- **EXECUTION**: prevents duplicate work or charges on restart. Start a new run instead of rebooting or resurrecting one.

### Coverage and price limitations

This Actor ranks the options it collects; it does **not** guarantee the cheapest fare available anywhere. It uses public Google Flights results and expands up to five outbound choices and their return alternatives for each round-trip search. It does not cover every airline, date combination or fare family. Complete date coverage is not exhaustive itinerary coverage.

Fares can change. `quotedFare` is a search quote, not a guaranteed final checkout total. Group fares come from the source and are never calculated by multiplying a one-adult fare. Seller fees, baggage and payment charges may be missing. `priceComplete` and `sellerCheckoutVerified` remain false.

Verified baggage allowances are unavailable. Requesting bags with `baggageMode=strict` excludes unknown offers; `show_unknown` keeps them with warnings. Seller offers, baggage retrieval and final checkout verification are unsupported. Leave `includeBookingDetails` false.

Google Flights links are navigation links and may expire or show different availability, currency or market. No tickets are held, purchased or booked. Airport-changing connections are excluded; connection protection, minimum connection times, transit requirements, refunds and changes are not verified.

SUMMARY distinguishes complete, partial, no\_matching\_results, empty\_unverified and failed searches. Unverified empty source responses are not proof that no flights exist. Partial runs preserve useful results and describe missing coverage.

### Operation and support

The included collector runs in this Actor without a private child Actor, external scraper fee or personal account token. Paid runs use the included collector only; leave `sourceActor` at its default. Runtime is bounded by the search matrix, six page requests per search and the configured deadline.

The implementation is deployed through GitHub CI. Automated checks cover date planning, group fares, complete round trips, timezone handling, filters, rankings, cancellation and billing. Live smoke tests cover multiple routes, currencies and passenger mixes; they are not a guarantee of uninterrupted upstream availability.

Use the Issues tab with your run ID and expected behavior when reporting a problem. Do not include API tokens or passenger personal information.

# Actor input Schema

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

1-10 actual airport IATA codes. City codes and nearby-airport expansion are not supported.

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

1-10 actual airport IATA codes. Each route is searched independently.

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

One-way or a complete outbound and return itinerary.

## `departureDate` (type: `string`):

YYYY-MM-DD. Omit for 30 days from today (UTC). Dates must be within 365 days.

## `departureDateEnd` (type: `string`):

Optional inclusive end of a 1-31 day departure window. Omit for a fixed date.

## `returnDate` (type: `string`):

Optional YYYY-MM-DD. Must follow the entire departure window. Do not combine with nights.

## `minNights` (type: `integer`):

For round trips without a fixed return date. Omit for 7 nights. Do not send for one-way.

## `maxNights` (type: `integer`):

For round trips only. Omit to use minimum nights. Maximum 28.

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

Passengers aged 12 and older. At most 9 passengers in total.

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

Children aged 2-11, passed as a count to the source. Exact-age fares are not supported. At most 9 passengers in total.

## `infantsOnLap` (type: `integer`):

Infants under 2 without their own seat. At most one per adult. At most 9 passengers in total.

## `infantsInSeat` (type: `integer`):

Infants under 2 with their own seat. At most 9 passengers in total.

## `cabinClass` (type: `string`):

Requested cabin passed to the source and checked on returned rows.

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

Uppercase ISO currency, e.g. USD, EUR or ILS. Seller checkout may use another currency.

## `market` (type: `string`):

Two-letter country code, e.g. US, GB or IL. Seller checkout market may differ.

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

Hard filter, checked again on complete returned legs.

## `maxDurationMinutes` (type: `integer`):

Includes layovers. Applied to each direction separately.

## `checkedBagsPerPassenger` (type: `integer`):

Verified per-fare allowance is currently unavailable. With strict baggage mode, requesting bags excludes unknown offers.

## `carryOnBagsPerPassenger` (type: `integer`):

Verified per-fare allowance is currently unavailable. A policy URL is not proof of inclusion.

## `maxResults` (type: `integer`):

Distinct itineraries in output. Other seller quotes are nested under alternativeOffers.

## `resultsPerSearch` (type: `integer`):

Caps source collection. Source may return duplicates or fewer flights.

## `maxSearches` (type: `integer`):

Each date and stay-length combination consumes a search slot.

## `concurrency` (type: `integer`):

Parallel route/date searches. The default collector runs inside this Actor.

## `timeoutSeconds` (type: `integer`):

Stops launching searches and aborts known active source runs at the deadline.

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

Optional maximum in the quote currency. Unknown baggage and payment fees are not included.

## `baggageMode` (type: `string`):

Strict excludes offers with unknown requested baggage. Show unknown keeps them with explicit warnings.

## `ranking` (type: `string`):

Cheapest compares quoted group fares. Best value adds your time and stop penalties, not payable charges.

## `valuePerHour` (type: `number`):

Preference weight in quote-currency units per travel hour. Used only for best-value scoring.

## `stopPenalty` (type: `number`):

Preference weight in quote-currency units. Used only for best-value scoring.

## `searchMode` (type: `string`):

Complete rejects an input that exceeds the search/cost allowance. Sample checks a deterministic spread and reports incomplete coverage.

## `maxSourceChargeUsd` (type: `number`):

Sum of reserved source-run charge limits. Parent compute/storage and unreported platform costs are separate.

## `sourceChargePerSearchUsd` (type: `number`):

Passed to each source run as maxTotalChargeUsd. Allowance is never reused after failures.

## `includeBookingDetails` (type: `boolean`):

Optional legacy source feature. Our default collector does not retrieve seller offers or baggage. Checkout prices are never verified.

## `sourceActor` (type: `string`):

Default selects our bundled direct collector, with no child Actor or extra source fee. Alternative owner/name is for private/free development only.

## Actor input object example

```json
{
  "origins": [
    "LHR"
  ],
  "destinations": [
    "FCO"
  ],
  "tripType": "round_trip",
  "adults": 1,
  "children": 0,
  "infantsOnLap": 0,
  "infantsInSeat": 0,
  "cabinClass": "economy",
  "currency": "USD",
  "market": "US",
  "maxStops": 1,
  "maxDurationMinutes": 1440,
  "checkedBagsPerPassenger": 0,
  "carryOnBagsPerPassenger": 0,
  "maxResults": 20,
  "resultsPerSearch": 30,
  "maxSearches": 12,
  "concurrency": 2,
  "timeoutSeconds": 240,
  "baggageMode": "strict",
  "ranking": "best_value",
  "valuePerHour": 15,
  "stopPenalty": 30,
  "searchMode": "complete",
  "maxSourceChargeUsd": 1,
  "sourceChargePerSearchUsd": 0.1,
  "includeBookingDetails": false,
  "sourceActor": "leadproof/google-flights-collector"
}
```

# Actor output Schema

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

Complete itinerary details and alternative seller quotes.

## `csv` (type: `string`):

Flat itinerary and quote columns.

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

Coverage, errors, source charges and best offers.

## `sourceRuns` (type: `string`):

Started dependency runs and reserved charge allowance.

# 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 = {
    "origins": [
        "LHR"
    ],
    "destinations": [
        "FCO"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("leadproof/flight-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 = {
    "origins": ["LHR"],
    "destinations": ["FCO"],
}

# Run the Actor and wait for it to finish
run = client.actor("leadproof/flight-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 '{
  "origins": [
    "LHR"
  ],
  "destinations": [
    "FCO"
  ]
}' |
apify call leadproof/flight-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,leadproof/flight-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/ZSAPUWPiJqOUZlO7H/builds/17aMWnviGG5oCsPVD/openapi.json
