Google Flights Scraper - A tool to retrieve Google Flights results with a simple API. Get flight itineraries, airlines, prices, departure and arrival times, layovers, emissions, price insights, and booking options when available.
Get results as structured JSON for applications or Markdown for LLMs and AI agents, without managing HTML parsing or proxies.
Using a simple GET request, you can retrieve round-trip flight results:
https://serpapi.com/search?engine=google_flights&departure_id=CDG&arrival_id=AUS&type=1&outbound_date=2026-10-17&return_date=2026-10-24¤cy=USD&hl=en&output=json&api_key=YOUR_SERPAPI_API_KEY
- Register at SerpApi to get your API Key. Replace
YOUR_SERPAPI_API_KEYin the examples with your private key; never publish it or commit it to source control. departure_idandarrival_id: airport codes such asCDGandAUS, or location IDs supported by Google Flights.type:1for round trip (default),2for one way, or3for multi-city.- Replace the static dates in the URL and both cURL examples with future travel dates in
YYYY-MM-DDformat before running them. Standard round-trip searches need both dates; one-way searches must omitreturn_date. Python and JavaScript calculate future dates automatically. currency(optional): the currency for returned prices, defaulting toUSD.
JSON is the default output and is useful when you need individual result fields. Add output=md to receive Markdown for text-based workflows, LLMs, and AI agents. The examples use the same CDG–AUS round trip, USD prices, and English language for both formats.
curl --get --fail-with-body --max-time 120 https://serpapi.com/search \
--data-urlencode engine="google_flights" \
--data-urlencode departure_id="CDG" \
--data-urlencode arrival_id="AUS" \
--data-urlencode type="1" \
--data-urlencode outbound_date="2026-10-17" \
--data-urlencode return_date="2026-10-24" \
--data-urlencode currency="USD" \
--data-urlencode hl="en" \
--data-urlencode output="md" \
--data-urlencode api_key="YOUR_SERPAPI_API_KEY"Markdown is returned as text, not a JSON object. Use a text response reader instead of a JSON parser or getJson. The JSON field names below describe JSON output, not a guaranteed Markdown structure. Changing the output format does not remove required route or date parameters.
Replace the dates below with your future travel dates. These cURL examples require cURL 7.76.0 or later for --fail-with-body, which reports HTTP failures while preserving the response body. They stop after 120 seconds. Inspect the body for API error messages as well; an HTTP success alone does not guarantee flight results.
curl --get --fail-with-body --max-time 120 https://serpapi.com/search \
--data-urlencode engine="google_flights" \
--data-urlencode departure_id="CDG" \
--data-urlencode arrival_id="AUS" \
--data-urlencode type="1" \
--data-urlencode outbound_date="2026-10-17" \
--data-urlencode return_date="2026-10-24" \
--data-urlencode currency="USD" \
--data-urlencode hl="en" \
--data-urlencode output="json" \
--data-urlencode api_key="YOUR_SERPAPI_API_KEY"Create a main.py file and install requests:
pip install requestsAdd this code to your file, then run python main.py. It searches for a departure 30 days from today and a return one week later:
from datetime import date, timedelta
import requests
SERPAPI_API_KEY = "YOUR_SERPAPI_API_KEY"
outbound_date = date.today() + timedelta(days=30)
return_date = outbound_date + timedelta(days=7)
params = {
"api_key": SERPAPI_API_KEY,
"engine": "google_flights",
"departure_id": "CDG",
"arrival_id": "AUS",
"type": 1,
"outbound_date": outbound_date.isoformat(),
"return_date": return_date.isoformat(),
"currency": "USD",
"hl": "en",
"output": "json"
}
search = requests.get("https://serpapi.com/search", params=params, timeout=120)
search.raise_for_status()
response = search.json()
if "error" in response:
raise RuntimeError(response["error"])
print(response)Flight results can appear in best_flights and other_flights. Inspect both groups when available rather than assuming every response includes best_flights.
To request Markdown instead, keep the imports, dates, and parameter definitions above and replace the request and response-handling lines with:
params["output"] = "md"
search = requests.get("https://serpapi.com/search", params=params, timeout=120)
search.raise_for_status()
print(search.text)This alternative prints the response body, including any API error text; do not treat every text response as a successful itinerary.
Install the SerpApi JavaScript package:
npm install serpapiCreate an index.js file in a CommonJS project (or use index.cjs in an ES-module project). Run it with node index.js. This JSON example uses the SDK's promise interface, handles request and API errors, and sets its timeout to 120 seconds:
const { config, getJson } = require("serpapi");
const API_KEY = "YOUR_SERPAPI_API_KEY";
config.timeout = 120000;
async function main() {
const outboundDate = new Date();
outboundDate.setUTCDate(outboundDate.getUTCDate() + 30);
const returnDate = new Date(outboundDate);
returnDate.setUTCDate(returnDate.getUTCDate() + 7);
const json = await getJson({
api_key: API_KEY,
engine: "google_flights",
departure_id: "CDG",
arrival_id: "AUS",
type: 1,
outbound_date: outboundDate.toISOString().slice(0, 10),
return_date: returnDate.toISOString().slice(0, 10),
currency: "USD",
hl: "en"
});
if ("error" in json) {
throw new Error(json.error);
}
console.log(json);
}
main().catch((error) => {
console.error(error.message);
process.exitCode = 1;
});For Markdown, this standalone alternative uses built-in fetch in Node.js 18 or later and needs no package installation. Save it as markdown.js and run node markdown.js. Both JavaScript examples calculate departure 30 days from today's UTC date and return seven days later.
async function main() {
const outboundDate = new Date();
outboundDate.setUTCDate(outboundDate.getUTCDate() + 30);
const returnDate = new Date(outboundDate);
returnDate.setUTCDate(returnDate.getUTCDate() + 7);
const params = new URLSearchParams({
api_key: "YOUR_SERPAPI_API_KEY",
engine: "google_flights",
departure_id: "CDG",
arrival_id: "AUS",
type: "1",
outbound_date: outboundDate.toISOString().slice(0, 10),
return_date: returnDate.toISOString().slice(0, 10),
currency: "USD",
hl: "en",
output: "md"
});
const response = await fetch(`https://serpapi.com/search?${params}`, {
signal: AbortSignal.timeout(120000)
});
const text = await response.text();
if (!response.ok) {
throw new Error(`SerpApi HTTP ${response.status}: ${text}`);
}
console.log(text);
}
main().catch((error) => {
console.error(error.message);
process.exitCode = 1;
});The Markdown alternative surfaces HTTP failures and prints any API-level error text returned in a successful HTTP response; it does not parse Markdown as JSON.
Use a simple GET request from any programming language, or explore the ready-to-use libraries in SerpApi Integrations.
These are the main parameters from the current API documentation. The ordinary route examples above use departure_id and arrival_id; multi-city and pinned-itinerary searches supply route information differently.
| Name | Description | Requirement |
|---|---|---|
| engine | Must be set to google_flights. |
Required |
| api_key | Your SerpApi private API key. | Required |
| Route and Dates | ||
| departure_id | Departure airport's uppercase 3-letter IATA code or location kgmid beginning with /m/ or /g/. Supports comma-separated alternatives, such as CDG,ORY. Can be derived from selected_flights_json; multi-city uses per-leg fields. |
Route-dependent |
| arrival_id | Arrival airport code or location kgmid. Supports comma-separated alternatives. Can be derived from selected_flights_json; multi-city uses per-leg fields. |
Route-dependent |
| type | 1 - Round trip (default), 2 - One way, 3 - Multi-city. |
Optional |
| outbound_date | Outbound date in YYYY-MM-DD format. Required for round trip and one way unless using selected_flights_json. Cannot be used for multi-city. |
Conditional |
| return_date | Return date in YYYY-MM-DD format. Required for round trip unless using selected_flights_json. Cannot be used for one way or multi-city. |
Conditional |
| multi_city_json | JSON string containing itinerary legs with departure_id, arrival_id, and date, plus optional times. Use this for type=3 instead of top-level dates. |
Required for multi-city |
| Localization | ||
| gl | Two-letter country code, such as us or uk. |
Optional |
| hl | Language code, such as en, es, or fr; regional variants are also supported. |
Optional |
| currency | Currency code for prices. Defaults to USD. |
Optional |
| Passengers and Cabin | ||
| travel_class | 1 - Economy (default), 2 - Premium economy, 3 - Business, 4 - First. |
Optional |
| adults | Number of adults. Defaults to 1. |
Optional |
| children | Number of children. Defaults to 0. |
Optional |
| infants_in_seat | Number of infants in a seat. Defaults to 0. |
Optional |
| infants_on_lap | Number of infants on a lap. Defaults to 0. |
Optional |
| Sorting and Filters | ||
| sort_by | 1 - Top flights (default), 2 - Price, 3 - Departure time, 4 - Arrival time, 5 - Duration, 6 - Emissions. |
Optional |
| stops | 0 - Any stops (default), 1 - Nonstop only, 2 - One stop or fewer, 3 - Two stops or fewer. |
Optional |
| include_airlines | Comma-separated airline codes or supported alliances. Cannot be used with exclude_airlines. |
Optional |
| exclude_airlines | Comma-separated airline codes or supported alliances to exclude. Cannot be used with include_airlines. |
Optional |
| max_price | Maximum ticket price in the selected currency. Defaults to unlimited. | Optional |
| bags | Number of carry-on bags. Defaults to 0; cannot exceed the total of adults, children, and infants in seats. |
Optional |
| outbound_times | Two or four comma-separated hour values for departure and optionally arrival windows. The end value includes that entire hour: 4,18 means departure from 04:00 to 19:00; 0,23 is unrestricted. |
Optional |
| return_times | Return-flight time windows, using the same format as outbound_times. Only for round trip. |
Optional |
| layover_duration | Minimum and maximum layover duration in minutes, such as 90,330. |
Optional |
| exclude_conns | Comma-separated connecting airport codes to exclude. | Optional |
| max_duration | Maximum flight duration in minutes. If there are no results, the docs suggest increasing by up to 200 minutes for route-specific scheduling variances. | Optional |
| emissions | Set to 1 for lower-emission flights only. |
Optional |
| exclude_basic | Set to true to exclude basic fares; defaults to false. Currently only works for US domestic flights with gl=us and travel_class=1. |
Optional |
| show_hidden | Set to true to include results behind "View more flights". Defaults to false. |
Optional |
| deep_search | Set to true for browser-equivalent results with a longer response time. Defaults to false. |
Optional |
| Flight Selection | ||
| departure_token | Token from a flight result to select that flight and retrieve return flights or the next multi-city leg. Cannot be combined with booking_token. |
Optional |
| booking_token | Token from a flight result to retrieve booking options. Cannot be combined with departure_token. Dates and advanced filters do not affect this lookup. |
Optional |
| selected_flights_json | JSON-encoded object of specific segments: outbound is required; return is required for round trip and forbidden for one way. Cannot be combined with either token, multi_city_json, or type=3. See the schema constraints below. |
Optional |
| SerpApi Parameters | ||
| no_cache | Set to true to request fresh results instead of using the one-hour cache. Cannot be combined with async. |
Optional |
| async | Set to true to submit a search for later retrieval through the Searches Archive API. Cannot be combined with no_cache or used with Ludicrous Speed enabled. |
Optional |
| zero_trace | Enterprise-only: set to true to avoid storing search parameters, files, and metadata on SerpApi's servers. Defaults to false; may make debugging harder. |
Optional |
| output | json (default) for structured results, html for raw HTML, or md for Markdown. Use https://serpapi.com/search when selecting the format. |
Optional |
| json_restrictor | Limit returned JSON fields to reduce payload size; see JSON Restrictor. | Optional |
See the country codes, language codes, and currency codes for supported localization values.
Google Flights uses flight-selection tokens rather than numbered result pages:
- Search with your route, trip type, dates, and preferences. Examine
best_flightsandother_flightswhen present. - For round trip (
type=1), choose an outbound itinerary and repeat the search with itsdeparture_tokento retrieve return-flight options. Keep the original route, dates, passenger counts, cabin, and localization; do not reverse the route. - For multi-city (
type=3), provide a JSON-encoded array inmulti_city_json. Each leg needsdeparture_id,arrival_id, anddate, with optionaltimes. Do not send top-leveloutbound_dateorreturn_date. Repeat the request with the chosen result'sdeparture_tokento select the next leg, preserving the multi-city itinerary and replacing the token with the newly selected result's token at each step. - Once a selected result provides a
booking_token, request booking options with that token. Removedeparture_token; the two tokens are mutually exclusive. Keep the search context, but date parameters and parameters in the documentation's Advanced Filters section do not affect a booking-token lookup. Changing those fields does not search a different itinerary; start a new flight search for that.
One-way searches (type=2) use outbound_date without return_date and can provide a booking_token without a return-selection step. Tokens are opaque API values; never construct them yourself. Booking lookup responses can contain booking_options, selected_flights, and baggage_prices instead of flight-result groups. Retrieving booking options does not purchase or reserve a ticket.
As an alternative to token selection, selected_flights_json can retrieve booking options for an exact one-way or round-trip itinerary:
- Pass a JSON-encoded object, not the multi-city array. It must have an
outboundarray. Thereturnarray is required for round trip and forbidden for one way. - Each ordered segment object needs
flight_number(2-character IATA airline code followed by 1–4 digits, such asBA591),departure_idandarrival_id(3-letter IATA airport codes), anddate(YYYY-MM-DD). Location kgmids and comma-separated airport alternatives are not the segment schema. - Within each leg, each segment's departure airport must equal the previous segment's arrival airport, and dates must be non-decreasing.
- Top-level
departure_id,arrival_id,outbound_date, andreturn_datebecome optional and are derived from the selected segments. If supplied, they must match the selected itinerary. The one-way prohibition onreturn_datestill applies. - Do not combine
selected_flights_jsonwithdeparture_token,booking_token,multi_city_json, ortype=3.
Use json.dumps(...) in Python or JSON.stringify(...) in JavaScript before passing this object through the client's parameter encoder. Consult the full selected-flight schema when constructing a pinned itinerary.
The fields returned depend on the route, availability, and selection stage:
| Field | What it contains |
|---|---|
search_metadata |
Search ID, status, and request metadata. |
search_parameters |
Parameters associated with the search. |
best_flights, other_flights |
Arrays of itineraries. Inspect both when present; neither is guaranteed on every response. |
price_insights |
Lowest price, price level, typical price range, and price history when available. |
airports |
Departure and arrival airport/location details. |
booking_options |
Booking providers and fare/booking details for a selected itinerary. |
selected_flights, baggage_prices |
Supporting itinerary and baggage information on booking lookups. |
error |
API error message, when a search fails. |
The following is a field guide for one itinerary inside best_flights or other_flights, not a literal API response. Its strings describe data types rather than actual flight values:
{
"flights": [
{
"departure_airport": {
"name": "String - Departure airport name",
"id": "String - Airport code",
"time": "String - Departure date and time"
},
"arrival_airport": {
"name": "String - Arrival airport name",
"id": "String - Airport code",
"time": "String - Arrival date and time"
},
"duration": "Integer - Segment duration in minutes",
"airplane": "String - Aircraft model",
"airline": "String - Airline name",
"airline_logo": "String - Airline logo URL",
"travel_class": "String - Cabin class",
"flight_number": "String - Flight number",
"ticket_also_sold_by": ["String - Other ticket-selling airlines"],
"legroom": "String - Legroom information",
"extensions": ["String - Additional segment details"]
}
],
"layovers": [
{
"duration": "Integer - Layover duration in minutes",
"name": "String - Connecting airport name",
"id": "String - Connecting airport code",
"overnight": "Boolean - Whether the layover is overnight"
}
],
"total_duration": "Integer - Total itinerary duration in minutes",
"price": "Number - Price in the requested currency",
"type": "String - Trip type",
"carbon_emissions": {
"this_flight": "Number - Estimated emissions for the itinerary",
"typical_for_this_route": "Number - Typical emissions for the route",
"difference_percent": "Number - Percentage difference from typical emissions"
},
"extensions": ["String - Additional itinerary details"],
"departure_token": "String - Token for selecting the next leg, when available",
"booking_token": "String - Token for booking options, when available"
}The selection tokens above describe alternative stages; do not assume both are present on an itinerary or send both in one request. Segment details, layovers, prices, and other optional sections may be absent. Do not assume a fixed page size or invent a page-number/offset parameter for these token-based selection flows.
See the official flight results, price insights, and booking options examples for stage-specific response shapes. For Markdown output, use output=md and read the response as text as shown above.
- Build flight comparison tools across routes, airlines, and dates.
- Track fare changes and send price alerts.
- Compare nonstop and connecting itineraries by price and total duration.
- Research lower-emission travel options.
- Power travel assistants with current flight and booking information.
- Analyze price insights for route-specific travel planning.
Tutorials from the resource catalog are useful walkthroughs; use the current API documentation above for parameter behavior and replace historical travel dates in older articles.
- How to Scrape Google Flights
- Introduction to scraping Google Flights using Node.js and SerpApi
- Building an Accessibility Search Experience with Google Flights, Hotels, and Maps APIs
- Exact Google Flight Search Results - How Deep Search Mirrors Your Browser
- Making a Flight Price Tracker with Google Flights and Make.com
Related travel workflows (separate APIs may be involved):
- How to Scrape Google Flights Autocomplete
- How to Scrape Google Flights Deals with a simple API
- Building an AI Travel Agent with SerpApi and n8n
Feel free to reach out via contact@serpapi.com.
Check other Google Scrapers from SerpApi.
