Skip to content
Google Flights

Return and next-leg flights

The return flights for a chosen outbound (or the next multi-city leg).

POST/v1/serp/google_flights_return
3 credits

SerpApi/SearchApi's departure_token flow: pass the departure_token of an itinerary from /v1/serp/google_flights. Prices are for the whole trip, as Google shows them. Last-leg options carry a booking_token.

Request

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

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

Body

JSON object. Unknown fields are rejected with 422.

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

    departure_token of an itinerary from /v1/serp/google_flights (or of a previous /v1/serp/google_flights_return leg of a multi-city trip). It carries the search, so nothing else is needed.

Example request

curl -X POST "https://api.scrapercompany.com/v1/serp/google_flights_return" \
  -H "x-api-key: $SCRAPERCOMPANY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "departure_token": "gf1.eNqFUMkKwjAU_Jd3TiGpVqU3TVuhBO1iIhpyEhe09NJWBfHfTRexxS2BlxneMvNygzPYBMEObJkWSYKqQOpHKo0kQbi8Cr3yn4IsD6w4A12rVMmBOtOGVSW4VQ4mNgcGwQax4Dmg7u5k6hF1x5hqPhr2Qf3w0quU29JdW9-NmCb8WbEReFMnCkFWfWMONtBj5C1db8bdq8dEFMRYzBm3AkHJhAnfC_klj0XkL04iDoW_1kttdBuPHY0OiYbbVKN9iYoM7g_hQ347"
  }'

Response

200 — Return-leg options for the chosen outbound, priced for the whole trip, each with a `booking_token`. Metered responses carry x-credits-charged and x-credits-remaining headers (see credit headers).

200 response
{
  "departure_airport": "CDG",
  "arrival_airport": "YUL",
  "departure_date": "2029-04-04",
  "currency": "USD",
  "adults": 1,
  "itineraries": [
    {
      "legs": [
        {
          "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"
        }
      ],
      "price": 527,
      "currency": "USD",
      "display_price": "$527",
      "booking_token": "gf1.eNp9T8sKwjAQ_Jc9p5BUqqU3tc0hBm0bE8WQk_hASy9tVRD_3aRVVBSzsJlhZjabK5wgIgi2EOmyKQrUNr-7tEEEaYKwK4Ne-q-m3QFGJ2C9xjgOfLh8sNaC3-zgY7_vEeyRAJ4DuvSH0o3oEjG3nAzCEMyfZXrfIjEIqvabNUQwPuR0kdCpTC6UqzwVWM24DFI1JiOuGM3kuRYqZ_OjEpliK_vo2sakiC3aFxZuSot2DjUV3O6AWl_r",
      "booking_url": "https://www.google.com/travel/flights/booking?tfs=CBwQAho_EgoyMDI2LTExLTA0Ih8KA1lVTBIKMjAyNi0xMS0wNBoDQ0RHKgJBQzIDODc0ag...",
      "carbon_emissions_kg": 413,
      "carbon_emissions_comparison": "6% higher than typical",
      "trip_type": "round_trip",
      "total_stops": 1,
      "is_direct": false,
      "google_flights_url": "https://www.google.com/travel/flights/booking?tfs=CBwQAho_EgoyMDI2LTExLTA0Ih8KA1lVTBIKMjAyNi0xMS0wNBoDQ0RHKgJBQzIDODc0ag...",
      "group": "other",
      "price_exact": 526.18,
      "carbon_emissions": {
        "this_flight": 413000,
        "typical_for_this_route": 390000,
        "difference_percent": 6
      },
      "total_duration_minutes": 835,
      "carry_on_bags_included": 1,
      "airline_logo": "https://www.gstatic.com/flights/airline_logos/70px/LX.png"
    }
  ],
  "wire_bytes": 104612,
  "elapsed_s": 0.543,
  "cheapest_price": 527,
  "trip_type": "round_trip",
  "leg_index": 1,
  "legs_total": 2,
  "itinerary_count": 16,
  "best_count": 0,
  "airlines_available": [
    {
      "code": "ONEWORLD",
      "name": "Oneworld",
      "type": "alliance"
    },
    {
      "code": "SKYTEAM",
      "name": "SkyTeam",
      "type": "alliance"
    }
  ],
  "google_flights_url": "https://www.google.com/travel/flights/search?tfs=CBwQAho_EgoyMDI2LTExLTA0Ih8KA1lVTBIKMjAyNi0xMS0wNBoDQ0RHKgJBQzIDODc0agcIARIDWVVMcgcIARIDQ0RHGh4SCjIwMjYtMTEtMTFqBwgBEgNDREdyBwgBEgNZVUxAAUgBcAGCAQsI____________AZgBAQ&hl=en&gl=us&curr=USD",
  "source": "rpc",
  "return_date": "2029-04-04"
}
Arrays are shortened to their first items.

