Skip to content

Google Flights data, with the price band attached.

Two endpoints over live Google Flights results. Every itinerary comes back with Google’s historical price range, its verdict on today’s fare, and a deep link that reopens exactly that itinerary.

one-way
POST https://api.flightpowers.com/v1/flights/oneway
x-api-key: <your RapidAPI key>
content-type: application/json

{
  "from_airport": "JFK",
  "to_airport": "LHR",
  "departure_date": "2026-09-22",
  "max_stops": 0,
  "currency": "usd",
  "limit": 5
}

The flagship field

price_insights_low, price_insights_high, and a verdict.

Google Flights shows travellers a historical price range and tells them whether the current fare sits low, typical or high within it. Those three values come back on every result row.

every result row carries
{
  "price_insights_low": 65,
  "price_insights_high": 135,
  "price_range_in_relation_to_other_periods": "low",
  "price": "$56",
  "price_as_number": 56
}

price_insights_low and price_insights_high are integers in the currency you requested, taken from the price-history data on the Google Flights page the search loads.

price_range_in_relation_to_other_periods is Google’s own label for the current fare — "low", "typical" or "high".

Handle the null case
Google does not publish a band for every search. When it is absent these fields come back null. Do not make them required in your schema, and do not build a UI that has nothing to show without them.

POST /v1/flights/roundtrip

A round trip is one search, not two.

The endpoint runs a genuine paired-leg search: the outbound leg it selects drives a filtered query for the matching return. You get a combined price and a single buy_link for an itinerary that can be bought as one ticket.

per-leg filtering
POST https://api.flightpowers.com/v1/flights/roundtrip

{
  "from_airport": "JFK",
  "to_airport": "LHR",
  "departure_date": "2026-09-22",
  "return_date": "2026-09-29",
  "max_departure_stops": 0,
  "max_return_stops": 1,
  "departure_airline_codes": ["BA"],
  "return_departure_time_min": 10,
  "limit": 5
}

Each leg takes its own constraints, which is the part two stapled one-way searches cannot express:

max_departure_stops / max_return_stopsint

Stop limits set independently per leg — non-stop out, one stop back.

departure_airline_codes / return_airline_codesstring[]

Restrict each leg to particular carriers. Matching exclude_ variants exist for both legs.

departure_departure_time_min / _maxint

Departure and arrival time windows, set separately for the outbound and return legs.

total_pricestring

The combined price for the paired itinerary, returned on the result.

POST /v1/flights/oneway

Request fields

Required

from_airportstring

Origin IATA code.

to_airportstring

Destination IATA code.

departure_datestring

YYYY-MM-DD.

Optional

max_stopsint

Maximum stops per itinerary.

airline_codes / exclude_airline_codesstring[]

Include or exclude specific carriers.

departure_time_min / _max, arrival_time_min / _maxint

Hour-of-day windows.

currencystring

Defaults to usd.

max_priceint

Upper bound on fare.

passengersint[]

Passenger breakdown.

limitint

Number of itineraries returned. Defaults to 10.

strictbool

When the search fails to complete, return 503 instead of an empty array. Available on the RapidAPI host.

Rate limits

Scanning a month of dates.

Cheapest-date and fare-alert products are date scans, and a date scan is bounded by requests per minute. Pro allows 150 per minute, Ultra 250, Mega 500 — as listed on RapidAPI on 2026-08-25.

python
# One month of departure dates, scanned in parallel.
# Each date is one request; keep concurrency under your plan's per-minute limit.
import asyncio, httpx, datetime as dt

KEY = os.environ["RAPIDAPI_KEY"]          # server-side only
DATES = [dt.date(2026, 9, 1) + dt.timedelta(days=i) for i in range(30)]

async def fare(client, day):
    r = await client.post(
        "https://api.flightpowers.com/v1/flights/oneway",
        headers={"x-api-key": KEY},
        json={"from_airport": "JFK", "to_airport": "LHR",
              "departure_date": day.isoformat(), "limit": 1},
        timeout=180,
    )
    rows = r.json()
    return day, (rows[0]["price_as_number"] if rows else None)

async def main():
    limits = httpx.Limits(max_connections=20)
    async with httpx.AsyncClient(limits=limits) as client:
        return await asyncio.gather(*(fare(client, d) for d in DATES))

Thirty dates is thirty billed requests. Keep your client’s connection limit under your plan’s per-minute figure; a 429 is returned to you unchanged and is never retried, so an exhausted quota is never double-billed.

Pricing

Plans on RapidAPI

PlanPer monthRequestsRate limitBeyond quota
Basic$010 / monthhard stop
Pro$102,500 / month150 / minute$0.003 per extra request
Ultrarecommended$2510,000 / month250 / minute$0.003 per extra request
Mega$5050,000 / month500 / minute$0.001 per extra request

Read from the live RapidAPI listing on 2026-08-25. RapidAPI bills; one call to any endpoint counts as one request. Check the listing for the current figures before you commit.

Flights API questions

Which fields identify a good price?
price_insights_low and price_insights_high are the ends of the historical price band Google Flights shows for that route and date, as integers in the requested currency. price_range_in_relation_to_other_periods is Google’s verdict on the current fare: "low", "typical" or "high". All three can be null when Google does not publish a band for a search, so treat them as optional in your schema.
What is in buy_link?
A Google Flights URL of the form https://www.google.com/travel/flights?tfs=<encoded>&curr=<currency>. The encoded payload carries the passengers, cabin, trip type and every leg’s date, airports, airline and flight number, so the link reopens that exact itinerary rather than a fresh search. Round-trip results carry one combined link for the paired itinerary.
How do I scan many dates at once?
Each date is a separate request, so a month scan is thirty calls. The per-minute rate limit on your plan is what bounds the concurrency: 150 per minute on Pro, 250 on Ultra, 500 on Mega, as listed on RapidAPI on 2026-08-25. Keep your client’s connection limit under that and a month of dates finishes in one batch.
What do the response airports look like?
Requests take IATA codes (from_airport, to_airport). Responses return them as a display string in the form "City (IATA)" — for example "New York (JFK)" — not as a bare code. Parse accordingly if you round-trip values through your own storage.
Is price a string or a number?
Both, in two fields. price is the formatted string, for example "$56". price_as_number is the integer. Use price_as_number for arithmetic. stops is an integer, but can be the string "Unknown" when the itinerary’s stop count could not be read, so guard for that.
How long can a search take?
The front allows up to 180 seconds for a search before it times out, because a live scrape of Google Flights is not a cache lookup. Set your client timeout accordingly — a default 30-second HTTP timeout will cut off searches that would have succeeded.