Skip to content
Google Flights

Flight booking options

Who sells the itinerary and for how much (SerpApi booking_options).

POST/v1/serp/google_flights_booking
3 credits

Airline direct and OTAs, each with price, fare name and rules, bag fees, the seller's local-currency price and Google's click-through as both a POST form (booking_request) and a GET link (booking_url). Google gathers seller prices while the request is open: expect 3-12 s.

Request

POSThttps://api.scrapercompany.com/v1/serp/google_flights_booking

Authenticate with your API key in the x-api-key header (see Authentication).

Body

JSON object. Unknown fields are rejected with 422.

  • booking_tokenstringrequiredpattern ^gf1\.[A-Za-z0-9_\-]{16,16384}$

    booking_token of a complete itinerary: a one-way result of /v1/serp/google_flights, or a return/last-leg result of /v1/serp/google_flights_return.

Example request

curl -X POST "https://api.scrapercompany.com/v1/serp/google_flights_booking" \
  -H "x-api-key: $SCRAPERCOMPANY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "booking_token": "gf1.eNp9T8sKwjAQ_Jc9p5BUqqU3tc0hBm0bE8WQk_hASy9tVRD_3aRVVBSzsJlhZjabK5wgIgi2EOmyKQrUNr-7tEEEaYKwK4Ne-q-m3QFGJ2C9xjgOfLh8sNaC3-zgY7_vEeyRAJ4DuvSH0o3oEjG3nAzCEMyfZXrfIjEIqvabNUQwPuR0kdCpTC6UqzwVWM24DFI1JiOuGM3kuRYqZ_OjEpliK_vo2sakiC3aFxZuSot2DjUV3O6AWl_r"
  }'

Response

200 — Sellers of the chosen itinerary with prices, fare rules, bag fees and click-through links. Metered responses carry x-credits-charged and x-credits-remaining headers (see credit headers).

