# Flight Deals Feed: Secret Flying, Fly4free & The Flight Deal (`automatic/flight-deals-feed`) Actor

Cheap flight deals and error fares from Secret Flying, Fly4free and The Flight Deal in one feed, deduplicated: origin, destination, IATA codes, price, currency, airline, travel dates, posted date and deal link. Filter by origin, destination and age for fare alerts.

- **URL**: https://apify.com/automatic/flight-deals-feed.md
- **Developed by:** [Philip Kirkbride](https://apify.com/automatic) (community)
- **Categories:** Travel, Automation
- **Security:** Limited permissions
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 deals

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

## Flight Deals Feed: Secret Flying, Fly4free, The Flight Deal

Get the cheap flight deals and error fares that Secret Flying, Fly4free and The Flight Deal publish, in one clean, deduplicated feed. Each row identifies the deal and its source link, with route, price, currency, airline, trip type and publication date when available. With deal details on (the default), rows can also include the stated travel period as dates, example travel dates, routing and stopovers.

Secret Flying covers departures worldwide, Fly4free departures from Europe and The Flight Deal departures from the United States. Filter by where you fly from, where you want to go and how fresh the deal is.

Use it for fare alerts: schedule a daily run with your home airports as the origin filter and send new rows to email, Slack or a spreadsheet.

### Quick Start

The newest deals from all three sites:

```json
{"maxResults": 20}
```

Deals from London to anywhere in Asia posted this week:

```json
{"origins": ["London", "LHR"], "destinations": ["Japan", "Thailand", "Vietnam", "Singapore"], "maxAgeDays": 7}
```

Error fares from the last month, without added travel details:

```json
{"errorFaresOnly": true, "maxAgeDays": 30, "includeDetails": false}
```

### Input

| Field | Type | Default | What it does |
|---|---|---:|---|
| `sources` | array | all three | `secretFlying`, `fly4free`, `theFlightDeal`. |
| `origins` | array | `[]` | Only deals departing from one of these places: a city (`London`), a country (`UK`, `United States`) or an IATA code (`LHR`, `LON`, `JFK`). An airport code also matches its city, so `LHR` matches deals from London. |
| `destinations` | array | `[]` | Only deals to one of these places, as for `origins`. |
| `dealTypes` | array | `["flight"]` | `flight`, `package` (flight + hotel), `hotel`, `cruise`. Only Fly4free publishes the last three. Travel news is never returned. |
| `errorFaresOnly` | boolean | `false` | Only deals flagged as error (mistake) fares. |
| `maxAgeDays` | integer | `7` | Only deals posted in the last N days, 1 to 365. |
| `maxResults` | integer | `20` | Maximum deals returned, newest first, across all sites. Up to 2,000, or 500 with `includeDetails` on. |
| `includeDetails` | boolean | `true` | Add the published travel period, example dates, airline, routing, stopovers and exact airport codes when available. |
| `proxyConfiguration` | object | off | Not needed; leave it off unless a site stops answering. |

A place filter matches a row when the term names its city, its country (common short names such as `UK`, `USA` and US states work) or its IATA code, or appears as whole words in the place as printed (`Hanoi` matches "Hanoi or Ho Chi Minh City, Vietnam"). Rows whose origin the site does not name (for example "many European cities") are left out when an origin filter is set.

### What it returns

One row per deal:

- `dealKey` (unique: site and deal page), `source` (`secretFlying`, `fly4free` or `theFlightDeal`), `sourceName`, `dealType`, `title` and `url` (the deal page).
- `postedAt` (ISO 8601 UTC) and `postedDate` (`YYYY-MM-DD`). Secret Flying may provide only the date unless details are enabled.
- `origin` and `destination` as printed, plus `originCity`, `originCountry`, `originIata`, `destinationCity`, `destinationCountry`, `destinationIata`. Codes are airport codes when the deal page gives them (`SFO`, `JFK`), otherwise the city's code (`LON`, `NYC`, `TYO` cover all of that city's airports). A deal to several cities, or to a whole country, has no single code.
- `price` (a number: the lowest headline fare in the first listed fare's currency; different currencies are not compared or converted) and `currency` (ISO code: `EUR`, `GBP`, `USD`, `CAD`, `AUD` ...).
- `tripType` (`roundtrip` or `oneWay`), `isErrorFare`, `isNonstop`, `cabinClass` (`business`, `first`, `premiumEconomy` or empty), `airline` and `tags` (banner words such as `LAST MINUTE` or `XMAS`).
- With details on: `travelWindow` (the travel period as stated), `travelDateFrom` and `travelDateTo` (its first and last day, by whole months), `sampleDepartDate` and `sampleReturnDate` (example dates, when the site gives them), `routing` and `stopovers`. `detailsParsed` says whether the deal page gave any of these; `detailsError` says why a deal page could not be read, or that it was not read because the run reached its time limit (the row is still delivered).
- `summary` (the site's short description, when it has one), `alsoPostedOn` (the same deal on another site: route, currency and price, posted within three days, and no conflicting trip type or cabin; that copy is not returned again), `sourceQuery` (your filters) and `scrapedAt`.

Values a deal does not state are empty (`null`). Prices are what the site published when it posted the deal. Posted fares are not guaranteed to be bookable: they sell out or change, often within hours, so check the deal page and the airline before you book.

### Output example

```json
{"dealKey":"theFlightDeal:2026/10/26/cathay-pacific-san-francisco-phu-quoc-vietnam-857-roundtrip-including-all-taxes","source":"theFlightDeal","sourceName":"The Flight Deal","dealType":"flight","title":"Cathay Pacific: San Francisco – Phú Quốc, Vietnam. $857. Roundtrip, including all Taxes","url":"https://www.theflightdeal.com/2026/10/26/cathay-pacific-san-francisco-phu-quoc-vietnam-857-roundtrip-including-all-taxes/","postedAt":"2026-10-26T18:53:00Z","postedDate":"2026-10-26","origin":"San Francisco","originCity":"San Francisco","originCountry":"United States","originIata":"SFO","destination":"Phú Quốc, Vietnam","destinationCity":"Phú Quốc","destinationCountry":"Vietnam","destinationIata":"PQC","price":857.0,"currency":"USD","tripType":"roundtrip","isErrorFare":false,"isNonstop":null,"cabinClass":null,"airline":"Cathay Pacific","tags":[],"travelWindow":"Valid for travel from late January 2027 – February 2027 or late August 2027 – September 2027 for Monday through Thursday departures and returns.","travelDateFrom":"2027-01-01","travelDateTo":"2027-09-30","sampleDepartDate":"2027-01-20","sampleReturnDate":"2027-01-27","routing":"SFO – HKG (Hong Kong) – PQC (Phú Quốc) – HKG – SFO","stopovers":null,"summary":"A good sale to Phú Quốc Phú Quốc is a special administrative region of Vietnam and allows all visitors to visit without","alsoPostedOn":[],"sourceQuery":"sources=secretFlying,fly4free,theFlightDeal maxAgeDays=7","detailsParsed":true,"detailsError":null,"scrapedAt":"2026-10-27T15:12:32.780335+00:00"}
```

### Limits and caveats

- Sources: Secret Flying, Fly4free and The Flight Deal. Results reflect their public deal listings within your age and result limits. A default run (20 deals with details) usually takes about a minute; narrow filters and longer date windows can take longer.
- Older Secret Flying deals may be unavailable, so a long age window does not guarantee complete historical coverage.
- Deal details come only from what each public deal page prints. Secret Flying keeps some facts (such as the operating airline and the bookable months) for its members; those are not returned. Travel periods are as stated by the site, by whole months, and some pages state none.
- A run that reaches its time limit keeps the deals found so far and reports partial coverage in its status. Some delivered deals may have no added details; check `detailsError`.
- Results reflect the published headlines. Multi-city or country-wide deals keep the place text but have no city or code, and some headlines name no price.
- Fly4free also posts hotels, packages, cruises and travel news. Only flights are returned unless you choose other deal types; news is never returned.

### FAQ

**How fresh is the data?** Every run collects the latest publicly available deals within your filters. `postedAt` and `postedDate` identify when the publisher posted the deal.

**How do I get only new deals each day?** Schedule a daily run with `maxAgeDays: 2` and your filters, and keep the `dealKey` values you have already seen.

**Are the same deals posted on several sites?** Sometimes. A deal with the same route, currency and exact decimal price on two sites within three days is returned once, with the other link in `alsoPostedOn`. A one-way and a roundtrip fare, or two cabin classes, at the same price stay separate rows.

**What happens when nothing matches?** A completed search with no matches succeeds with an empty dataset. If a source is unavailable, other sources can still contribute deals and the status identifies the unavailable source. An unavailable source is reported as an error, rather than as "no deals".

### Price

You pay $0.005 per run start plus $0.001 per delivered deal ($1 per 1,000 deals). Each delivered row is one deduplicated deal: a copy folded into `alsoPostedOn` is not charged again. Deal details are included in that price. The run-start event is charged per GB of memory; the default 512 MB run is one start event. The start is charged even if the run saves no results. Platform usage is included in the price.

### Support

For questions or issues, contact us from the Actor page.

# Actor input Schema

## `sources` (type: `array`):

Sites to read. Secret Flying covers departures worldwide, Fly4free departures from Europe, The Flight Deal departures from the US. Empty = all three.

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

Only deals departing from one of these places: a city ('London'), a country ('United Kingdom', 'UK', 'USA') or an IATA code ('LHR', 'LON', 'JFK'). An airport code also matches its city, so 'LHR' matches deals from London. Empty = any origin.

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

Only deals to one of these places: a city, a country or an IATA code, as for the origin filter. Empty = any destination.

## `dealTypes` (type: `array`):

Flight deals only by default. Fly4free also publishes flight + hotel packages, hotel deals and cruises. Travel news posts are never returned.

## `errorFaresOnly` (type: `boolean`):

Only deals the site flags as error (mistake) fares. These are rare: a week often has none.

## `maxAgeDays` (type: `integer`):

Only deals published in the last N days (1 to 365).

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

Maximum number of deals returned, newest first, across all sites. Up to 2,000, or 500 with deal details on.

## `includeDetails` (type: `boolean`):

Open each deal page for the travel period, example dates, airline, routing, stopovers and exact airport codes. Adds about 1 to 3 seconds per deal.

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

Not needed: the deal sites answer without a proxy. Turn it on only if a site stops answering from the Apify platform.

## Actor input object example

```json
{
  "sources": [
    "secretFlying",
    "fly4free",
    "theFlightDeal"
  ],
  "origins": [],
  "destinations": [],
  "dealTypes": [
    "flight"
  ],
  "errorFaresOnly": false,
  "maxAgeDays": 7,
  "maxResults": 20,
  "includeDetails": true,
  "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 = {
    "sources": [
        "secretFlying",
        "fly4free",
        "theFlightDeal"
    ],
    "origins": [],
    "destinations": [],
    "dealTypes": [
        "flight"
    ],
    "maxAgeDays": 7,
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("automatic/flight-deals-feed").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 = {
    "sources": [
        "secretFlying",
        "fly4free",
        "theFlightDeal",
    ],
    "origins": [],
    "destinations": [],
    "dealTypes": ["flight"],
    "maxAgeDays": 7,
    "maxResults": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("automatic/flight-deals-feed").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 '{
  "sources": [
    "secretFlying",
    "fly4free",
    "theFlightDeal"
  ],
  "origins": [],
  "destinations": [],
  "dealTypes": [
    "flight"
  ],
  "maxAgeDays": 7,
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call automatic/flight-deals-feed --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automatic/flight-deals-feed"
        }
    }
}
```

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/KMvksJ5u6dAmVJSyQ/builds/MHtZ8awfwhlsE3u1u/openapi.json
