Google Flights Multi-City Scraper avatar

Google Flights Multi-City Scraper

Pricing

from $0.21 / 1,000 flight-scrapeds

Go to Apify Store
Google Flights Multi-City Scraper

Google Flights Multi-City Scraper

Scrape Google Flights multi-city trips of three legs or more, and quiet routes Google leaves out of its own page. Each row is an itinerary with its price, airlines, aircraft, legroom, layovers, CO2 and contrail warming. $0.30 per 1,000 flights.

Pricing

from $0.21 / 1,000 flight-scrapeds

Rating

0.0

(0)

Developer

BonCross API

BonCross API

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

6 hours ago

Last modified

Categories

Share

What is Google Flights Multi-City Scraper?

Google Flights Multi-City Scraper prices the trips an ordinary flight search can't: an itinerary of three legs or more as one fare, and the quiet routes where Google's page shows nothing even though flights exist. Give it your legs, one per line, or a single route, and you get the itineraries back as structured data. It will also tell you the cheapest date to fly across a window of months.

Three things it does that are hard to get elsewhere:

  • A multi-city trip as one fare. London, Paris, Rome and back to London returned 21 to 22 itineraries in about a second per search, each priced for the whole trip.
  • Routes that normally come up empty. Port Moresby to Honiara, a return that an ordinary search leaves blank, returned 13 itineraries in 4 seconds.
  • The cheapest day to go. Sixty routes with a four-month date window returned 600 itineraries and 7,136 dated prices in 29 seconds.

You also get the contrail warming potential of each leg, which most flight data leaves out, and you pay $0.30 per 1,000 flights on the Free plan ($0.21 on Business) with proxy usage and platform usage included.

BonCross Verified means we tested this actor against the live site before release and kept the record:

  • 41 of 41 live checks on its inputs and filters passed on 8 October 2026
  • 4 searches run on 7 October 2026, a four-leg trip and 3 quiet routes: 60 itineraries, none for the four-leg trip
  • Charges matched: 1 start, 4 searches, 60 itineraries

Planning an ordinary one way or return search? Use Google Flights Scraper. It's built for those and costs two thirds as much per flight. This actor is for the shapes that one can't do: multi-city trips, quiet routes and flexible dates.

What else you can do with it:

  • Read the flights of the first leg (flight number, aircraft type, legroom and operating carrier) beside the whole trip's fare
  • See layover airports, layover length and whether the connection changes airport
  • Get the CO2 estimate per itinerary and per leg, against the route's typical, with Google's lower-emissions badge
  • Compare each itinerary's price with what it cost on your last run
  • Search several airports at once, or a whole city, and get the pairings in one run
  • Exclude an airline or a whole alliance, and sort by price, time, duration or CO2
  • Filter on stops, airline, alliance, price, time windows, journey time, layover length, connecting airports and lower emissions
  • Follow a link straight into Google's booking page for each itinerary
  • See which airline you book and which one actually operates each leg

Who uses multi-city flight data?

  • Travel planners pricing a round-the-world or multi-stop itinerary as one trip, not as separate tickets
  • Anyone comparing the same multi-city trip across departure dates to find the cheapest combination
  • Teams that need fares for regional and island routes an ordinary search leaves empty
  • Booking and corporate travel tools that take multi-leg itinerary data as a feed
  • Fare watchers tracking a multi-stop trip daily to catch a drop
  • Sustainability teams measuring the carbon cost of a multi-leg travel policy, contrail warming included
  • Researchers looking at which aircraft and cabins serve a quiet route and what legroom they offer, or keeping a fare history for pricing or academic work

What data can you extract?

✈️ Airline names and codesFlight numbers of the first leg
💷 Price and currencyTrip type: one way, return or multi-city
🕑 Departure and arrival times📅 Dates, with next-day arrival offset
⏱ Total journey timeNumber of stops
🛬 Layover airport, city and lengthAirport-change flag on connections
Aircraft type per legLegroom in inches
🔌 In-seat power and USB📶 Free or paid Wi-Fi per leg
🎬 Live TV, on-demand video and streaming🧳 Airline baggage policy links
🌱 CO2 per itinerary and per legCO2 against the route's typical, lower-emissions badge
☁️ Contrail warming potentialCabin flown on each leg
💺 Seat type and legroom ratingCodeshare flag per leg
Marketing and operating carrier and flight number🛫 Origin and destination airport per leg
Price change since your last run⭐ Google's best-flights flag
🗺 One fare for the whole multi-city tripThe legs of the trip, and which one the row details
📆 Cheapest fare per departure date🔗 Booking link and booking token per itinerary

