Flight Price Aggregator API πŸ’° β€” 7 Sources, One Query avatar

Flight Price Aggregator API πŸ’° β€” 7 Sources, One Query

Pricing

from $2.50 / 1,000 flight offers

Go to Apify Store
Flight Price Aggregator API πŸ’° β€” 7 Sources, One Query

Flight Price Aggregator API πŸ’° β€” 7 Sources, One Query

Compare flight prices across Google Flights, Skyscanner, Kiwi, Ryanair, Wizz Air, EasyJet & Norwegian in one call β€” or batch 50 routes per run. Merges the same flight across sources and converts every currency to yours, so the cheapest tag is real. Optional per-route savings summary. JSON/CSV.

Pricing

from $2.50 / 1,000 flight offers

Rating

5.0

(1)

Developer

Muhamed Didovic

Muhamed Didovic

Maintained by Community

Actor stats

0

Bookmarked

34

Total users

13

Monthly active users

16 hours ago

Last modified

Categories

Share

Flight Price Aggregator API β€” 7 Sources, One Query πŸ’°

⭐ Useful? Leave a review β€” it takes 10 seconds and is the single biggest thing that helps other travel developers find this aggregator.

Compare flight prices across Google Flights, Skyscanner, Kiwi, Ryanair, Wizz Air, EasyJet and Norwegian in a single call β€” or batch up to 50 routes in one run. One search fans out to all seven sources in parallel, merges the results by flight identity, and cross-source price-matches β€” so for every flight you instantly see which source sells it cheapest.

How it works

Why this actor

Most flight scrapers give you one source's view. Low-cost carriers are almost always cheaper booked direct than through a metasearch aggregator β€” but you only know that if you can see both prices side by side. This actor does exactly that:

  • Direct LCC fares from Ryanair, Wizz Air, EasyJet and Norwegian β€” the real, bookable price, not a marked-up resale.
  • Broad coverage from Google Flights, Skyscanner and Kiwi β€” every airline on the route, including the legacy carriers the LCCs don't show.
  • One merged view β€” the same physical flight from multiple sources collapses into a single row with a per-source price map (prices), the list of sources that returned it (sourcesFound), and the cheapest seller tagged (cheapestSource).
  • Batch mode β€” pass a routes array and monitor a whole route portfolio in one run instead of scheduling N separate actors.
  • Result filters β€” directOnly, maxStops, maxDurationMinutes applied server-side, so your downstream code gets exactly the flights you care about.

The payoff is concrete: on a typical London→Paris search the same EasyJet flight comes back at £14.99 direct (about $20) vs $41 via Google Flights — and the actor tags the direct fare as cheapest automatically. Sources that price in their own currency are converted before anything is ranked, so the cheapest tag reflects the actual cheaper fare, not the smaller number.

Use cases

  • Fare-alert products β€” batch your subscribers' routes into one scheduled run, push a notification whenever the cheapest price drops below a threshold. Per-source price, cheapest seller and booking URL are already in the payload.
  • Price comparison / meta-search tools β€” power a "compare all sources" feature without integrating seven APIs and managing seven sets of blocks.
  • Deal hunting at scale β€” 50 routes per run Γ— nonstop-only filter = a clean daily feed of direct-flight deals.
  • Market & pricing research β€” see how direct LCC pricing compares to aggregator pricing at scale, with aligned timestamps across sources in one run.
  • AI agents β€” pair with the companion MCP server to give an assistant a search_flights tool.

Input

