Skip to content

Quickstart

Five minutes to your first live price

Five steps, all of them a paste. No SDK, no account on this site, nothing to install. The free tier is 10 requests a month on flights and 10 on hotels, so the steps below are ordered to spend as few of them as possible.

1

Get a key

Both APIs are listed on RapidAPI, and one key works for both the marketplace hosts and api.flightpowers.com. Subscribe to the free tier. It takes about a minute and asks for no card, then copy the key from RapidAPI's Apps page.

Put it in your shell so nothing below contains a real key: export RAPIDAPI_KEY="…"

2

Check the key works, before you spend a search on finding out

curl
curl -sS "https://api.flightpowers.com/v1/verify" \
  -H "x-api-key: $RAPIDAPI_KEY"

A 200 means the key authenticates. Anything else is worth fixing before step 3: 401 is a key the gateway does not recognise, 403 is a real key that is not subscribed to that listing.

Honest note: /v1/verify performs a real upstream check, so it costs one request against the hotels plan. On a 10-request free tier that is worth knowing before you run it in a loop.

3

Run your first search

curl · one-way, live Google Flights prices
curl -sS -X POST "https://api.flightpowers.com/v1/flights/oneway" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $RAPIDAPI_KEY" \
  -d '{
    "from_airport": "JFK",
    "to_airport": "CUN",
    "departure_date": "2027-01-01",
    "limit": 5,
    "currency": "usd"
  }'

Three fields are required: from_airport, to_airport, departure_date. Airports are IATA codes, the date is YYYY-MM-DD. A round trip is its own endpoint, /v1/flights/roundtrip, which takes a return_date and prices the legs as one itinerary. It is not two one-ways stapled together, and calling it that way gives you a different, usually worse answer.

4

Read the answer

response · Captured run: real response from a live request on 2026-08-26
// the cheapest row of that captured response, trimmed
{
  "price": "$177",
  "price_as_number": 177,
  "price_range_in_relation_to_other_periods": "typical",
  "price_insights_low": 140,
  "price_insights_high": 180,
  "airline": "American",
  "duration": "4 hr 25 min"
}

price_range_in_relation_to_other_periods is Google's own verdict on this fare: low, typical or high. And price_insights_low/high are the band it judged against. None of the four Google Flights listings ranked above ours on RapidAPI documents that field (all four listing pages pulled on 2026-09-06), and it is what lets you say “book now” instead of just showing a number. SerpApi and HasData do return a comparable object, so this is a difference on the RapidAPI shelf, not against every provider.

Check the x-search-status response header too. It is one of ok, empty, partial or degraded. empty means the route genuinely has no fares; degraded means the search did not complete, so an empty array from it says nothing about availability. Branch on the header, not on the array length.

5

Search hotels, from any market you like

curl · live Booking.com rates, priced as a German visitor
curl -sS -X POST "https://api.flightpowers.com/v1/hotels/search" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $RAPIDAPI_KEY" \
  -d '{
    "destination": "Lisbon",
    "checkin_date": "2026-10-09",
    "checkout_date": "2026-10-12",
    "adults": 2,
    "currency": "EUR",
    "filters": [
      "review_score_8",
      "free_cancellation"
    ],
    "proxy_country": "de"
  }'

The field is destination. A location key is rejected with a 400, and it is the single most common first-call mistake, because location is a field in the response.

proxy_country routes the request through a residential proxy in that country. Booking.com quotes different markets differently; this is how you observe that, and it is the basis of rate-parity and geo-pricing monitoring. Omit it and you get the global pool.

6

If a flight call comes back 422, it is one of four things

A 422 means the request never reached a search: the body was rejected at the door. The response says which field and why, in detail, with a one-line hint and a help link back to this section. These are the four things it can be.

1. A field name this endpoint does not have. Unknown keys are rejected, not ignored, so a typo costs you a call instead of quietly answering a different question. The three that catch people: to_airports (plural) — the field is to_airport, one IATA code; min_departure_date or max_departure_date — the field is departure_date; and max_stops on a round trip, which has max_departure_stops and max_return_stops instead. Sending the plural gives you two errors at once, an unknown key and a missing one. Fix the name, not the missing field.

2. A required field missing, or the wrong type. One-way needs from_airport, to_airport and departure_date; round trip adds return_date. Numbers are numbers: max_stops, max_price, limit, seat_type and the four time filters are whole numbers, and a string like "2" is a 422.

3. A date that is not YYYY-MM-DD, or a return before the departure. departure_date and return_date are plain YYYY-MM-DD strings, so 05/11/2026 is rejected. On /v1/flights/roundtrip, return_date has to be a later calendar day than departure_date; same-day round trips are not supported.

4. A value the search itself refuses. A date in the past — the boundary is today in UTC, so it moves at UTC midnight, not in your timezone. A time filter (departure_time_min/max, arrival_time_min/max, and their departure_/return_ prefixed round-trip twins) outside 0–24. A negative max_stops or max_price. This is the class that fails intermittently: the same client code that worked yesterday starts 422ing overnight because the date it is asking for has passed.

Hotels have their own version of the first one, above: the field is destination, and location is a 400.

Same key, two hosts

If you would rather not depend on a marketplace

Every call above works just as well against the RapidAPI host you subscribed on. The paths differ; the key, the request bodies and the responses do not.

curl · the same search on the RapidAPI host
curl -X POST "https://google-flights-live-api.p.rapidapi.com/api/google_flights/oneway/v1" \
  -H "Content-Type: application/json" \
  -H "x-rapidapi-host: google-flights-live-api.p.rapidapi.com" \
  -H "x-rapidapi-key: $RAPIDAPI_KEY" \
  -d '{
    "from_airport": "JFK",
    "to_airport": "CUN",
    "departure_date": "2027-01-01",
    "currency": "usd"
  }'

api.flightpowers.com is our own domain and carries the machine-readable spec at /openapi.json. The key goes in x-api-key, x-rapidapi-key, or Authorization: Bearer, whichever your client makes easiest.

Next

Where to go from here

Know before the response shape changes

One email when something ships that changes what you can build: a new endpoint, a changed field, a deprecation, a price move. Nothing else goes to this list.

The address is stored to send that list and nothing else. It is not sold, not shared with the marketplaces, and not used to build a profile. Unsubscribe from any email, or from the unsubscribe page. More in privacy.