200 response
{
  "currency": "USD",
  "trip_type": "round_trip",
  "legs": [
    {
      "segments": [
        {
          "departure_airport": "YUL",
          "arrival_airport": "CDG",
          "departure_time": "2026-11-04T18:10:00",
          "arrival_time": "2026-11-05T07:20:00",
          "airline": "Air Canada",
          "airline_code": "AC",
          "flight_number": "AC 874",
          "duration_minutes": 430,
          "aircraft": "Airbus A330",
          "cabin_class": "economy",
          "departure_airport_name": "Montréal-Pierre Elliott Trudeau International Airport",
          "arrival_airport_name": "Aéroport de Paris-Charles de Gaulle",
          "ticket_also_sold_by": [
            "LH 6809",
            "SN 9636"
          ],
          "legroom": "31 in",
          "legroom_category": "average",
          "overnight": true,
          "red_eye": false,
          "often_delayed_by_over_30_min": false,
          "carbon_emissions_kg": 325,
          "extensions": [
            "Average legroom (31 in)",
            "Wi-Fi for a fee"
          ],
          "airline_logo": "https://www.gstatic.com/flights/airline_logos/70px/AC.png"
        }
      ],
      "departure_airport": "YUL",
      "arrival_airport": "CDG",
      "duration_minutes": 430,
      "stops": 0,
      "layover_airports": [],
      "is_direct": true,
      "layovers": [],
      "airlines": [
        "Air Canada"
      ],
      "departure_time": "2026-11-04T18:10:00",
      "arrival_time": "2026-11-05T07:20:00"
    },
    {
      "segments": [
        {
          "departure_airport": "CDG",
          "arrival_airport": "ZRH",
          "departure_time": "2026-11-11T07:15:00",
          "arrival_time": "2026-11-11T08:35:00",
          "airline": "SWISS",
          "airline_code": "LX",
          "flight_number": "LX 647",
          "duration_minutes": 80,
          "aircraft": "Airbus A320",
          "cabin_class": "economy",
          "departure_airport_name": "Aéroport de Paris-Charles de Gaulle",
          "arrival_airport_name": "Zurich Airport",
          "ticket_also_sold_by": [],
          "legroom": "29 in",
          "legroom_category": "below_average",
          "overnight": false,
          "red_eye": false,
          "often_delayed_by_over_30_min": false,
          "carbon_emissions_kg": 62,
          "extensions": [
            "Below average legroom (29 in)",
            "Carbon emissions estimate: 62 kg"
          ],
          "airline_logo": "https://www.gstatic.com/flights/airline_logos/70px/LX.png"
        },
        {
          "departure_airport": "ZRH",
          "arrival_airport": "YUL",
          "departure_time": "2026-11-11T12:40:00",
          "arrival_time": "2026-11-11T15:10:00",
          "airline": "SWISS",
          "airline_code": "LX",
          "flight_number": "LX 86",
          "duration_minutes": 510,
          "aircraft": "Airbus A330",
          "cabin_class": "economy",
          "departure_airport_name": "Zurich Airport",
          "arrival_airport_name": "Montréal-Pierre Elliott Trudeau International Airport",
          "ticket_also_sold_by": [
            "AC 6821"
          ],
          "legroom": "31 in",
          "legroom_category": "average",
          "overnight": false,
          "red_eye": false,
          "often_delayed_by_over_30_min": true,
          "carbon_emissions_kg": 351,
          "extensions": [
            "Average legroom (31 in)",
            "Wi-Fi for a fee"
          ],
          "airline_logo": "https://www.gstatic.com/flights/airline_logos/70px/LX.png"
        }
      ],
      "departure_airport": "CDG",
      "arrival_airport": "YUL",
      "duration_minutes": 835,
      "stops": 1,
      "layover_airports": [
        "ZRH"
      ],
      "is_direct": false,
      "layovers": [
        {
          "duration_minutes": 245,
          "airport": "ZRH",
          "airport_name": "Zurich Airport",
          "city": "Zürich",
          "departure_airport": "ZRH",
          "change_of_airport": false,
          "overnight": false
        }
      ],
      "airlines": [
        "SWISS"
      ],
      "departure_time": "2026-11-11T07:15:00",
      "arrival_time": "2026-11-11T15:10:00"
    }
  ],
  "booking_options": [
    {
      "book_with": "SWISS",
      "seller_code": "LX",
      "is_airline": true,
      "price": 527,
      "currency": "USD",
      "display_price": "$527",
      "local_prices": [
        {
          "currency": "CAD",
          "price": 749
        }
      ],
      "marketed_as": [
        "LH 6809",
        "LX 647"
      ],
      "booking_request": {
        "url": "https://www.google.com/travel/clk/f",
        "post_data": "u=ADowPOL...&v=1"
      },
      "booking_url": "https://www.google.com/travel/clk/f?u=ADowPOL...&v=1",
      "seller_domain": "www.swiss.com/...",
      "separate_tickets": false,
      "sellers": [
        "SWISS"
      ],
      "extensions": [],
      "baggage_prices": [
        "1st checked bag: $127",
        "2nd checked bag: $183"
      ]
    },
    {
      "book_with": "Lufthansa",
      "seller_code": "LH",
      "is_airline": true,
      "price": 527,
      "currency": "USD",
      "display_price": "$527",
      "local_prices": [
        {
          "currency": "CAD",
          "price": 749
        }
      ],
      "marketed_as": [
        "LH 6809",
        "LX 647"
      ],
      "booking_request": {
        "url": "https://www.google.com/travel/clk/f",
        "post_data": "u=ADowPOL...&v=1"
      },
      "booking_url": "https://www.google.com/travel/clk/f?u=ADowPOL...&v=1",
      "seller_domain": "www.lufthansa.com/...",
      "separate_tickets": false,
      "sellers": [
        "Lufthansa"
      ],
      "extensions": [],
      "baggage_prices": [
        "1st checked bag: $127",
        "2nd checked bag: $183"
      ]
    }
  ],
  "option_count": 9,
  "cheapest_price": 527,
  "price_insights": {
    "lowest_price": 527,
    "price_level": "typical",
    "typical_price_range": [
      495,
      880
    ],
    "price_history": [
      [
        1790568000,
        529
      ],
      [
        1790654400,
        528
      ]
    ]
  },
  "google_flights_url": "https://www.google.com/travel/flights/booking?tfs=CBwQAho_EgoyMDI2LTExLTA0Ih8KA1lVTBIKMjAyNi0xMS0wNBoDQ0RHKgJBQzIDODc0ag...",
  "wire_bytes": 79626,
  "elapsed_s": 6.247
}
Arrays are shortened to their first items.

Response fields