FieldRequiredDescription
originβœ…*Origin β€” city name (London) or airport IATA code (LGW)
destinationβœ…*Destination β€” city name or IATA code
departDateβœ…*Outbound date YYYY-MM-DD
returnDateReturn date YYYY-MM-DD (omit for one-way)
routesBatch mode: array of {origin, destination, departDate?, returnDate?} β€” up to 50 routes in one run. Per-route dates fall back to the top-level dates. When set, top-level origin/destination are ignored.
adults / childrenPassenger counts (defaults 1 / 0)
currencyPreferred display currency, ISO 4217 (default USD)
cabinClassECONOMY / PREMIUM_ECONOMY / BUSINESS / FIRST
directOnlytrue = only nonstop flights
maxStopsOnly flights with at most this many stops
maxDurationMinutesOnly flights up to this total duration (e.g. 300 = 5 h)
sourcesSubset of the seven sources; omit to query all
maxPerSourceCap on offers per source before merging (default 10)
includeRouteSummarytrue = also emit one cross-source comparison row per route (cheapest source per direction, the spread, every source's price) into a separate dataset β€” see Route summary
routeSummaryDatasetNameWhere those summary rows go (default route-summaries). Named datasets append across runs, so a scheduled watch builds price history in one place
proxyConfigurationProxy settings; residential is the default and recommended

* Either set origin + destination + departDate at the top level, or provide them per route in routes.

Single route

{
"origin": "LGW",
"destination": "CDG",
"departDate": "2026-08-12",
"returnDate": "2026-08-19",
"maxPerSource": 8
}

Batch mode β€” one run, many routes

{
"routes": [
{ "origin": "London", "destination": "Barcelona" },
{ "origin": "London", "destination": "Madrid" },
{ "origin": "STN", "destination": "DUB", "departDate": "2026-09-01" }
],
"departDate": "2026-08-12",
"directOnly": true,
"currency": "EUR"
}

Output

One row per merged offer:

{
"source": "easyjet",
"direction": "outbound",
"origin": "LGW",
"destination": "CDG",
"date": "2026-08-12",
"price": 14.99,
"currency": "GBP",
"priceNormalized": 20.15,
"normalizedCurrency": "USD",
"fxRate": 1.344598,
"carrier": "easyJet",
"flightNumber": "U28405",
"departTime": "16:10",
"arriveTime": "18:25",
"stops": 0,
"prices": { "easyjet": 14.99, "googleflights": 41 },
"pricesCurrency": { "easyjet": "GBP", "googleflights": "USD" },
"pricesNormalized": { "easyjet": 20.15, "googleflights": 41 },
"sourcesFound": ["easyjet", "googleflights"],
"cheapestSource": "easyjet",
"isCheapest": true
}
FieldMeaning
price / currencyWhat the source quotes β€” the amount you pay at that seller's checkout
priceNormalized / normalizedCurrencyThe same fare restated in your requested currency, so it can be compared with the other sources
fxRateReference rate used for that conversion (1 = no conversion)
pricesEvery source's price for this exact flight, keyed by source, as each one quoted it
pricesCurrencyThe currency of each entry in prices β€” they can differ between sources
pricesNormalizedThe same map in normalizedCurrency β€” the one that is safe to compare
sourcesFoundWhich sources returned this flight
cheapestSourceThe source selling it cheapest (ranked on pricesNormalized)
isCheapesttrue on the single cheapest offer per direction (ranked on priceNormalized)
stops / durationMinutesStop count and total duration (filterable via input)

Export as JSON, CSV, Excel or XML from the run page, or pull via the Apify API.

Route summary (optional)

Set includeRouteSummary: true to also get one comparison row per route β€” the answer to "which source is cheapest, and by how much" without reading every offer yourself:

{
"type": "route-summary",
"origin": "LHR", "destination": "BUD",
"currency": "USD",
"priceComparable": true,
"quotedCurrencies": ["GBP", "HUF"],
"fx": { "converted": true, "ratesDate": "2026-08-04", "rateSources": ["ECB euro reference rates"], "supplemented": [], "unconvertible": [] },
"outbound": {
"cheapestPrice": 98.14, "cheapestSource": "wizzair",
"cheapestQuotedPrice": 72.99, "cheapestQuotedCurrency": "GBP",
"highestPrice": 121.4, "highestSource": "googleflights",
"spread": 23.26, "spreadPct": 23.7,
"pricesBySource": [{ "source": "wizzair", "price": 98.14, "quotedPrice": 72.99, "quotedCurrency": "GBP" }],
"sourcesNotComparable": []
},
"sourcesQueried": 7, "sourcesOk": 7, "sourcesFailed": []
}

These rows go to a separate named dataset (route-summaries by default, or whatever you set in routeSummaryDatasetName) β€” not the main one β€” so your flight rows keep a single clean shape for CSV export. Named datasets append across runs, so a scheduled fare watch accumulates readable price history in one place.

spread is what you save by booking the cheapest source instead of the dearest, in your requested currency. priceComparable tells you whether every priced source could be converted; when it is false, fx.unconvertible and sourcesNotComparable name exactly which quotes were left out of the ranking rather than guessed at.

Code examples

curl

curl -X POST 'https://api.apify.com/v2/acts/memo23~flights-aggregator-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"routes": [
{ "origin": "LHR", "destination": "BCN" },
{ "origin": "LHR", "destination": "MAD" }
],
"departDate": "2026-08-12",
"directOnly": true,
"currency": "EUR"
}'