How to scrape a multi-city trip

It's a form. You type the legs and download a spreadsheet.

  1. Create a free Apify account and open Google Flights Multi-City Scraper.
  2. Add your legs, one per line, as origin, destination and date: LHR,JFK,2026-11-10.
  3. Set cabin, passengers and any airline, stop or layover filters you want.
  4. Click Start. A three-leg trip took 1 to 4 seconds in the measured runs below.
  5. Download the trip's itineraries as a spreadsheet (Excel or CSV), or take JSON, XML or HTML.

⬇️ Input

Give it a multi-city trip, or a single quiet route that an ordinary search returns nothing for. Airport codes such as LHR work, and you can use city codes such as LON or TYO too. If you have more one way or return routes, add them under "More routes", one per line as origin, destination, departure date and an optional return date. Paste Google Flights links into "Google Flights URLs".

For a long list of links, use Start URLs. It loads them in bulk from a file, a Google Sheet or a remote list, and whatever you put there is combined with the pasted links.

You have two limits. "Max itineraries per search" applies to each trip or route separately: ten targets at 50 each returns 500. "Maximum results for the whole run" is the ceiling across all of them. Once it's reached, nothing more is fetched or charged.

A multi-city trip

{
"multiCityLegs": [
"LHR,JFK,2026-11-10",
"JFK,LAX,2026-11-15",
"LAX,LHR,2026-11-20"
],
"currency": "GBP"
}

A four leg trip in business class

{
"multiCityLegs": [
"LHR,NRT,2026-11-10",
"NRT,ICN,2026-11-15",
"ICN,SIN,2026-11-18",
"SIN,LHR,2026-11-22"
],
"cabinClass": "business",
"adults": 2
}

A quiet route that an ordinary search leaves empty

{
"origin": "POM",
"destination": "HIR",
"departureDate": "2026-11-17",
"returnDate": "2026-11-24",
"currency": "GBP"
}

When is it cheapest to go?

{
"origin": "LHR",
"destination": "JFK",
"departureDate": "2026-11-17",
"returnDate": "2026-11-24",
"flexibleDates": true,
"flexibleDateFrom": "2026-11-01",
"flexibleDateTo": "2027-01-15",
"tripLengthDays": 7,
"currency": "GBP"
}

Switch on "Also return the cheapest date to fly" and give a window with the earliest and latest departure dates. You get one row per departure date in the window, with the lowest fare for that date under the same cabin, stops and airline filters as the search. For a return trip, "Trip length in days" sets how many nights to stay. It defaults to the gap between your departure and return dates.

Lower-emission options on the first leg, cheapest first

{
"multiCityLegs": [
"LHR,CDG,2026-11-10",
"CDG,FCO,2026-11-14",
"FCO,LHR,2026-11-18"
],
"lessCo2Only": true,
"sortBy": "price"
}

Watch a multi-city trip and report what moved

{
"multiCityLegs": [
"LHR,JFK,2026-11-10",
"JFK,LAX,2026-11-15",
"LAX,LHR,2026-11-20"
],
"trackPriceChanges": true,
"priceMemoryStore": "autumn-tour"
}

Passengers and bags. Besides adults (default 1, 1 to 9) you can set children aged 2 to 11, "Infants in seat" (their own seat) and "Infants on lap", 0 to 8 each. The two bag settings, "Carry-on bags" and "Checked bags" (0 to 5), keep only fares that include that many bags, and they work on one way and return searches. Google doesn't apply bag filters to a multi-city itinerary, and they have no effect there.

Filters. On a multi-city trip the stop, journey-time, layover and connecting-airport filters apply to the first leg, the one each row details.

SettingWhat it does
maxStops (0 to 3)Empty for any number of stops, 0 for nonstop only
airlines, excludeAirlinesTwo letter airline codes such as BA, or an alliance (ONEWORLD, SKYTEAM, STAR_ALLIANCE), to keep or to leave out. An itinerary is excluded if any of its flights match
maxPriceKeep only itineraries at or below this fare, in the chosen currency
departureTimeFrom, departureTimeTo, arrivalTimeFrom, arrivalTimeTo (hours, 0 to 23)Keep only flights leaving or landing within these hours
maxDurationMinutes (60 to 4000)Keep only itineraries no longer than this, door to door
minLayoverMinutes, maxLayoverMinutes (30 to 1440)Drop itineraries with a connection shorter or longer than this
onlyConnectingAirports, excludeConnectingAirportsThree letter airport codes such as AMS, to connect only through or to avoid
lessCo2OnlyKeep only Google's lower-emission options
sortByOrder by price, journey time, departure time, arrival time, CO2 or number of stops. top keeps the site's own ranking
language (default en)Language code for airport and airline names

