Flights API & Scraper
The Flights API returns flight search and fare data as clean JSON.
🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.
The primary search_flights endpoint returns flights with price and segments (carrier, flight number, departure and arrival), and you can search places, pull airport_info, a price_graph and seat_info. It is built for travel apps and fare monitoring that need flight search without a scraper. One ReefAPI key, one shared credit pool, the standard envelope.
What a flights price, time and code actually mean
Three things get misread here: whether the price covers one seat or the whole booking, whether a timestamp is local or UTC, and whether a code is one airport or a whole city. Every row below was measured on 2026-08-27 against London to New York and LHR to JFK for a 2026-09-25 departure.
| Field or parameter | What it actually holds | Measured 2026-08-27 |
|---|---|---|
| price.amount | Total for the whole booking in the requested currency, not per passenger | Same LHR-JFK flight VY6653: 580 USD with adults=1, 1160 USD with adults=2 |
| price_eur | A second euro figure returned next to price on every itinerary | 580.0 USD came back alongside 498.064846 eur |
| departure / arrival | Local wall-clock at that airport, written without an offset | Norse Z0701 departs Gatwick at 2026-09-25T13:05:00 |
| departure_utc / arrival_utc | The same instant in UTC, per segment | That 13:05 Gatwick departure is 12:05 UTC |
| origin as a city name | Resolved to a city id that covers all of its airports | "London" resolved to City:london_gb (code LON); one search returned departures from LGW, STN and LHR |
| flights[].id | Prefix ItineraryOneWay: or ItineraryReturn: followed by base64 | ItineraryOneWay:eyJwcm92aWRlcnMiOiJLSVdJ... |
| segments vs outbound/inbound | One-way puts segments at the top of the itinerary; a return nests them under outbound and inbound instead | Return LHR-JFK: outbound VS25, inbound VS138, no top-level segments array |
| operating_carrier | null when the marketing airline flies it, a name when someone else does | FR3002 came back with operating_carrier "Malta Air"; VS25 came back null |
| cabin_class | economy, premium_economy, business, first. An unknown value is not rejected, it silently becomes economy | cabin_class=luxury returned ok:true with meta.cabin_class ECONOMY |
| price_graph rating | CHEAP, AVERAGE or EXPENSIVE, one label per departure date | 2026-09-25 was 462 USD AVERAGE; the cheapest day, 2026-10-09, was 414 USD CHEAP |
| seat_info pitch / width / recline | Strings, with the unit in a sibling field (CM in every measured response) | BA177 economy pitch "78" CM; the same flight in business, "182" CM |
duration_seconds covers the whole itinerary including layovers, so a one-stop LON-NYC came back at 59,100 seconds against 28,200 for the nonstop. search_flights caps what it returns with limit, while meta.total_available reports how many itineraries the search found: 50 on the measured London to New York run.
Real request and response JSON
Captured from the indexed primary action, search_flights, on .
{
"method": "POST",
"url": "https://api.reefapi.com/flights/v1/search_flights",
"headers": {
"x-api-key": "$REEF_KEY",
"content-type": "application/json"
},
"body": {
"origin": "London",
"destination": "New York",
"depart_date": "2026-08-17",
"limit": 5
}
}{
"ok": true,
"meta": {
"api": "flights",
"endpoint": "search_flights",
"mode": "live",
"latency_ms": 3780.8,
"record_count": 5,
"bytes": 26789,
"cache_hit": false,
"completeness_pct": 100,
"trip_type": "oneway",
"total_available": 50,
"has_more_pending": false,
"polls": 0,
"cabin_class": "ECONOMY",
"sort": "PRICE",
"requests": 3
},
"data": {
"flights": [
{
"id": "ItineraryOneWay:eyJwcm92aWRlcnMiOiJLSVdJLUJBU0lDOktJV0kiLCJyb3V0ZV9kYXRhIjoiUks6ODYwNTpTVE46MTc4NzAwMDQwMDpFREk6MTc4NzAwNTIwMDplY29ub215OkZhbHNlOjo6Ukt8V1M6Mzc6RURJOjE3ODcwNDkwMDA6WVlaOjE3ODcwNzY2MDA6ZWNvbm9teTpUcnVlOjpUcnVlOldTfFBEOjIxNDM6WVRaOjE3ODcwOTk0MDA6RVdSOjE3ODcxMDQ4MDA6ZWNvbm9teTpUcnVlOjpUcnVlOlAzIiwicHJpY2UiOiI1MjgifQ==",
"type": "oneway",
"price": {
"amount": 528,
"currency": "USD"
},
"price_eur": {
"amount": 461.659526,
"currency": "eur"
},
"duration_seconds": 104400,
"cabin_classes": [
"ECONOMY"
],
"booking_url": "https://www.kiwi.com/en/booking/?direct=true&locale=en¤cy=usd&passengers=1-0-0&token=H4x4DbJeoaJndFxr-ReLNqgpiJS59TpPEFg6RQ_k09RuxvyRkJTIJx-udfpE0g_NQMcrs5nckIB6SnIvgEilgf1Dyz5hC7vugZmWY-EJRYgzmPDXDvkwuI8Qf_2o6JsVNnDOw87rm1q3Ri3HroVtnHy8ltfttAugiDBFvHZv_lsLepLvhQN5eFL0mXyFeKBgai0D4OKtDgSV3MaiVFpgCtsTlnyEwscjH0tzEQqhVBnuZvGm_YUuoztiaPrRyhQzw_qKD7e9ZPGjUFG01q3XGT65TGeROZ8cYywpelhZePZtBZBXqI6OJlNKGgrCRtCAOS4hHMINcTNOmk7YEoUjsGaQk-7N_5hPVwqrzBnYUnSVQ7Dzo4UcawQmtRs9XXq07d5thQUmr5EGBEzoS_DHC7vJfzsKJX__HRPJM3qGJYZPn10nhhmywSRNhBi-I-AoyFuLIOhcT6Ku2tqbRe6d5XNz6Zuq4X0v42txqFbSKnpWepqtmIxQ1GrOBY-33",
"origin": "STN",
"destination": "EWR",
"departure": "[redacted-phone]T22:00:00",
"arrival": "[redacted-phone]T22:00:00",
"stops": 2,
"segments": [
{
"carrier": "[trimmed-depth]",
"carrier_code": "[trimmed-depth]",
"flight_no": "[trimmed-depth]",
"operating_carrier": "[trimmed-depth]",
"from": "[trimmed-depth]",
"from_name": "[trimmed-depth]",
"from_city": "[trimmed-depth]",
"to": "[trimmed-depth]",
"to_name": "[trimmed-depth]",
"to_city": "[trimmed-depth]",
"departure": "[trimmed-depth]",
"arrival": "[trimmed-depth]",
"departure_utc": "[trimmed-depth]",
"arrival_utc": "[trimmed-depth]",
"duration_seconds": "[trimmed-depth]"
},
{
"carrier": "[trimmed-depth]",
"carrier_code": "[trimmed-depth]",
"flight_no": "[trimmed-depth]",
"operating_carrier": "[trimmed-depth]",
"from": "[trimmed-depth]",
"from_name": "[trimmed-depth]",
"from_city": "[trimmed-depth]",
"to": "[trimmed-depth]",
"to_name": "[trimmed-depth]",
"to_city": "[trimmed-depth]",
"departure": "[trimmed-depth]",
"arrival": "[trimmed-depth]",
"departure_utc": "[trimmed-depth]",
"arrival_utc": "[trimmed-depth]",
"duration_seconds": "[trimmed-depth]"
},
{
"carrier": "[trimmed-depth]",
"carrier_code": "[trimmed-depth]",
"flight_no": "[trimmed-depth]",
"operating_carrier": "[trimmed-depth]",
"from": "[trimmed-depth]",
"from_name": "[trimmed-depth]",
"from_city": "[trimmed-depth]",
"to": "[trimmed-depth]",
"to_name": "[trimmed-depth]",
"to_city": "[trimmed-depth]",
"departure": "[trimmed-depth]",
"arrival": "[trimmed-depth]",
"departure_utc": "[trimmed-depth]",
"arrival_utc": "[trimmed-depth]",
"duration_seconds": "[trimmed-depth]"
}
],
"carriers": [
"PD",
"RK",
"WS"
]
},
{
"id": "ItineraryOneWay:eyJwcm92aWRlcnMiOiJLSVdJLUJBU0lDOktJV0kiLCJyb3V0ZV9kYXRhIjoiRlI6MjU2OlNUTjoxNzg3MDAzMTAwOkRVQjoxNzg3MDA3OTAwOmVjb25vbXk6RmFsc2U6Ojp8QjY6ODQyOkRVQjoxNzg3MDQ5MDAwOkpGSzoxNzg3MDc2MzYwOmVjb25vbXk6VHJ1ZTpQSVQ6VHJ1ZTpCNiIsInByaWNlIjoiNTMyIn0=",
"type": "oneway",
"price": {
"amount": 532,
"currency": "USD"
},
"price_eur": {
"amount": 465.156947,
"currency": "eur"
},
"duration_seconds": 73260,
"cabin_classes": [
"ECONOMY"
],
"booking_url": "https://www.kiwi.com/en/booking/?direct=true&locale=en¤cy=usd&passengers=1-0-0&token=Hqz9Gb6d0gLO7Yye9TBaUDtGYhUhv0uCcOpCUTBB1_56LxQH8zZ9-dHIy3Yn-01VLNV4vO2bTr0mLmLbfZJ1wRTD_3tf00cG1JHJNQ08tbDDS2lJY7OxvhbuSJBW9hsFS4NqTNrhA-in11XIZXAOl-hnIM9INm7hVw2AIzRx5stwibay7USR-6JGS6iaCs6sepCPd8wm75raVMT5aPpdB_Q4uIZKxty8VAVxGzhKc2IV9ln90lZfpmbMUbGdIgS6tLIchUsZvzyHMTDCd4knzIorHHOv6pTXNwBttCInqPeN1pZzU1bxRg-oc6Wdav6Ybn37drLO-qYYVbb5yPyqgCA3_paBkoSoq5BGo3_R8gDIqwr0ZIdkuvRxApK42QTG3ADN7dCu1k4ogNMJGDRK6HphGLxJORZsijYIqBQsCse3GNoiPx7ely_mZ0BmJUwE9Ft0HzhGudCENDnBcfgxCF0hqMlyr5Z0sLyBQEWQPnyBoMhaB4kgG2fELxWvc",
"origin": "STN",
"destination": "JFK",
"departure": "[redacted-phone]T22:45:00",
"arrival": "[redacted-phone]T14:06:00",
"stops": 1,
"segments": [
{
"carrier": "[trimmed-depth]",
"carrier_code": "[trimmed-depth]",
"flight_no": "[trimmed-depth]",
"operating_carrier": "[trimmed-depth]",
"from": "[trimmed-depth]",
"from_name": "[trimmed-depth]",
"from_city": "[trimmed-depth]",
"to": "[trimmed-depth]",
"to_name": "[trimmed-depth]",
"to_city": "[trimmed-depth]",
"departure": "[trimmed-depth]",
"arrival": "[trimmed-depth]",
"departure_utc": "[trimmed-depth]",
"arrival_utc": "[trimmed-depth]",
"duration_seconds": "[trimmed-depth]"
},
{
"carrier": "[trimmed-depth]",
"carrier_code": "[trimmed-depth]",
"flight_no": "[trimmed-depth]",
"operating_carrier": "[trimmed-depth]",
"from": "[trimmed-depth]",
"from_name": "[trimmed-depth]",
"from_city": "[trimmed-depth]",
"to": "[trimmed-depth]",
"to_name": "[trimmed-depth]",
"to_city": "[trimmed-depth]",
"departure": "[trimmed-depth]",
"arrival": "[trimmed-depth]",
"departure_utc": "[trimmed-depth]",
"arrival_utc": "[trimmed-depth]",
"duration_seconds": "[trimmed-depth]"
}
],
"carriers": [
"B6",
"FR"
]
},
{
"id": "ItineraryOneWay:eyJwcm92aWRlcnMiOiJLSVdJLUJBU0lDOktJV0kiLCJyb3V0ZV9kYXRhIjoiUks6ODYwNTpTVE46MTc4NzAwMDQwMDpFREk6MTc4NzAwNTIwMDplY29ub215OkZhbHNlOjo6Ukt8V1M6NzM6RURJOjE3ODcwNDE1MDA6WUhaOjE3ODcwNjQ2MDA6ZWNvbm9teTpUcnVlOjpUcnVlOldTfFdTOjgwMzpZSFo6MTc4NzA3MDYwMDpZWVo6MTc4NzA3OTYwMDplY29ub215OkZhbHNlOjo6V1N8UEQ6NjA3OllZWjoxNzg3MDg5ODAwOkxHQToxNzg3MDk1NTAwOmVjb25vbXk6VHJ1ZTo6VHJ1ZTpQRCIsInByaWNlIjoiNTQxIn0=",
"type": "oneway",
"price": {
"amount": 541,
"currency": "USD"
},
"price_eur": {
"amount": 473.026143,
"currency": "eur"
},
"duration_seconds": 95100,
"cabin_classes": [
"ECONOMY"
],
"booking_url": "https://www.kiwi.com/en/booking/?direct=true&locale=en¤cy=usd&passengers=1-0-0&token=HqNot3bc1zIvThuL8OuCgNn0pCObmGiRghZJ6aH2loI--MGEvsvZz6gpyvHw0ti1VsBy2kadvUCNfkmCTAT57jfk1Uv4MvtjHhrvypoWtFxJQspgYWsrAnr1OegKfdV2kMWkahRedWA0ZVe8EhIEYmAfNCVvgnT8ls7WFXVxojtZnZe0psacQbyPJB2MbbskDaWCg4inTMmmfh8Ur-ieQqG8uymTAf39hfZkGQ5LLhksLeWe9SnPCsUb5bhH-vBHdX9m7Vh6TaP28ZowJqOkxa2iA_pkHBjkynOVhH_bCDNZNHubuZiB79rFARKUpsCcFNGqIkvYsQ2b8KuV6l29n_aqPnmvBmRol9bme_aCIEmhG90zggtHeIr_4cBmJy5c1Ms-VbYThw5Qswq5OMINZ5rk6iELkKkYaReYk6ez7tVRB2FtYiQ76GZtuDVE-3yTfSUeXeAEsimTVeQzFG4u8djAXzCpuMTrHDlVp4UnsbWBBVcnm8xDE7j9jR4vB",
"origin": "STN",
"destination": "LGA",
"departure": "[redacted-phone]T22:00:00",
"arrival": "[redacted-phone]T19:25:00",
"stops": 3,
"segments": [
{
"carrier": "[trimmed-depth]",
"carrier_code": "[trimmed-depth]",
"flight_no": "[trimmed-depth]",
"operating_carrier": "[trimmed-depth]",
"from": "[trimmed-depth]",
"from_name": "[trimmed-depth]",
"from_city": "[trimmed-depth]",
"to": "[trimmed-depth]",
"to_name": "[trimmed-depth]",
"to_city": "[trimmed-depth]",
"departure": "[trimmed-depth]",
"arrival": "[trimmed-depth]",
"departure_utc": "[trimmed-depth]",
"arrival_utc": "[trimmed-depth]",
"duration_seconds": "[trimmed-depth]"
},
{
"carrier": "[trimmed-depth]",
"carrier_code": "[trimmed-depth]",
"flight_no": "[trimmed-depth]",
"operating_carrier": "[trimmed-depth]",
"from": "[trimmed-depth]",
"from_name": "[trimmed-depth]",
"from_city": "[trimmed-depth]",
"to": "[trimmed-depth]",
"to_name": "[trimmed-depth]",
"to_city": "[trimmed-depth]",
"departure": "[trimmed-depth]",
"arrival": "[trimmed-depth]",
"departure_utc": "[trimmed-depth]",
"arrival_utc": "[trimmed-depth]",
"duration_seconds": "[trimmed-depth]"
},
{
"carrier": "[trimmed-depth]",
"carrier_code": "[trimmed-depth]",
"flight_no": "[trimmed-depth]",
"operating_carrier": "[trimmed-depth]",
"from": "[trimmed-depth]",
"from_name": "[trimmed-depth]",
"from_city": "[trimmed-depth]",
"to": "[trimmed-depth]",
"to_name": "[trimmed-depth]",
"to_city": "[trimmed-depth]",
"departure": "[trimmed-depth]",
"arrival": "[trimmed-depth]",
"departure_utc": "[trimmed-depth]",
"arrival_utc": "[trimmed-depth]",
"duration_seconds": "[trimmed-depth]"
}
],
"carriers": [
"PD",
"RK",
"WS"
]
}
],
"count": 5,
"trip_type": "oneway",
"origin": {
"input": "London",
"id": "City:london_gb",
"name": "London",
"code": "LON",
"type": "City",
"slug": "london-united-kingdom",
"resolved_from": "places"
},
"destination": {
"input": "New York",
"id": "City:new-york-city_ny_us",
"name": "[redacted-name]",
"code": "NYC",
"type": "City",
"slug": "new-york-city-new-york-united-states",
"resolved_from": "places"
},
"currency": "USD",
"total_available": 50
}
}What the Flights API does
| Action | Description | Concrete use case | Key params |
|---|---|---|---|
| search_flights | Search flights from origin to destination for a given date. Returns ranked itineraries with price, all flight segments (carrier, flight number, departure/arrival times), total journey duration and a direct booking link. Supports one-way and return trips. | Travel apps call search_flights to search flights from origin to destination for a given date. | origin, destination, depart_date, return_date, depart_date_end, ... |
| search_places | Resolve a city or airport name to location IDs used in flight search — useful when you want to pin an exact airport rather than a city (e.g. 'Heathrow' → LHR). | Pricing monitors call search_places to resolve a city or airport name to location IDs used in flight search. | query, limit |
| airport_info | Look up airports and cities by name or IATA code. Returns full reference data: IATA + ICAO codes, GPS coordinates, timezone, country, and — for a city — the list of all its airports. Useful to validate a code, geolocate an airport, or map a city to its airports. | Itinerary products call airport_info to look up airports and cities by name or IATA code. | query, limit |
| price_graph | Find the cheapest day to fly. Returns the lowest price for each departure date across a date range, each tagged CHEAP / AVERAGE / EXPENSIVE, plus the single cheapest option. Set nights_min/nights_max for a return trip; omit them for one-way. One fast call. | Hospitality analysts call price_graph to find the cheapest day to fly. | origin, destination, depart_date, depart_date_end, nights_min, ... |
| seat_info | Get the seat specs and amenities for a specific flight: seat pitch, width and recline (legroom/comfort), plus power, Wi-Fi and in-flight entertainment availability. Look up by airline + flight number + route + date. Returns honest empty when the flight is unknown. | Travel apps call seat_info to get the seat specs and amenities for a specific flight. | carrier, flight_number, source, destination, date, ... |
Call search_flights from your stack
curl -X POST https://api.reefapi.com/flights/v1/search_flights \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"origin":"London","destination":"New York","depart_date":"2026-08-17","limit":5}'import requests
r = requests.post(
"https://api.reefapi.com/flights/v1/search_flights",
headers={"x-api-key": REEF_KEY},
json={
"origin": "London",
"destination": "New York",
"depart_date": "2026-08-17",
"limit": 5
},
)
print(r.json()["data"])const res = await fetch("https://api.reefapi.com/flights/v1/search_flights", {
method: "POST",
headers: {
"x-api-key": process.env.REEF_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"origin": "London",
"destination": "New York",
"depart_date": "2026-08-17",
"limit": 5
}),
});
const { ok, data, meta, error } = await res.json();Ask your MCP-connected assistant: call reefapi.flights.search_flights with {"origin":"London","destination":"New York","depart_date":"2026-08-17","limit":5}.Who uses this API and why
- Travel apps call search_flights to show fares by route and date.
- Fare monitors use price_graph to find the cheapest days to fly.
- Booking flows use seat_info and airport_info to complete a trip.
Questions developers ask before integrating
Is the flight price per passenger or for the whole trip?
It is the total for the whole booking. On 2026-08-27 the same LHR to JFK itinerary (Vueling VY6653, departing 2026-09-25) came back at 580.00 USD with adults=1 and 1160.00 USD with adults=2. Divide by your passenger count if you need a per-seat figure. Every itinerary also carries price_eur, a euro figure for the same total, whatever currency you asked for.
Are departure and arrival times local or UTC?
Both, in separate fields. departure and arrival are the local clock at each airport and carry no offset, so "2026-09-25T13:05:00" means 13:05 in London. Each segment additionally carries departure_utc and arrival_utc for the same instant, and that Gatwick departure came back as 12:05 UTC. Do arithmetic on the _utc pair and display the local pair.
What happens if I pass a city name instead of an airport code?
It resolves to a city and searches every airport in it. "London" resolved to City:london_gb with code LON, and one search returned itineraries departing Gatwick, Stansted and Heathrow. The resolved place comes back in data.origin with its id, name, code and type, so you can see what you actually searched. Pass a three-letter airport code instead when you want one specific airport.
Why does a return search have no segments array?
A return itinerary nests its flights under outbound and inbound instead, each with its own segments, stops, departure, arrival and carriers. A one-way itinerary puts segments, stops, departure and arrival at the top level. The id prefix tells you which shape you have before you parse: ItineraryOneWay: or ItineraryReturn:. meta.trip_type says the same thing.
What does seat_info return for a flight it does not recognize?
ok:true with found:false, seat set to null, and meta.record_count 0. Asking for BA9999 LHR to JFK produced exactly that on 2026-08-27, while BA177 on the same route returned pitch 78 CM, width 43 CM, recline 10 CM and has_power, has_wifi and has_audio_video all true. Check found before reading seat, because an unknown flight is not an error response.
How do I find the cheapest day to fly?
price_graph returns one row per departure date across a range, each with a price and a rating of CHEAP, AVERAGE or EXPENSIVE, plus a separate cheapest object. A London to New York window of 2026-09-25 to 2026-10-10 returned 16 rows, both endpoints included, with 2026-09-25 at 462 USD rated AVERAGE and the cheapest day, 2026-10-09, at 414 USD rated CHEAP. Add nights_min and nights_max to turn it into a return-trip graph; leave them out and return_date comes back null on every row.
What happens if I send a cabin_class the API does not know?
It is ignored rather than rejected, and the search runs in economy. Sending cabin_class=luxury returned ok:true with results, and meta.cabin_class read ECONOMY. The four accepted values are economy, premium_economy, business and first. The sort parameter behaves the same way, falling back to price. Read meta.cabin_class and meta.sort back if you need to be sure your filter took effect.
How do I validate an airport code or get its coordinates?
airport_info takes a name or a code and returns the IATA code, the ICAO code, the timezone and GPS coordinates. "Heathrow" returned id Station:airport:LHR with iata LHR, icao EGLL, timezone Europe/London and gps 51.4775 / -0.461389. A city match looks different from an airport match: cities carry country and country_code, airports carry the parent city instead. Matching is fuzzy and ranked, so check type and iata on the row before using it rather than taking the first hit blind.
What is the Flights API?
Flights API is a ReefAPI endpoint group for search flights with prices, routes and times. It returns live JSON through POST requests under /flights/v1.
Is the Flights API free to try?
Yes. ReefAPI starts with 1,000 free credits, no card required. Flights calls use the same shared credit balance as every other ReefAPI engine.
Do I need a Flights login or account?
No login to Flights is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the Flights data?
The page example is captured from a live search_flights call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the Flights API use?
Flights actions currently cost 1-2 credits per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.
Can I call Flights from an AI assistant or MCP client?
Yes. Connect ReefAPI once through MCP and your assistant can call flights actions with the same key, credit pool and JSON envelope used by normal REST requests.