Fields marked required are always present; others appear when they apply.

  • currencystringrequired

    Currency of the original search.

  • trip_typestringrequired

    one_way, round_trip or multi_city.

    One ofone_wayround_tripmulti_city

  • legsarray of objectrequired

    Every leg of the chosen itinerary, in order.

    Show 11 child fields
    • legs[].segmentsarray of objectrequired

      Flights in order.

      Show 22 child fields
      • legs[].segments[].departure_airportstringrequired

        IATA code.

      • legs[].segments[].arrival_airportstringrequired

        IATA code.

      • legs[].segments[].departure_timestring | nullrequired

        Airport-local wall-clock time as Google shows it, ISO 8601 without a UTC offset, e.g. 2026-11-04T18:10:00. Null when unknown.

      • legs[].segments[].arrival_timestring | nullrequired

        Airport-local wall-clock time as Google shows it, ISO 8601 without a UTC offset, e.g. 2026-11-04T18:10:00. Null when unknown.

      • legs[].segments[].airlinestringrequired

        Marketing airline name (empty string when Google gives none).

      • legs[].segments[].airline_codestring | nullrequired

        IATA code of the marketing airline.

      • legs[].segments[].flight_numberstring | nullrequired

        Marketing carrier and number, e.g. AC 874.

      • legs[].segments[].duration_minutesinteger | nullrequired

        Flight time, minutes.

      • legs[].segments[].aircraftstring | nullrequired

        e.g. Airbus A330.

      • legs[].segments[].cabin_classstring | nullrequired

        One ofeconomypremium_economybusinessfirst

      • legs[].segments[].departure_airport_namestring | nullrequired
      • legs[].segments[].arrival_airport_namestring | nullrequired
      • legs[].segments[].operated_bystring | nullrequired

        The airline actually flying it when Google names one other than the marketing carrier, e.g. Endeavor Air DBA Delta Connection.

      • legs[].segments[].ticket_also_sold_byarray of stringrequired

        Codeshare flight numbers the same flight is also sold under, e.g. LH 6809.

      • legs[].segments[].legroomstring | nullrequired

        Seat pitch as Google shows it, e.g. 31 in.

      • legs[].segments[].legroom_categorystring | nullrequired

        One ofaveragebelow_averageabove_average

      • legs[].segments[].overnightbooleanrequired

        Lands on a later calendar day than it departs (local times).

      • legs[].segments[].red_eyebooleanrequired

        Heuristic: departs 20:00-02:59 and lands 04:00-10:59 after the night (local times). overnight is exact; this is not.

      • legs[].segments[].often_delayed_by_over_30_minbooleanrequired

        Google's flag that this flight is often delayed by more than 30 minutes.

      • legs[].segments[].carbon_emissions_kginteger | nullrequired

        CO2e estimate for this flight, kilograms (rounded).

      • legs[].segments[].extensionsarray of stringrequired

        Google's amenity lines, e.g. Average legroom (31 in), Free Wi-Fi, Wi-Fi for a fee, In-seat power & USB outlets, Live TV, On-demand video, Stream media to your device, Carbon emissions estimate: 325 kg.

      • legs[].segments[].airline_logostring | nullrequired

        Logo URL of the marketing airline.

    • legs[].departure_airportstringrequired

      IATA code.

    • legs[].arrival_airportstringrequired

      IATA code.

    • legs[].departure_timestring

      Airport-local wall-clock time as Google shows it, ISO 8601 without a UTC offset, e.g. 2026-11-04T18:10:00. Present only when known.

    • legs[].arrival_timestring

      Airport-local wall-clock time as Google shows it, ISO 8601 without a UTC offset, e.g. 2026-11-04T18:10:00. Present only when known.

    • legs[].duration_minutesinteger | nullrequired

      Door-to-door travel time including layovers, minutes.

    • legs[].stopsintegerrequired
    • legs[].layover_airportsarray of stringrequired

      IATA codes of the connection airports.

    • legs[].is_directbooleanrequired

      stops is 0.

    • legs[].layoversarray of objectrequired
      Show 7 child fields
      • legs[].layovers[].duration_minutesinteger | nullrequired

        Connection time, minutes.

      • legs[].layovers[].airportstringrequired

        IATA code of the airport the traveller lands at.

      • legs[].layovers[].airport_namestring | nullrequired
      • legs[].layovers[].citystring | nullrequired
      • legs[].layovers[].departure_airportstringrequired

        Airport the next flight leaves from; equals airport unless the connection changes airports.

      • legs[].layovers[].change_of_airportbooleanrequired

        The next flight leaves from a different airport.

      • legs[].layovers[].overnightbooleanrequired

        The next flight leaves on a later calendar day than the previous one lands.

    • legs[].airlinesarray of stringrequired

      Airline names Google lists for this leg.

  • booking_optionsarray of objectrequired

    Airline-direct and online travel agency sellers.

    Show 17 child fields
    • booking_options[].book_withstringrequired

      Seller name; several sellers are joined with and when the option is separate tickets.

    • booking_options[].seller_codestring | nullrequired

      Google's code for the (first) seller: the IATA code for an airline, e.g. LX.

    • booking_options[].is_airlinebooleanrequired

      Every seller is an airline (airline direct).

    • booking_options[].pricenumber | nullrequired

      This seller's price for the whole trip, in currency, as Google shows it.

    • booking_options[].currencystringrequired

      Currency of the original search.

    • booking_options[].display_pricestring | nullrequired

      price with its currency symbol, e.g. $527.

    • booking_options[].local_pricesarray of objectrequired

      The seller's own price when it charges in another currency, e.g. CAD 749.

      Show 2 child fields
      • booking_options[].local_prices[].currencystringrequired
      • booking_options[].local_prices[].pricenumberrequired
    • booking_options[].marketed_asarray of stringrequired

      Flight numbers this seller sells the itinerary under, e.g. LX 647.

    • booking_options[].booking_requestobject | nullrequired

      Google's click-through as a form (SerpApi's shape): POST post_data as application/x-www-form-urlencoded to url. Null when the seller has no link (e.g. call to book).

      Show 2 child fields
      • booking_options[].booking_request.urlstringrequired

        Google's click-through URL.

      • booking_options[].booking_request.post_datastringrequired

        URL-encoded form body.

    • booking_options[].booking_urlstring | nullrequired

      The same click-through as a GET link; Google answers it with a redirect to the seller's page. Null when booking_request is.

    • booking_options[].seller_domainstring | nullrequired

      The seller's site as Google shows it, e.g. www.swiss.com/....

    • booking_options[].booking_phonestring | nullrequired

      Phone number of a call-to-book seller (which has no link).

    • booking_options[].separate_ticketsbooleanrequired

      The option is several tickets bought from different sellers (see sellers).

    • booking_options[].sellersarray of stringrequired

      Every seller of this option.

    • booking_options[].option_titlestring | nullrequired

      Fare family when Google names one, e.g. Delta Main Basic.

    • booking_options[].extensionsarray of stringrequired

      Fare rules Google lists, e.g. No refunds, Free seat selection, Ticket changes for a fee. Mostly shown for airline-direct sellers.

    • booking_options[].baggage_pricesarray of stringrequired

      Bag fees as Google words them, e.g. 1st checked bag: $45, 1 free carry-on.

  • option_countintegerrequired

    Number of entries in booking_options.

  • cheapest_pricenumber | nullrequired

    Lowest price in booking_options; null when none is priced.

  • price_insightsobject | null

    Null when Google gives none. Omitted when booking_options is empty; that answer is not billed.

    Show 4 child fields
    • price_insights.lowest_pricenumber | nullrequired

      Lowest price Google shows for this search, in currency.

    • price_insights.price_levelstring | nullrequired

      Google's verdict on today's price: low (below its typical range), typical (inside it) or high (above it).

      One oflowtypicalhigh

    • price_insights.typical_price_rangearray of number | nullrequiredmin items 2, max items 2

      [low, high]: Google's typical price range for this trip.

    • price_insights.price_historyarray of array of numberrequired

      [[unix_seconds, price], ...]: Google's price history for this trip, about 60 days. Empty when Google gives none.

  • google_flights_urlstringrequired

    Google Flights booking page for this itinerary.

  • wire_bytesintegerrequired

    Size of Google's response, bytes.

  • elapsed_snumberrequired

    Time Google took to answer, seconds (typically 3-12 s: Google checks seller prices while the request is open).