For developers

  • maxResultsPerSearch is the per-target limit and maxItems the run-wide one. Leave either at its default of 0 and it doesn't limit anything.
  • fastPath (Try the fast path first, default true) gives much faster results. Measured on a three-leg trip, it returned 21 itineraries in under a second against 22 in about six with it off, the extra one being the highest-priced option. Turn it off if you need the last itinerary and can spare the time.
  • maxConcurrency (Parallel requests, default 8, 1 to 32) is the number of requests in flight at once. Searches in one run, and the date windows of each price calendar, are fetched at the same time. If a run reports errors, try a lower value.
  • Flexible-date windows longer than 61 days are split automatically. The window ends at most 330 days after flexibleDateFrom and 330 days from today. A later flexibleDateTo is brought in to that limit, with a note in the log.
  • With trackPriceChanges on, each itinerary's price is kept in a named storage between runs, and the next run fills previousPrice, priceChange, priceChangePct and previousScrapedAt. Two watchlists sharing one priceMemoryStore name would overwrite each other. Name them apart.
  • Alliance membership for excludeAirlines is kept by this actor. An airline that joined very recently may not be recognised.
  • Each search is retried up to three times. A run where all searches come up empty restarts once and then fails with a message. That way a refusal is never reported as a trip with no flights.
  • Rows are saved as the run goes. A run that the platform restarts picks up where it stopped, and no row is saved or charged a second time.

⬆️ Output

You get one record per itinerary, plus one record per departure date when flexible dates are switched on. A search Google answers with no itineraries writes one noItineraries record naming the trip, which means no search goes unaccounted for. Open the Overview view for a table of price, airlines, times, duration, stops, CO2 and price change.

{
"recordType": "itinerary",
"id": "UtB22d",
"url": "https://www.google.com/travel/flights/search?tfs=…",
"scrapedAt": "2026-09-26T17:33:34.793Z",
"origin": "LHR",
"destination": "LHR",
"departureDate": "2026-11-10",
"returnDate": null,
"isTopFlight": true,
"price": 577,
"isPriceAvailable": true,
"currency": "GBP",
"priceType": "multi-city",
"itinerary": ["LHR-CDG 2026-11-10", "CDG-FCO 2026-11-14", "FCO-LHR 2026-11-18"],
"detailLeg": "LHR-CDG 2026-11-10",
"airlineCode": "BA",
"airlineNames": ["British Airways"],
"operatingAirlineNames": [],
"originCode": "LHR",
"destinationCode": "CDG",
"departureAt": "2026-11-10T07:15",
"departureTime": "07:15",
"arrivalAt": "2026-11-10T09:30",
"arrivalDate": "2026-11-10",
"arrivalTime": "09:30",
"arrivalDayOffset": 0,
"durationMinutes": 75,
"durationText": "1 hr 15 min",
"stops": 0,
"layovers": [],
"emissionsKg": 58,
"emissionsTypicalKg": 62,
"emissionsVsTypicalPct": -6,
"isLowerEmissions": true,
"legs": [
{
"airlineCode": "BA",
"airlineName": "British Airways",
"flightNumber": "BA304",
"operatedByCode": "BA",
"operatedByName": "British Airways",
"operatedByFlightNumber": "BA304",
"marketingCarriers": [],
"isCodeshare": false,
"originCode": "LHR",
"originName": "Heathrow Airport",
"destinationCode": "CDG",
"destinationName": "Paris Charles de Gaulle Airport",
"departureAt": "2026-11-10T07:15",
"arrivalAt": "2026-11-10T09:30",
"durationMinutes": 75,
"aircraft": "Airbus A320",
"legroom": "29 in",
"legroomClass": "below average",
"cabinClass": "economy",
"emissionsKg": 58,
"contrailWarming": "low",
"amenities": {
"powerAndUsbOutlets": false,
"onDemandVideo": false,
"wifiType": "paid",
"wifi": true,
"wifiIsPaid": true
}
}
],
"baggageUrls": [{ "airlineCode": "BA", "airlineName": "British Airways", "url": "https://…" }],
"bookingToken": "CjRIRkw2…",
"itineraryToken": "[\"CAISA0dCUBoE…\"]",
"bookingUrl": "https://www.google.com/travel/flights/booking?tfs=…",
"previousPrice": 598,
"priceChange": -21,
"priceChangePct": -3.51,
"previousScrapedAt": "2026-09-25T17:30:02.114Z"
}