Response fields

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

  • departure_airportstringrequired

    Origin of the leg these options are for: airport codes or Google city ids, comma-separated.

  • arrival_airportstringrequired

    Destination of the leg these options are for: airport codes or Google city ids, comma-separated.

  • departure_datestring (date)required

    Date of the leg these options are for (the return date of a round trip).

  • return_datestring (date)

    Present only for round trips (the same date as departure_date).

  • currencystringrequired

    The requested currency.

  • adultsintegerrequired
  • itinerariesarray of objectrequired

    Options for the leg being chosen: Google's best flights first, then the others.

    Show 22 child fields
    • itineraries[].legsarray of objectrequired

      The leg chosen in this call (one entry). Earlier legs are not repeated; /v1/serp/google_flights_booking returns every leg.

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

        Flights in order.

      • itineraries[].legs[].departure_airportstringrequired

        IATA code.

      • itineraries[].legs[].arrival_airportstringrequired

        IATA code.

      • itineraries[].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.

      • itineraries[].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.

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

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

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

        IATA codes of the connection airports.

      • itineraries[].legs[].is_directbooleanrequired

        stops is 0.

      • itineraries[].legs[].layoversarray of objectrequired
      • itineraries[].legs[].airlinesarray of stringrequired

        Airline names Google lists for this leg.

    • itineraries[].pricenumber | nullrequired

      Google's displayed whole amount for the whole trip (every leg, all passengers), in currency. Google rounds up (527 where the exact fare is 526.19; see price_exact). When priced_in is set, the amount is in that currency instead.

    • itineraries[].currencystringrequired

      The requested currency.

    • itineraries[].display_pricestring | nullrequired

      price with its currency symbol, e.g. $527. Null when price is null or priced_in is set.

    • itineraries[].booking_tokenstring | nullrequired

      Pass to POST /v1/serp/google_flights_booking for sellers, prices and booking links. Set only on complete itineraries (one-way options, and the options of a trip's last leg); null when departure_token is set. Compatibility: until 2026-09-30 this field held Google's raw price token on every itinerary; that value is now price_token.

    • itineraries[].booking_urlstring | nullrequired

      Google Flights booking page for the complete itinerary. Set together with booking_token.

    • itineraries[].carbon_emissions_kginteger | nullrequired

      CO2e estimate for this itinerary, kilograms (rounded). carbon_emissions has the same figure in grams.

    • itineraries[].carbon_emissions_comparisonstring | nullrequired

      e.g. 19% lower than typical or typical for this route.

    • itineraries[].trip_typestringrequired

      one_way, round_trip or multi_city.

      One ofone_wayround_tripmulti_city

    • itineraries[].total_stopsintegerrequired

      Stops across legs.

    • itineraries[].is_directbooleanrequired

      total_stops is 0.

    • itineraries[].departure_tokenstring | nullrequired

      Pass to POST /v1/serp/google_flights_return for the next leg's options after choosing this one. Set while legs remain to choose (round-trip outbound, multi-city legs before the last); null when booking_token is set. Self-contained: nothing else is needed with it.

    • itineraries[].google_flights_urlstring | nullrequired

      Google Flights page for this option: the search page with the earlier legs chosen, or the booking page once every leg is chosen.

    • itineraries[].groupstringrequired

      best (Google's top flights) or other. Every option is other when sort_by is not top_flights.

      One ofbestother

    • itineraries[].price_exactnumber | nullrequired

      Price with minor units, from Google's price token (526.19 where price is 527). Null when the token has no amount or is in another currency.

    • itineraries[].price_tokenstring | nullrequired

      Google's own opaque price token for this option, on every itinerary (returned as booking_token until 2026-09-30). Usable as an itinerary key; no endpoint takes it.

    • itineraries[].priced_instring | nullrequired

      Set only when Google priced this option in another currency than requested: that ISO 4217 code. price is then in this currency and warnings says so.

    • itineraries[].carbon_emissionsobject | nullrequired

      Null when Google gives no estimate.

      Show 3 child fields
      • itineraries[].carbon_emissions.this_flightintegerrequired

        Estimate for this itinerary, grams of CO2e.

      • itineraries[].carbon_emissions.typical_for_this_routeinteger | nullrequired

        Typical estimate for this route, grams of CO2e.

      • itineraries[].carbon_emissions.difference_percentinteger | nullrequired

        This itinerary vs typical, percent (negative = lower).

    • itineraries[].total_duration_minutesinteger | nullrequired

      Sum of the legs' door-to-door durations, minutes; null when one is unknown.

    • itineraries[].carry_on_bags_includedinteger | nullrequired

      Carry-on bags included in the fare, as Google states it; null when not stated.

    • itineraries[].checked_bags_includedinteger | nullrequired

      Checked bags included in the fare, as Google states it; null when not stated.

    • itineraries[].airline_logostring | nullrequired

      Logo URL of the main airline; null when several airlines share the itinerary.

  • wire_bytesintegerrequired

    Size of Google's response, bytes.

  • elapsed_snumberrequired

    Time Google took to answer, seconds.

  • cheapest_pricenumber | nullrequired

    Lowest price in itineraries; null when none is priced.

  • trip_typestringrequired

    one_way, round_trip or multi_city.

    One ofone_wayround_tripmulti_city

  • leg_indexintegerrequired

    Which leg these options are for: 1 = return or second multi-city leg, and so on.

  • legs_totalintegerrequired

    Legs in the trip: 1 one-way, 2 round trip, 2-5 multi-city.

  • itinerary_countintegerrequired

    Number of entries in itineraries.

  • best_countintegerrequired

    How many itineraries have group: best.

  • price_insightsobject | null

    Usually null: Google rarely gives insights for a return or later leg. Omitted when itineraries 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.

  • airlines_availablearray of objectrequired

    Airlines and alliances Google offers as filters for this search; the codes work in include_airlines.

    Show 3 child fields
    • airlines_available[].codestringrequired

      IATA airline code, or STAR_ALLIANCE / SKYTEAM / ONEWORLD.

    • airlines_available[].namestring | nullrequired
    • airlines_available[].typestringrequired

      One ofallianceairline

  • google_flights_urlstringrequired

    Google Flights search page for this trip.

  • sourcestringrequired

    Always rpc for this call.

    One ofrpchtml

  • warningsarray of stringrequired

    Notices about this answer, e.g. that Google priced some options in another currency (see each itinerary's priced_in). Empty when none.

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.