Skip to content

Round-Trip Flight API

A round trip is one search, not two

POST both dates and get paired itineraries, outbound and return already matched, with a combined price, duration, and one booking link.

  • total_price · total_duration_seconds · total_stops on every itinerary
  • Per-leg controls: stops, carriers, and time windows set separately for out and back
  • "Empty" and "failed" stay distinguishable even across the return-leg fan-out, see search status

Free tier on RapidAPI. No card to try.

POST /api/google_flights/roundtrip/v1
captured run · 2026-08-26
{
  "from_airport": "BER",
  "to_airport": "CDG",
  "departure_date": "2026-10-06",
  "return_date": "2026-10-13",
  "limit": 5,
  "currency": "usd"
}
Replays the captured request: free, no account, nobody's quota.

The same capture, rendered

A real week in Paris, $112, marked low

Berlin→Paris with both legs paired. The cheapest captured itinerary sits below Google's own band for the route, so it arrives wearing the verdict.

BER→CDG · 2026-10-062026-10-13

captured run · 2026-08-26

Google's price band. Cheapest paired itinerary: $112

$120 low$220 high
$112lownonstop both waysbuy_link →
OUTeasy | Jet · 1 hr 50 min · 5:05 PM on Tue, Oct 6RETeasy | Jet · 1 hr 45 min · 8:50 AM on Tue, Oct 13
$113lownonstop both waysbuy_link →
OUTeasy | Jet · 1 hr 50 min · 6:15 AM on Tue, Oct 6RETeasy | Jet · 1 hr 45 min · 8:50 AM on Tue, Oct 13
$116lownonstop both waysbuy_link →
OUTAir France · 1 hr 50 min · 6:25 PM on Tue, Oct 6RETAir France · 1 hr 45 min · 7:10 AM on Tue, Oct 13
$116lownonstop both waysbuy_link →
OUTAir France · 1 hr 50 min · 7:55 PM on Tue, Oct 6RETAir France · 1 hr 45 min · 7:10 AM on Tue, Oct 13
$124lownonstop both waysbuy_link →
OUTAir France · 1 hr 50 min · 3:10 PM on Tue, Oct 6RETAir France · 1 hr 45 min · 7:10 AM on Tue, Oct 13

Each row is one object from the response. The low badge is price_range_in_relation_to_other_periods rendered directly, Google's own call that $112 is under the usual $120–$220 range for these dates.

Response shape

One object per itinerary

No leg-matching on your side: the pairing, the totals, and the single booking link are the endpoint's job.

total_price / total_price_as_numberstring · number

The combined fare for the paired itinerary, $112 in the capture, as a display string and a sortable number. Not the sum of two separately-priced one-ways.

total_duration_secondsnumber

Both legs' flying time combined, in seconds.

total_stopsint

Stops across both legs: 0 means nonstop in each direction.

buy_linkstring

One Google Flights deep link for the whole paired itinerary, both legs, in the requested currency.

departure_flight_*fields

The outbound leg in full: departure_flight_airline, departure_flight_duration, departure_flight_stops, plain-text departure and arrival descriptions, and departure_stops_info per layover.

return_flight_*fields

The return leg, same structure, already matched to that exact outbound.

price_insights_low / high + verdictnumber · string | null

Google's band and low | typical | high verdict for the route and date pair, same as one-way. Null when Google doesn't publish a band.

Request

Every one-way control, twice

Four required fields; then each leg takes its own constraints, the part two stapled one-way searches cannot express.

Required

departure_date / return_datestring

Both travel dates, YYYY-MM-DD.

from_airport / to_airportstring

IATA codes.

Optional · per leg

max_departure_stops / max_return_stopsint

Stop limits per leg: nonstop out, one stop back is one request.

departure_airline_codes / return_airline_codesstring[]

Carrier restrictions per leg, with departure_exclude_airline_codes and return_exclude_airline_codes to remove carriers instead.