On a multi-city row, price is the whole trip's fare, itinerary lists the trip leg by leg, and detailLeg names the leg that legs, stops, layovers, times and duration describe (the first one). On a one way or return search itinerary and detailLeg are null and the row reads like an ordinary search result.

With flexibleDates on, you also get one row per departure date with the lowest fare for it. Its url opens the search for that date pair, which puts the cheapest date in the calendar one click from its itineraries:

{
"recordType": "datePrice",
"id": "LHR-JFK-2026-11-01-2026-11-08",
"url": "https://www.google.com/travel/flights/search?tfs=…",
"origin": "LHR",
"destination": "JFK",
"departureDate": "2026-11-01",
"returnDate": "2026-11-08",
"tripLengthDays": 7,
"price": 373,
"currency": "GBP",
"scrapedAt": "2026-09-13T17:00:37.402Z"
}

Four things to know about the columns:

  • price covers the whole party you searched for, adults, children and infants together. It isn't a per-person fare.
  • airlineCode and flightNumber name the flight the way Google lists it (BA113). If it's a codeshare, isCodeshare is true and marketingCarriers has the partner airlines selling it under their own numbers (AA6913, IB3541).
  • operatedByName tells you, in Google's words, when another airline flies the aircraft, a regional partner for instance ("Republic Airways as American Eagle").
  • bookingUrl takes you to Google's page for that exact itinerary, priced in your search currency.

How many itineraries per trip, and how fast?

SearchItinerariesTime
London, Paris, Rome, London21 to 22about 1 s per search
London, New York, Los Angeles, London54 s
Port Moresby to Honiara, return134 s
Four quiet routes in one run1675 s
A multi-city trip plus five routes, with flexible dates120 itineraries and 535 dated prices5-6 s
16 routes with flexible dates320 itineraries and 1,711 dated prices6-13 s
60 routes with flexible dates over four months600 itineraries and 7,136 dated prices29 s
60 routes with flexible dates over two months600 itineraries and 3,660 dated prices7-8 s

Searches in one run are fetched at the same time, 8 at once by default. That matters on a long list: the 16-route run took 92 s one search at a time. Several thousand routes fit inside the default one-hour run limit. We measured these between 1 and 3 October 2026 as whole runs on Apify, with start-up counted.

Expect small result sets. A multi-city search returns the options Google lists for the first leg, each with the fare for the whole trip, and that came to between 5 and 22 on the trips above. A quiet route returns whatever Google has for it, often a handful. The fares are the ones Google displays in the currency you chose, and a different currency gives a different answer. Now and then Google shows an itinerary with no price. You'll find isPriceAvailable: false on those rows.

How much does it cost?

EventFree planStarterScaleBusiness
actor-start, per run$0.001$0.001$0.001$0.001
search-resolved, per trip or route searched$0.0005$0.0005$0.0005$0.0005
flight-scraped, per itinerary returned, and per dated price when flexible dates are on$0.0003$0.00027$0.00024$0.00021

Enterprise plans pay the Business price.

That's $0.30 per 1,000 flights on the Free plan and $0.21 on Business, and there's nothing on top: proxy usage and platform usage are included.

  • A multi-city trip returning 6 itineraries: $0.001 + $0.0005 + 6 × $0.0003 = $0.0033 ($0.0028 on Business).
  • Flexible dates on one route: each dated price is a row, charged as flight-scraped. A 76-date window across two and a half months adds 76 × $0.0003 = $0.0228 to that route's search ($0.016 on Business).

The $5 of credits that comes with Apify's Free plan each month pays for about 1,500 multi-city searches of 6 itineraries each before you pay anything.

A search Google answers with no bookable flights isn't charged. A search that's answered with an empty list, or that has nothing left after your filters, costs the $0.0005 resolve fee alone.