Errors

Errors return a JSON body with a detail field. Failed requests are not charged. See Errors for the full list and retry advice.

StatusMeaningRetry?
401Unauthorized

Missing or invalid API key.

{"detail":"missing or invalid API key"}
No, fix the request
402Payment Required

Not enough credits for this request. Only returned once credit enforcement is switched on; during the beta metering runs in shadow mode and never blocks.

{"detail":"insufficient credits: this request costs 5, 0 available. Credits renew 2026-11-01."}
No, fix the request
422Unprocessable Content

Request validation failed. detail is a list of problems for schema errors, or a string for semantic checks performed by the endpoint.

{"detail":[{"loc":["body","name"],"msg":"Field required","type":"missing"}]}
No, fix the request
429Too Many Requests

Too many requests: the key's requests-per-minute limit was exceeded, or (once credit enforcement is on) the plan's concurrent-request limit. No rate-limit or Retry-After headers are sent; back off and retry.

{"detail":"rate limit 60/min exceeded"}
Yes, with backoff
502Bad Gateway

The upstream source failed, blocked the request or returned an unusable answer. Safe to retry later; failed requests are not charged.

{"detail":"RuntimeError"}
Yes, with backoff

Try it

  1. Export your key: export SCRAPERCOMPANY_API_KEY=sk_... (no key yet? request access).
  2. Copy the cURL example above and run it in a terminal.
  3. Or open the interactive playground on api.scrapercompany.com, paste your key and pick this endpoint.

Credits

3 credits per successful call. Failed, blocked and empty results are free. Credit metering is in beta and does not block requests yet.