Python (apify-client)

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("memo23/flights-aggregator-scraper").call(run_input={
"origin": "London",
"destination": "Barcelona",
"departDate": "2026-08-12",
"returnDate": "2026-08-19",
"maxStops": 1,
})
for offer in client.dataset(run["defaultDatasetId"]).iterate_items():
print(offer["flightNumber"], offer["price"], offer["cheapestSource"], offer["prices"])

Node.js (apify-client)

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('memo23/flights-aggregator-scraper').call({
routes: [{ origin: 'STN', destination: 'DUB' }, { origin: 'LTN', destination: 'KRK' }],
departDate: '2026-08-12',
directOnly: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.table(items.map((o) => ({ flight: o.flightNumber, price: o.price, cheapest: o.cheapestSource })));

How it compares

FeatureThis actorSingle-source scraper (Google Flights only)Other multi-source scraperBrowser-based scraper
Sources per run7 (Google Flights, Skyscanner, Kiwi, Ryanair, Wizz Air, EasyJet, Norwegian)15–71–2
Routes per runUp to 50 (batch mode)111
Per-source price map + cheapest sellerYesNoYesNo
Direct-only / max-stops / max-duration filtersYes, server-sideRareNo (post-process yourself)Rare
City-name input (auto-resolves to IATA)YesIATA onlyIATA onlyVaries
Children in passenger countYesVariesAdults onlyVaries
Scraping engineRaw HTTPRaw HTTPRaw HTTPHeadless browser
Companion MCP server for AI agentsYesRareVariesRare

The honest take: if you only need one source's view of one route, a single-source scraper is fine. If you monitor multiple routes, want the bookable direct LCC fare next to the metasearch price, or need filtered results without post-processing, this is the one to pick.

Notes & FAQ

  • Which routes do the LCCs cover? Ryanair, Wizz Air, EasyJet and Norwegian only return flights on their own (mostly European) routes. For a route they don't fly they simply return nothing β€” Google Flights, Skyscanner and Kiwi still cover it. A source with no data for a route never fails the run.
  • Why does a row come back from a different airport than I asked for? Because the low-cost carriers don't fly to every airport a city name resolves to. London resolves to Heathrow, and Wizz Air, easyJet and Norwegian serve none of it β€” so each one searches its own London-wide code instead (Gatwick, Luton, Stansted, Southend) rather than reporting nothing. Rows then carry the airport actually flown: you may ask for LHR and get LTN, and the bookingUrl points at that airport's fare. Norwegian's calendar prices a whole city rather than one airport, so its rows carry the metro code LON. The run log names every substitution it makes. Airports genuinely outside a carrier's network β€” Zurich on Wizz Air, Frankfurt on Norwegian β€” return no offers from that source instead of failing it.
  • How do the filters treat price-only rows? Wizz Air and Norwegian rows come from per-day low-fare calendars (cheapest price for the date, no flight number/times), and a multi-segment connection from Skyscanner or Kiwi is priced as a whole trip rather than as one flight. Whenever directOnly, maxStops or maxDurationMinutes is set, those price-only rows are excluded β€” an "unknown stops" row surviving a nonstop filter would be misleading. Direct flights from Skyscanner and Kiwi carry full stop/duration data and pass the filters normally.
  • Currencies. Most sources are queried in your currency directly. Wizz Air and easyJet always price in the departure market's currency instead (a Milan departure comes back in EUR, a Geneva one in CHF) and offer no way to ask for another. Those rows keep the price the airline actually quotes in price/currency, and every row also carries priceNormalized in your requested currency, converted at the ECB's daily reference rate β€” that is the figure the cheapest tag, the row order and the route summary's spread are computed from, so a Β£12.99 fare never beats a $15 one just because the number is smaller. The ECB doesn't publish every currency Wizz Air quotes in (its Tirana, Belgrade, Skopje, Sarajevo, Kutaisi, Chisinau, Kyiv and Abu Dhabi markets bill in ALL, RSD, MKD, BAM, GEL, MDL, UAH and AED), so those are converted from a backup feed instead; the route summary's fx.rateSources and fx.supplemented say exactly which rate priced the route. Anything neither feed covers is still returned with its real price, just left out of the cheapest comparison rather than guessed at. Reference rates rank offers; they are not the rate your bank will settle at.
  • Skyscanner rows. Skyscanner is searched one direction at a time, so its prices are true one-way fares directly comparable with every other source, and its direct flights carry a flight number that cross-source price-matches against Google Flights and the airlines' own fares. Connections are priced as a whole trip, so they are marked price-only and stay out of the per-flight match.
  • Past dates. A route with a past departDate is skipped with an explicit PAST_DATE row in the dataset (instead of silently returning nothing); the remaining routes still run.
  • Proxies. Residential proxy is recommended (and the default) for the broadest, most stable coverage.
  • How often should I run it for fare monitoring? Once or twice a day covers most routes; hourly for hot routes. More often than every 15 minutes rarely surfaces new prices.

πŸ€– For AI Agents & LLM Apps

Compact reference for AI agents calling this actor via the Apify MCP server or the Apify API (actor: memo23/flights-aggregator-scraper).

Purpose: Fan out one flight search to 7 sources (Google Flights, Skyscanner, Kiwi, Ryanair, Wizz Air, EasyJet, Norwegian), merge by flight identity, and tag the cheapest seller per flight.

Minimal input:

{
"origin": "London",
"destination": "Barcelona",
"departDate": "2026-08-12",
"maxPerSource": 8
}

Batch mode (overrides top-level origin/destination): { "routes": [{"origin":"LHR","destination":"BCN"},{"origin":"LHR","destination":"MAD"}], "departDate": "2026-08-12" }

Output: one row per merged offer β€” source, direction, origin, destination, date, price, currency, priceNormalized, normalizedCurrency, fxRate, carrier, flightNumber, departTime, arriveTime, stops, durationMinutes, prices {source: price}, pricesCurrency {source: currency}, pricesNormalized {source: price}, sourcesFound, cheapestSource, isCheapest.

Compare on priceNormalized (all rows share normalizedCurrency), not on price β€” sources quote in different currencies and price is deliberately left as each source quoted it.

Behaviors an agent should know:

  • No maxItems field; cap volume with maxPerSource (default 10, max 100) β€” keep ≀ 50 for quick runs. Row count scales with sources Γ— routes.
  • routes (array, max 50) is batch mode; when set the top-level origin/destination are ignored.
  • The four LCC sources (Ryanair, Wizz Air, EasyJet, Norwegian) only return their own mostly-European routes; a source with no data never fails the run.
  • A row's origin/destination may differ from the airport you asked for: the LCCs don't serve every airport a city resolves to (London β†’ Heathrow, which none of them fly), so they search that city's other airports and return the one actually flown β€” ask for LHR, get LTN. Match rows on the city, not on the requested code. Norwegian prices a whole city, so its rows carry the metro code LON.
  • includeRouteSummary: true adds one comparison row per route β€” cheapest source and price per direction, the spread against the dearest source, and pricesBySource β€” written to a separate dataset (routeSummaryDatasetName, default route-summaries), not the main one. Read it when you want the verdict rather than the offers.
  • directOnly / maxStops / maxDurationMinutes filter server-side and drop price-only rows (Wizz Air / Norwegian low-fare-calendar rows, and multi-segment connections priced as a whole trip).
  • A past departDate is skipped with an explicit PAST_DATE row; other routes still run.
  • Pay-per-event billing β€” an actor-start fee, one route search fee per originβ†’destination searched (batch mode bills one per route), and a small per-result fee. Current rates are on the Pricing tab of the actor page.
  • Maximum charge per run works as a hard cost ceiling: the actor stops cleanly at the cap and pushes a MAX_CHARGE_REACHED row telling you how many routes were left unsearched. Long batches that would hit the run timeout stop early the same way (TIME_BUDGET_EXHAUSTED row) instead of timing out mid-route.

⚠️ Disclaimer

This actor collects only publicly available flight pricing and schedule information. It does not access any private, authenticated, or personal data. You are responsible for ensuring your use complies with the applicable websites' terms and with all relevant laws (including data-protection regulations). Prices and availability are provided as-is and change constantly β€” always confirm the final price on the airline's or seller's own site before booking.

SEO Keywords

flight price comparison API, cheap flights scraper, multi-source flight scraper, Ryanair scraper, Wizz Air scraper, EasyJet scraper, Google Flights API, Skyscanner scraper, Kiwi flights API, Norwegian air scraper, flight fare aggregator, airfare comparison, low-cost carrier prices, flight deals API, metasearch flights, batch flight search, direct flights filter, one-way and round-trip fares, flight price monitoring, fare alert API, travel data API, MCP flight search