Limitations

  • A multi-city row details the first leg. You get the options for the first leg, each priced for the whole trip, which is what Google itself shows. You don't get all combinations of all legs. On those rows detailLeg names the leg the flight details describe ("LHR-CDG 2026-11-10"): legs, stops, layovers, times and duration are that leg's, price is the trip's, and itinerary lists the legs in order.
  • A trip of four or more legs is priced for some dates and not for others. The same four cities have returned itineraries on one set of dates and none on another a few weeks apart, while three-leg trips have returned on every test. When Google returns none, you get one row with recordType: "noItineraries", the trip's cities and dates, and an error message saying no itineraries were returned for these dates. It costs the resolve fee alone. Try other dates.
  • Google publishes no price history or typical-price range for multi-city trips or quiet routes, and you won't get a price insights record for them. Ordinary routes have one, through the plain search actor.
  • Flexible dates cover one origin-and-destination pair. A multi-city trip is priced as a whole and Google publishes no per-date calendar for one. The option is skipped there, with a note in the log.
  • Google occasionally fails to return results for a search that normally works. After three tries, a search that still returns nothing gets a row with an error message saying it was refused. That row isn't charged, and the search is worth running again later.
  • On a multi-city trip the stop, journey time, layover and connecting-airport filters apply to the first leg. The price is always the whole trip's.
  • You can filter by airline code and by alliance. You can't filter to a named fare brand.
  • The carry-on and checked bag filters have no effect on a multi-city trip. Google applies them to a one-way or round-trip search but lists a multi-city itinerary without them. The rows have no bag allowance to filter on afterwards, only a link to each airline's baggage page. Both filters work normally on the one-way and round-trip searches this actor also serves.
  • A fare here is what Google showed at the time of the run. It isn't a live airline quote and may have moved by the time you book.

FAQ

Do I need proxies or a Google account?

Neither. There's no proxy to set up and no proxy charge, and you don't need an account or an API key of any kind.

Why does an ordinary search return nothing for my route?

Google doesn't put results in the page for every search. On quiet routes it serves an empty page even though flights exist. This actor loads those searches the way the site itself does, which is why it finds them.

My four-leg trip returned nothing. Is it broken?

Probably not. Google prices trips of four or more legs for some dates and not for others, and the same four cities can return itineraries a few weeks later. Look for the noItineraries row in your dataset: it names the trip and says no itineraries were returned for those dates. Move the dates and run it again.

Which leg do the flight details describe?

The first. On a multi-city row, detailLeg names it, and the price beside it is for the whole trip.

How do I find the cheapest date to fly?

Switch on "Also return the cheapest date to fly" and set the earliest and latest departure dates. You get a row per date with the lowest fare, and each row links to the search for that date. It works for one origin and destination, not for a multi-city trip.

How do I see what a trip's price did since yesterday?

Schedule the run in Apify and switch on "Compare with the last run". The second run, and each one after it, shows what an itinerary cost last time and the change in money and in percent. If you watch more than one trip list, give each its own "Price memory name".

Why is there no price history in my results?

Google only computes price insights for ordinary one way and return routes, which leaves out multi-city trips and quiet routes. Nothing is being dropped: the data doesn't exist for these searches. Ordinary routes do have it, through Google Flights Scraper.

Why are some prices missing?

Sometimes Google lists an itinerary and attaches no fare to it. Those rows have a null price and isPriceAvailable: false. We don't put a zero there, because a zero would read as a free flight.

In most jurisdictions, yes: scraping public information is legal, and the fare pages read here are open to anyone without a login. No personal data is collected. Republishing fares is a different matter from reading them, and that part is yours to check.

Run it on a schedule or from code

A daily watch on a multi-stop trip needs no code. Apify's scheduler runs the actor, and a webhook or the Slack and Google Sheets integrations can pass on the trips whose fare moved.

From your own code, one call runs the actor and returns the dataset. There are clients for JavaScript and Python.

POST https://api.apify.com/v2/acts/boncross~google-flights-multi-city/run-sync-get-dataset-items?token=YOUR_TOKEN

Agents in Claude, ChatGPT, Cursor or LibreChat can price a trip too. Point the client at the Apify MCP server (mcp.apify.com) and reference the actor as boncross/google-flights-multi-city. The agent sends the legs as input JSON and gets the itineraries back.

More from BonCross

Your feedback

Got a trip that should price and doesn't, or a quiet route we still miss? Open an issue on the Issues tab in Apify Console and include the legs and dates. We read every issue and reply there.