Google Flights API
Scrape Google Flights for fares, durations, layovers, airlines, and carbon emissions as structured JSON
The Google Flights API is a specialized plugin that searches Google's flight feed and returns the same fare list, durations, layovers, airlines, and emissions that Google shows in the Flights UI, as clean JSON. No JavaScript rendering, no headless browsers, no booking-flow scraping. One HTTP call returns up to 30 itineraries plus aggregate price insights and full airport metadata.
Credit Usage: Each successful request costs 10 credits. For bulk processing, use the Async API with plugins.
Key Features
- Structured JSON Output: Each itinerary returns
flights[](per-segment),layovers[],total_duration,price,carbon_emissions,airline_logo, and abooking_token. - Round Trip, One Way, Multi-Origin: Round trips with
return_date, one-way searches by default, and multi-airport origin/destination via comma-separated IATA codes (departure_id=JFK,LGA,EWR). - Price Insights: Every response includes
price_insightswithlowest_price,price_level(low / typical / high),typical_price_range, and a sparseprice_historytime series. - Carbon Emissions: Per-itinerary
carbon_emissionsblock withthis_flight,typical_for_this_route, anddifference_percentso you can prioritize lower-emission options. - Sort Modes:
sort_bycontrols top, price, departure, arrival, duration, or emissions ordering. Six modes in total. - Cabin & Stop Filters:
travel_class(economy / premium / business / first),stops(any / nonstop / ≤1 / ≤2),include_airlines/exclude_airlinesby IATA code. - Localization:
hl,gl, andcurrencyfor full regional pricing (EUR, GBP, JPY, TRY, etc). - No Blocks or CAPTCHAs: All anti-bot measures are handled automatically by Scrape.do.
Endpoint
GET https://api.scrape.do/plugin/google/flightsRequest Parameters
Required
| Parameter | Type | Description |
|---|---|---|
token | string | Your Scrape.do API authentication token |
departure_id | string | Origin IATA code (e.g. JFK). Comma-separated allowed for multi-airport origin (e.g. JFK,LGA,EWR) |
arrival_id | string | Destination IATA code. Same multi-airport rules as departure_id |
outbound_date | string | Departure date in YYYY-MM-DD format. Must be today or a future date; past dates return 400 |
Trip Type
| Parameter | Type | Default | Description |
|---|---|---|---|
type | integer | auto | 1 = round trip (requires return_date), 2 = one way, 3 = multi-city. Auto-inferred from return_date |
return_date | string | — | Return date in YYYY-MM-DD format. Required when type=1; must be today or later and on or after outbound_date |
Multi-city (type=3) is not yet supported. The endpoint returns 400 if requested. Contact support if you need it.
Passengers
| Parameter | Type | Default | Description |
|---|---|---|---|
adults | integer | 1 | 1–9 |
children | integer | 0 | 0–9 |
infants_in_seat | integer | 0 | 0–4 |
infants_on_lap | integer | 0 | 0–4 |
Cabin & Filters
| Parameter | Type | Default | Description |
|---|---|---|---|
travel_class | integer | 1 | 1 = economy, 2 = premium economy, 3 = business, 4 = first |
stops | integer | 0 | 0 = any, 1 = nonstop, 2 = ≤1 stop, 3 = ≤2 stops |
sort_by | integer | 1 | 1 = top, 2 = price, 3 = departure, 4 = arrival, 5 = duration, 6 = emissions |
include_airlines | string | — | Comma-separated IATA airline codes (DL,B6,AA). Mutually exclusive with exclude_airlines |
exclude_airlines | string | — | Comma-separated IATA airline codes |
Not yet supported: max_price, max_duration, bags. Sending them returns 400 so callers notice rather than silently filtering nothing.
Localization
| Parameter | Type | Default | Description |
|---|---|---|---|
hl | string | en | Language code |
gl | string | us | Country code |
currency | string | USD | Currency code (e.g. EUR, GBP, JPY, TRY) |
Example Usage
Simple One-Way
curl --location --request GET 'https://api.scrape.do/plugin/google/flights?token=<SDO-token>&departure_id=JFK&arrival_id=LAX&outbound_date=2026-06-15'import requests
import json
token = "<SDO-token>"
url = f"https://api.scrape.do/plugin/google/flights?token={token}&departure_id=JFK&arrival_id=LAX&outbound_date=2026-06-15"
response = requests.request("GET", url)
print(json.dumps(response.json(), indent=2))const axios = require('axios');
const token = "<SDO-token>";
const url = `https://api.scrape.do/plugin/google/flights?token=${token}&departure_id=JFK&arrival_id=LAX&outbound_date=2026-06-15`;
axios.get(url)
.then(response => {
console.log(JSON.stringify(response.data, null, 2));
})
.catch(error => {
console.error(error);
});package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
token := "<SDO-token>"
url := fmt.Sprintf(
"https://api.scrape.do/plugin/google/flights?token=%s&departure_id=JFK&arrival_id=LAX&outbound_date=2026-06-15",
token,
)
resp, err := http.Get(url)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}require 'net/http'
require 'json'
token = "<SDO-token>"
url = URI("https://api.scrape.do/plugin/google/flights?token=#{token}&departure_id=JFK&arrival_id=LAX&outbound_date=2026-06-15")
response = Net::HTTP.get(url)
puts JSON.pretty_generate(JSON.parse(response))import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class GoogleFlights {
public static void main(String[] args) throws Exception {
String token = "<SDO-token>";
String url = String.format(
"https://api.scrape.do/plugin/google/flights?token=%s&departure_id=JFK&arrival_id=LAX&outbound_date=2026-06-15",
token
);
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setRequestMethod("GET");
BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream())
);
String line;
StringBuilder response = new StringBuilder();
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
System.out.println(response.toString());
}
}using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
string token = "<SDO-token>";
string url = $"https://api.scrape.do/plugin/google/flights?token={token}&departure_id=JFK&arrival_id=LAX&outbound_date=2026-06-15";
using HttpClient client = new HttpClient();
string response = await client.GetStringAsync(url);
Console.WriteLine(response);
}
}<?php
$token = "<SDO-token>";
$url = "https://api.scrape.do/plugin/google/flights?token={$token}&departure_id=JFK&arrival_id=LAX&outbound_date=2026-06-15";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo json_encode(json_decode($response), JSON_PRETTY_PRINT);
?>curl "https://api.scrape.do/plugin/google/flights?departure_id=JFK&arrival_id=LAX&outbound_date=2026-12-15&token=$TOKEN"Round Trip, Two Adults, Business Class, EUR
curl "https://api.scrape.do/plugin/google/flights?departure_id=IST&arrival_id=LHR&outbound_date=2026-12-01&return_date=2026-12-15&adults=2&travel_class=3¤cy=EUR&gl=gb&token=$TOKEN"Nonstop, Cheapest First
curl "https://api.scrape.do/plugin/google/flights?departure_id=SFO&arrival_id=NRT&outbound_date=2026-12-10&stops=1&sort_by=2&token=$TOKEN"Multi-Airport Origin (NYC)
curl "https://api.scrape.do/plugin/google/flights?departure_id=JFK,LGA,EWR&arrival_id=LAX&outbound_date=2026-12-15&token=$TOKEN"Filter by Airlines
curl "https://api.scrape.do/plugin/google/flights?departure_id=JFK&arrival_id=LAX&outbound_date=2026-12-15&include_airlines=DL,B6&token=$TOKEN"Lowest Carbon Emissions First
curl "https://api.scrape.do/plugin/google/flights?departure_id=JFK&arrival_id=LAX&outbound_date=2026-12-15&sort_by=6&token=$TOKEN"Response
Top-Level Structure
{
"search_parameters": { ... },
"best_flights": [ ... ],
"other_flights": [ ... ],
"price_insights": { ... },
"airports": [ ... ]
}search_parameters
Echo of the request parameters, with engine: "google_flights", type, departure_id, arrival_id, outbound_date, adults, currency, gl, hl always present. Optional fields appear when set.
best_flights[] and other_flights[]
Each entry is an Itinerary object:
{
"flights": [
{
"departure_airport": { "name": "John F. Kennedy International Airport", "id": "JFK", "time": "2026-06-15 08:29" },
"arrival_airport": { "name": "Los Angeles International Airport", "id": "LAX", "time": "2026-06-15 11:25" },
"duration": 356,
"airplane": "Airbus A320",
"airline": "JetBlue",
"airline_logo": "https://www.gstatic.com/flights/airline_logos/70px/B6.png",
"travel_class": "Economy",
"flight_number": "B6 323",
"legroom": "32 inches",
"extensions": ["Wi-Fi for a fee", "In-seat power"],
"overnight": false
}
],
"layovers": [
{ "duration": 65, "name": "Denver International Airport", "id": "DEN" }
],
"total_duration": 421,
"carbon_emissions": {
"this_flight": 405000,
"typical_for_this_route": 316000,
"difference_percent": 28
},
"price": 149,
"type": "One way",
"airline_logo": "https://www.gstatic.com/flights/airline_logos/70px/B6.png",
"booking_token": "CjRIVVBMZHNBZEpBRDhBQmN1QndCRy0..."
}Itinerary Fields
| Field | Type | Description |
|---|---|---|
flights[] | array | Per-segment details, one entry per leg |
flights[].departure_airport | object | { name, id, time }. time format YYYY-MM-DD HH:MM |
flights[].arrival_airport | object | Same shape as departure |
flights[].duration | integer | Segment duration in minutes |
flights[].airplane | string | Aircraft type when available |
flights[].airline | string | Operating airline name |
flights[].airline_logo | string | https://www.gstatic.com/flights/airline_logos/70px/<CODE>.png |
flights[].travel_class | string | "Economy" / "Premium economy" / "Business" / "First" |
flights[].flight_number | string | IATA code + flight number (e.g. B6 323) |
flights[].legroom | string | Human-readable legroom |
flights[].extensions | string[] | Amenity strings ("Wi-Fi for a fee", "In-seat power", …) |
flights[].overnight | bool | true when the segment crosses midnight |
layovers[] | array | Stops between segments |
layovers[].duration | integer | Layover duration in minutes |
layovers[].name / .id | string | Layover airport |
total_duration | integer | End-to-end duration in minutes, including layovers |
carbon_emissions | object | { this_flight, typical_for_this_route, difference_percent } in grams |
price | integer | Total price in the requested currency. Sub-unit precision is dropped |
type | string | "One way" or "Round trip" |
airline_logo | string | Representative logo for the itinerary |
booking_token | string | Opaque token identifying the upstream booking page |
departure_token | string | Per-flight short token, when Google emits one |
carbon_emissions.difference_percent may be negative when a flight emits less than the route average. this_flight and typical_for_this_route are in grams.
price_insights
{
"lowest_price": 149,
"price_level": "typical",
"typical_price_range": [90, 205],
"price_history": [
[1771218000000, 169],
[1771304400000, 169]
]
}| Field | Type | Description |
|---|---|---|
lowest_price | integer | Cheapest fare in the response |
price_level | string | "low", "typical", or "high" per Google's classification |
typical_price_range | int[2] | [low, high] for this route |
price_history | array | [unix_ms, price] pairs. Empty when Google doesn't ship a history |
airports
Top-level airport reference list. One entry per search (usually a single object containing departure[] and arrival[]).
[
{
"departure": [
{
"id": "JFK",
"name": "John F. Kennedy International Airport",
"city": "New York",
"country": "United States",
"country_code": "US",
"latitude": 40.6397,
"longitude": -73.7789,
"images": []
}
],
"arrival": [ { "id": "LAX", "name": "Los Angeles International Airport", "city": "Los Angeles", "country": "United States", "country_code": "US", "latitude": 33.9425, "longitude": -118.4081, "images": [] } ]
}
]Schema note: each departure[] / arrival[] entry includes the airport id, name, city, country, coordinates, and an images array at the same level.
Sort Modes (sort_by)
| Value | Meaning |
|---|---|
1 (default) | Top. Google's default ranking |
2 | Price ascending |
3 | Departure time ascending |
4 | Arrival time ascending |
5 | Total duration ascending |
6 | Carbon emissions ascending |
# Lowest emissions first
curl "https://api.scrape.do/plugin/google/flights?departure_id=JFK&arrival_id=LAX&outbound_date=2026-12-15&sort_by=6&token=$TOKEN"With the default sort_by=1, Google returns ranked best_flights plus other_flights. With any other sort mode (2–6), Google returns one ordered list under other_flights, and best_flights is empty.
Stop Filters (stops)
| Value | Meaning |
|---|---|
0 (default) | Any |
1 | Nonstop only |
2 | At most 1 stop |
3 | At most 2 stops |
Notes
- Cabin class changes fares.
travel_class=3ortravel_class=4returns business or first-class cabin pricing inbest_flights/other_flights, not economy prices with a label change. - Dates must be today or in the future. Past
outbound_dateorreturn_datevalues are rejected with400, andreturn_datemust be on or afteroutbound_date. If a date near today is rejected because of timezone differences, move it forward a day. - Listing data only.
booking_tokento fare detail / baggage / seat map expansion is not yet exposed. - Prices are integer units in the requested currency; sub-unit precision is dropped.
- Live prices drift. Fares can change between requests; expect small variance on repeated calls.
- Airline logos are synthesised from the IATA code and may 404 for obscure carriers.
- Multi-city (
type=3) returns400until support lands.
Error Handling
{ "error": "Human readable error message" }Common Error Codes
| Status | Error | Description |
|---|---|---|
400 | token is required | Missing authentication token |
400 | departure_id is required (IATA or comma-separated IATAs) | Missing origin |
400 | arrival_id is required (IATA or comma-separated IATAs) | Missing destination |
400 | outbound_date is required (format: YYYY-MM-DD) | Missing or malformed outbound date |
400 | return_date is required for round-trip (format: YYYY-MM-DD) | type=1 without return_date |
400 | outbound_date is in the past; Google Flights only supports today or future dates | outbound_date is a past date |
400 | return_date is in the past; Google Flights only supports today or future dates | return_date is a past date |
400 | return_date must be on or after outbound_date | return_date is earlier than outbound_date |
400 | multi-city (type=3) is not yet supported — use one-way or round-trip | type=3 requested |
400 | type must be 1 (round-trip), 2 (one-way), or 3 (multi-city) | Invalid type |
400 | travel_class must be 1 (economy), 2 (premium economy), 3 (business), or 4 (first) | Invalid travel_class |
400 | stops must be 0 (any), 1 (nonstop), 2 (≤1), or 3 (≤2) | Invalid stops |
400 | sort_by must be 1-6 (1=top, 2=price, 3=dep, 4=arr, 5=duration, 6=emissions) | Invalid sort_by |
400 | include_airlines and exclude_airlines are mutually exclusive | Both supplied |
400 | max_price is not yet supported | max_price, max_duration, or bags passed |
400 | invalid search parameters | Google rejected the search, such as an unknown IATA code or a date it considers in the past |
502 | request failed | Transient upstream failure. Retry |
502 | unexpected response | Non-200 from Google. Retry |
502 | upstream error | Temporary upstream error. Retry |
500 | parse failed | Response parsing error |