departure_departure_time_min / _maxint 0–23

Outbound departure-hour window, with departure_arrival_time_min / _max for its arrival.

return_departure_time_min / _maxint 0–23

The same pair of windows for the return leg.

Optional · shared

sort_type · currency · max_price · seat_type · passengers · limit · strict · use_ext_proxy

Exactly as on one-way, applied to the paired search as a whole.

The honest comparison

Paired search vs. two one-ways, stapled

Stapling two one-way calls together is the workaround most flight APIs leave you with. Here is what it actually costs.

Two one-way calls

  • Two requests billed per date pair, so a flexible-date round-trip scan costs double.
  • No combined total: you add two fares that may not be purchasable as one ticket at that price.
  • Leg combinations are yours to cross-match, filter, and de-duplicate.
  • Two separate booking links that never open a single round-trip purchase.

POST /roundtrip

  • One request, one billed search, however many outbound candidates it prices.
  • total_price is the itinerary priced as one purchase.
  • Legs arrive pre-paired, with per-leg filters applied inside the search.
  • One buy_link that reopens the exact paired itinerary.

The hard part, handled

Honest empty-vs-failed reporting is harder on round-trips than it sounds: a round-trip prices a return leg for every outbound candidate, and each of those fetches can fail on its own. empty is only reported when every candidate was attempted and every one read a real Google Flights page saying it had nothing. A fan-out that was blocked, or that stopped on the request's time ceiling, reports degraded or partial, never "no flights". The search-status page documents the full contract.

Pricing

Round-trip search on every plan

PlanPrice / moRequests$ / 1k reqOverageRate limit
BASICFree10 / mohard capGet this plan →
PRO$102,500 / mo$4.00$0.003 / req150 / minGet this plan →
ULTRArecommended$2510,000 / mo$2.50$0.003 / req250 / minGet this plan →
MEGA$5050,000 / mo$1.00$0.001 / req500 / minGet this plan →

Every plan includes every endpoint. You only choose volume and rate limit. Read from the live listing on 2026-08-26; the listing is authoritative.

Questions, answered plainly

Does the API return round-trip prices as one itinerary?
Yes. POST /roundtrip returns one flat JSON object per itinerary with total_price, total_price_as_number, total_duration_seconds, total_stops, and both legs’ details already paired under departure_flight_* and return_flight_* fields.
Can I set different filters for the outbound and return legs?
Yes. Every one-way filter exists per leg: max_departure_stops and max_return_stops, departure_airline_codes and return_airline_codes (with exclude variants), and separate departure/arrival time windows for each leg. Nonstop out, one stop back with a morning return is a single request.
Why not just make two one-way calls?
Two one-way searches cost two requests per date pair, give you no combined total, and price legs independently. The sum of two one-way fares is not the fare of a round-trip ticket. The paired endpoint prices the itinerary as one purchase and ships one buy_link for it.
Is buy_link for the whole round trip?
Yes. One combined Google Flights deep link that reopens the exact paired itinerary, both legs, ready to book as one ticket.
What does an empty round-trip response mean?
Check X-Search-Status before deciding. A round-trip prices a return leg for every outbound candidate, and each of those fetches can fail on its own, so "empty" is only reported when every candidate read a real Google Flights page saying it had nothing. A blocked or truncated fan-out reports "degraded" or "partial", never "no flights".
Do the price-insights fields work on round-trips?
Yes. Each itinerary carries price_insights_low, price_insights_high, and the low | typical | high verdict for the route and date pair. The captured $112 BER→CDG itinerary on this page came back marked "low" against a $120–$220 band.
How many requests does a round-trip search cost?
One. The return-leg fan-out happens inside the API: a whole paired search, however many outbound candidates it prices, bills as a single request.

Stop stapling one-ways together

Paired itineraries with combined totals, per-leg filters, and one booking link, in a single request.

Free tier: 10 requests/month. No card to try.