curl --request POST \
--url https://api.gojinko.com/v1/flight_search \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"origin": "JFK",
"destination": "CDG",
"departure_date": "2026-09-01",
"return_date": "2026-09-08",
"trip_type": "roundtrip",
"cabin_class": "economy",
"adults": 1,
"max_stops": 1,
"checked_bag_included": true,
"currency": "USD"
}
'import requests
url = "https://api.gojinko.com/v1/flight_search"
payload = {
"origin": "JFK",
"destination": "CDG",
"departure_date": "2026-09-01",
"return_date": "2026-09-08",
"trip_type": "roundtrip",
"cabin_class": "economy",
"adults": 1,
"max_stops": 1,
"checked_bag_included": True,
"currency": "USD"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
origin: 'JFK',
destination: 'CDG',
departure_date: '2026-09-01',
return_date: '2026-09-08',
trip_type: 'roundtrip',
cabin_class: 'economy',
adults: 1,
max_stops: 1,
checked_bag_included: true,
currency: 'USD'
})
};
fetch('https://api.gojinko.com/v1/flight_search', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.gojinko.com/v1/flight_search",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'origin' => 'JFK',
'destination' => 'CDG',
'departure_date' => '2026-09-01',
'return_date' => '2026-09-08',
'trip_type' => 'roundtrip',
'cabin_class' => 'economy',
'adults' => 1,
'max_stops' => 1,
'checked_bag_included' => true,
'currency' => 'USD'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.gojinko.com/v1/flight_search"
payload := strings.NewReader("{\n \"origin\": \"JFK\",\n \"destination\": \"CDG\",\n \"departure_date\": \"2026-09-01\",\n \"return_date\": \"2026-09-08\",\n \"trip_type\": \"roundtrip\",\n \"cabin_class\": \"economy\",\n \"adults\": 1,\n \"max_stops\": 1,\n \"checked_bag_included\": true,\n \"currency\": \"USD\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.gojinko.com/v1/flight_search")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"origin\": \"JFK\",\n \"destination\": \"CDG\",\n \"departure_date\": \"2026-09-01\",\n \"return_date\": \"2026-09-08\",\n \"trip_type\": \"roundtrip\",\n \"cabin_class\": \"economy\",\n \"adults\": 1,\n \"max_stops\": 1,\n \"checked_bag_included\": true,\n \"currency\": \"USD\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gojinko.com/v1/flight_search")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"origin\": \"JFK\",\n \"destination\": \"CDG\",\n \"departure_date\": \"2026-09-01\",\n \"return_date\": \"2026-09-08\",\n \"trip_type\": \"roundtrip\",\n \"cabin_class\": \"economy\",\n \"adults\": 1,\n \"max_stops\": 1,\n \"checked_bag_included\": true,\n \"currency\": \"USD\"\n}"
response = http.request(request)
puts response.read_body{
"offers": [
{
"offer_id": "offer__3a9f1b27",
"origin": {
"code": "NYC",
"name": "New York"
},
"destination": {
"code": "LAX",
"name": "Los Angeles"
},
"additional_legs": [],
"fares": [
{
"trip_item_token": "offer__3a9f1b27:0-1-0",
"searched_at": "2026-09-23T15:43:40Z",
"expires_at": "2026-09-23T16:58:40Z",
"cabin_class": "economy",
"brand_name": "Main Cabin",
"total_price": {
"amount": 123,
"value": 41250,
"currency": "USD",
"decimal_places": 2,
"display": "USD 412.50"
},
"price_per_person": {
"value": 41250,
"currency": "USD",
"decimal_places": 2,
"display": "USD 412.50"
},
"included_baggage": {
"pieces": 1,
"weight": 23,
"weight_unit": "KG",
"dimensions": "158 cm linear",
"description": "1 bag, 23KG each"
},
"carry_on_baggage": {
"pieces": 1,
"weight": 23,
"weight_unit": "KG",
"dimensions": "158 cm linear",
"description": "1 bag, 23KG each"
},
"is_changeable": true,
"is_refundable": false,
"refund_policy": "Refundable with fee",
"change_policy": "Changes allowed with fee",
"checked_bag_included": true
}
],
"is_round_trip": false,
"total_duration_minutes": 385,
"outbound": {
"origin": "JFK",
"destination": "LAX",
"departure_datetime": "2026-07-15T08:30:00-04:00",
"arrival_datetime": "2026-07-15T11:55:00-07:00",
"duration_minutes": 385,
"airline": "AA",
"airline_name": "American Airlines",
"stops": 0,
"stop_infos": [
{
"airport_code": "DFW",
"duration_minutes": 95
}
],
"segments": [
{
"airline": "AA",
"airline_name": "American Airlines",
"flight_number": "460",
"aircraft": "32Q",
"departure_airport": "JFK",
"departure_city": "NYC",
"departure_time": "2026-09-23T11:55:00-04:00",
"arrival_airport": "DFW",
"arrival_city": "DFW",
"arrival_time": "2026-09-23T15:10:00-05:00",
"duration_minutes": 255,
"layover_minutes": 95,
"operating_carrier": "MQ"
}
]
},
"inbound": {
"origin": "JFK",
"destination": "LAX",
"departure_datetime": "2026-07-15T08:30:00-04:00",
"arrival_datetime": "2026-07-15T11:55:00-07:00",
"duration_minutes": 385,
"airline": "AA",
"airline_name": "American Airlines",
"stops": 0,
"stop_infos": [
{
"airport_code": "DFW",
"duration_minutes": 95
}
],
"segments": [
{
"airline": "AA",
"airline_name": "American Airlines",
"flight_number": "460",
"aircraft": "32Q",
"departure_airport": "JFK",
"departure_city": "NYC",
"departure_time": "2026-09-23T11:55:00-04:00",
"arrival_airport": "DFW",
"arrival_city": "DFW",
"arrival_time": "2026-09-23T15:10:00-05:00",
"duration_minutes": 255,
"layover_minutes": 95,
"operating_carrier": "MQ"
}
]
}
}
],
"exact_match_found": true,
"result": "no_matches",
"instruction": "Search completed successfully, but no offers satisfied every filter sent: the filter combination is too restrictive for this route and dates. Ask the user which filter to relax before searching again."
}{
"error": {
"code": "BAD_REQUEST",
"message": "The request was declined for these inputs. Check the dates, places and travellers, then retry."
}
}{
"error": {
"code": "AUTH_REQUIRED",
"message": "Invalid or expired API key.",
"doc_url": "https://docs.gojinko.com/authentication/api-keys"
}
}{
"error": {
"code": "PAYMENT_REQUIRED",
"message": "Insufficient balance — this call costs $0.0150 and your organization has $0.0000 available. Top up at https://dashboard.gojinko.com/developers/billing/topup",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "NOT_FOUND",
"message": "Resource not found.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "CONFLICT",
"message": "The operation conflicts with the current state of the resource.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "GONE",
"message": "The resource no longer exists.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "BAD_REQUEST",
"message": "A required field is missing or invalid.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "RATE_LIMITED",
"message": "Too many requests. Retry after the Retry-After delay.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "UPSTREAM_REJECTED",
"message": "The request was declined for this offer. Try another offer.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "UPSTREAM_UNAVAILABLE",
"message": "The service is temporarily unavailable. Retry after the Retry-After delay.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "UPSTREAM_TIMEOUT",
"message": "The request timed out before a result was available. Retry the request.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}flight-search
Get live flight pricing, search by route, or re-price a known offer
curl --request POST \
--url https://api.gojinko.com/v1/flight_search \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"origin": "JFK",
"destination": "CDG",
"departure_date": "2026-09-01",
"return_date": "2026-09-08",
"trip_type": "roundtrip",
"cabin_class": "economy",
"adults": 1,
"max_stops": 1,
"checked_bag_included": true,
"currency": "USD"
}
'import requests
url = "https://api.gojinko.com/v1/flight_search"
payload = {
"origin": "JFK",
"destination": "CDG",
"departure_date": "2026-09-01",
"return_date": "2026-09-08",
"trip_type": "roundtrip",
"cabin_class": "economy",
"adults": 1,
"max_stops": 1,
"checked_bag_included": True,
"currency": "USD"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
origin: 'JFK',
destination: 'CDG',
departure_date: '2026-09-01',
return_date: '2026-09-08',
trip_type: 'roundtrip',
cabin_class: 'economy',
adults: 1,
max_stops: 1,
checked_bag_included: true,
currency: 'USD'
})
};
fetch('https://api.gojinko.com/v1/flight_search', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.gojinko.com/v1/flight_search",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'origin' => 'JFK',
'destination' => 'CDG',
'departure_date' => '2026-09-01',
'return_date' => '2026-09-08',
'trip_type' => 'roundtrip',
'cabin_class' => 'economy',
'adults' => 1,
'max_stops' => 1,
'checked_bag_included' => true,
'currency' => 'USD'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.gojinko.com/v1/flight_search"
payload := strings.NewReader("{\n \"origin\": \"JFK\",\n \"destination\": \"CDG\",\n \"departure_date\": \"2026-09-01\",\n \"return_date\": \"2026-09-08\",\n \"trip_type\": \"roundtrip\",\n \"cabin_class\": \"economy\",\n \"adults\": 1,\n \"max_stops\": 1,\n \"checked_bag_included\": true,\n \"currency\": \"USD\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.gojinko.com/v1/flight_search")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"origin\": \"JFK\",\n \"destination\": \"CDG\",\n \"departure_date\": \"2026-09-01\",\n \"return_date\": \"2026-09-08\",\n \"trip_type\": \"roundtrip\",\n \"cabin_class\": \"economy\",\n \"adults\": 1,\n \"max_stops\": 1,\n \"checked_bag_included\": true,\n \"currency\": \"USD\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gojinko.com/v1/flight_search")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"origin\": \"JFK\",\n \"destination\": \"CDG\",\n \"departure_date\": \"2026-09-01\",\n \"return_date\": \"2026-09-08\",\n \"trip_type\": \"roundtrip\",\n \"cabin_class\": \"economy\",\n \"adults\": 1,\n \"max_stops\": 1,\n \"checked_bag_included\": true,\n \"currency\": \"USD\"\n}"
response = http.request(request)
puts response.read_body{
"offers": [
{
"offer_id": "offer__3a9f1b27",
"origin": {
"code": "NYC",
"name": "New York"
},
"destination": {
"code": "LAX",
"name": "Los Angeles"
},
"additional_legs": [],
"fares": [
{
"trip_item_token": "offer__3a9f1b27:0-1-0",
"searched_at": "2026-09-23T15:43:40Z",
"expires_at": "2026-09-23T16:58:40Z",
"cabin_class": "economy",
"brand_name": "Main Cabin",
"total_price": {
"amount": 123,
"value": 41250,
"currency": "USD",
"decimal_places": 2,
"display": "USD 412.50"
},
"price_per_person": {
"value": 41250,
"currency": "USD",
"decimal_places": 2,
"display": "USD 412.50"
},
"included_baggage": {
"pieces": 1,
"weight": 23,
"weight_unit": "KG",
"dimensions": "158 cm linear",
"description": "1 bag, 23KG each"
},
"carry_on_baggage": {
"pieces": 1,
"weight": 23,
"weight_unit": "KG",
"dimensions": "158 cm linear",
"description": "1 bag, 23KG each"
},
"is_changeable": true,
"is_refundable": false,
"refund_policy": "Refundable with fee",
"change_policy": "Changes allowed with fee",
"checked_bag_included": true
}
],
"is_round_trip": false,
"total_duration_minutes": 385,
"outbound": {
"origin": "JFK",
"destination": "LAX",
"departure_datetime": "2026-07-15T08:30:00-04:00",
"arrival_datetime": "2026-07-15T11:55:00-07:00",
"duration_minutes": 385,
"airline": "AA",
"airline_name": "American Airlines",
"stops": 0,
"stop_infos": [
{
"airport_code": "DFW",
"duration_minutes": 95
}
],
"segments": [
{
"airline": "AA",
"airline_name": "American Airlines",
"flight_number": "460",
"aircraft": "32Q",
"departure_airport": "JFK",
"departure_city": "NYC",
"departure_time": "2026-09-23T11:55:00-04:00",
"arrival_airport": "DFW",
"arrival_city": "DFW",
"arrival_time": "2026-09-23T15:10:00-05:00",
"duration_minutes": 255,
"layover_minutes": 95,
"operating_carrier": "MQ"
}
]
},
"inbound": {
"origin": "JFK",
"destination": "LAX",
"departure_datetime": "2026-07-15T08:30:00-04:00",
"arrival_datetime": "2026-07-15T11:55:00-07:00",
"duration_minutes": 385,
"airline": "AA",
"airline_name": "American Airlines",
"stops": 0,
"stop_infos": [
{
"airport_code": "DFW",
"duration_minutes": 95
}
],
"segments": [
{
"airline": "AA",
"airline_name": "American Airlines",
"flight_number": "460",
"aircraft": "32Q",
"departure_airport": "JFK",
"departure_city": "NYC",
"departure_time": "2026-09-23T11:55:00-04:00",
"arrival_airport": "DFW",
"arrival_city": "DFW",
"arrival_time": "2026-09-23T15:10:00-05:00",
"duration_minutes": 255,
"layover_minutes": 95,
"operating_carrier": "MQ"
}
]
}
}
],
"exact_match_found": true,
"result": "no_matches",
"instruction": "Search completed successfully, but no offers satisfied every filter sent: the filter combination is too restrictive for this route and dates. Ask the user which filter to relax before searching again."
}{
"error": {
"code": "BAD_REQUEST",
"message": "The request was declined for these inputs. Check the dates, places and travellers, then retry."
}
}{
"error": {
"code": "AUTH_REQUIRED",
"message": "Invalid or expired API key.",
"doc_url": "https://docs.gojinko.com/authentication/api-keys"
}
}{
"error": {
"code": "PAYMENT_REQUIRED",
"message": "Insufficient balance — this call costs $0.0150 and your organization has $0.0000 available. Top up at https://dashboard.gojinko.com/developers/billing/topup",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "NOT_FOUND",
"message": "Resource not found.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "CONFLICT",
"message": "The operation conflicts with the current state of the resource.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "GONE",
"message": "The resource no longer exists.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "BAD_REQUEST",
"message": "A required field is missing or invalid.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "RATE_LIMITED",
"message": "Too many requests. Retry after the Retry-After delay.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "UPSTREAM_REJECTED",
"message": "The request was declined for this offer. Try another offer.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "UPSTREAM_UNAVAILABLE",
"message": "The service is temporarily unavailable. Retry after the Retry-After delay.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}{
"error": {
"code": "UPSTREAM_TIMEOUT",
"message": "The request timed out before a result was available. Retry the request.",
"doc_url": "https://docs.gojinko.com/concepts/errors"
}
}Two modes, one endpoint
POST /v1/flight_search serves both modes:
- Search mode: filter-based live search by
origin,destination,departure_date, and passengers. Returns priced offers, each fare carrying atrip_item_tokenyou can add to a trip. - Reprice mode: pass an
offer_tokenfrom discovery (find_destination,flight_calendar) to re-price that specific offer before adding it to a trip. Route and filter fields are not allowed besideoffer_token.
--offer-token for reprice mode, omit it for search mode.
Cabin class in live search
Omitcabin_class or send null when the user has not requested a cabin. Providers search economy by default, and the response can include other recognized cabins they return.
Send economy, premium_economy, business, or first only when the user explicitly chooses that cabin. Jinko filters returned fares to match the cabin on the itinerary’s longest segment. Shorter connections may use another cabin; check segment details when presenting a mixed-cabin itinerary.
A successful search with no matches
When a live search finds no offers that match the current filters, the endpoint returns HTTP 200 withoffers: [], result: "no_matches", and an instruction that asks the caller to explain that the search succeeded. When the request sent a filter that narrows the results, the instruction asks the user which filter to relax: every such filter is applied exactly as sent, so the empty result means the filter combination was too restrictive for this route and dates. Otherwise it asks whether to try other dates or airports; see Filters are always applied. The deprecated X-Jinko-Result and X-Jinko-Instruction headers carry the same outcome; read the body instead.
The search answers no_matches whenever at least one airline source answered, even if another could not be searched. When some sources fail and others return offers, the response carries those offers and does not say which sources failed.
A search where every source failed is an error: temporary unavailability or incomplete polling returns 503 (honor Retry-After when present and preserve the user’s filters), and a timeout returns 504. The error message is fixed per code; see Messages on supplier failures. These search rules apply to live search mode; reprice and cache-based discovery retain their existing behavior.
Offer freshness
Each fare can carrysearched_at and expires_at as RFC 3339 timestamps. searched_at is when the supplier search began. expires_at is the earlier of a known supplier deadline and Jinko’s 75-minute token lifetime. When the supplier gives no deadline, it bounds token retention only. Neither field guarantees availability or price; suppliers can withdraw an offer sooner. Missing timestamps mean unknown.
Repeated searches can return the same trip_item_token. Use the timestamps and latest search result to assess freshness. Complete checkout promptly; if the user pauses, search again before checkout. After expires_at, search again and replace the item. There is no universal safe maximum age, and creating a trip does not extend the offer’s lifetime.
value is an integer — divide by
10 ** decimal_places to display it. { "value": 15977, "decimal_places": 2 }
is $159.77, not $15,977. See Money & prices.Authorizations
Body
3-letter IATA city or airport code. See origin_type for how an untyped code is read. origin and destination must differ. A 3-letter code the platform’s location catalog does not recognise is not refused: it is searched as an airport, and if no provider sells it the search answers result: no_matches.
"JFK"
3-letter IATA city or airport code. See destination_type for how an untyped code is read: LAX alone is the Los Angeles CITY; send destination_type: "airport" for the airport only. origin and destination must differ. A 3-letter code the platform’s location catalog does not recognise is not refused: it is searched as an airport, and if no provider sells it the search answers result: no_matches.
"LAX"
How to read the code: city searches every airport of the city, airport only that one airport. Omit it and the platform applies one rule: a code that names a multi-airport city is searched as the city; every other code is searched as the airport. Untyped NYC, LON or PAR is the city; untyped JFK, LHR or CDG is the airport; and untyped LAX, MIA or LAS — codes a city shares with its main airport — is the CITY, so results can land at any airport of that city. If the user named the airport, send airport; if they named the city, omit the field. The provider decides which airports a city holds, so a city search can return airports the catalog does not list under that code: searched as a city, LAX returns Ontario (ONT) fares, often as the cheapest offers. Each offer’s legs carry the airports flown; the offer-level origin / destination carry the city.
city, airport "airport"
How to read the code: city searches every airport of the city, airport only that one airport. Omit it and the platform applies one rule: a code that names a multi-airport city is searched as the city; every other code is searched as the airport. Untyped NYC, LON or PAR is the city; untyped JFK, LHR or CDG is the airport; and untyped LAX, MIA or LAS — codes a city shares with its main airport — is the CITY, so results can land at any airport of that city. If the user named the airport, send airport; if they named the city, omit the field. The provider decides which airports a city holds, so a city search can return airports the catalog does not list under that code: searched as a city, LAX returns Ontario (ONT) fares, often as the cheapest offers. Each offer’s legs carry the airports flown; the offer-level origin / destination carry the city.
city, airport "airport"
Departure date, YYYY-MM-DD: the local date at origin. Required in search mode, with origin and destination; not allowed beside offer_token. A date that does not exist on the calendar (2026-02-30) is refused with 422 naming the field.
^\d{4}-\d{2}-\d{2}$"2026-09-01"
Return date, YYYY-MM-DD, on or after departure_date (a same-day return is valid). Sending it makes the search a round trip; see trip_type.
^\d{4}-\d{2}-\d{2}$oneway or roundtrip. Omit it and return_date decides: present is a round trip, absent a one-way trip. roundtrip requires return_date, and oneway refuses it (422 naming return_date).
oneway, roundtrip Omit this field or send null to let the provider default the search to economy without applying a cabin filter. Send an explicit enum value to require each fare’s representative cabin to equal it. The representative cabin is the cabin on the longest flight segment; shorter connecting segments may use another cabin. An omitted or null cabin applies no cabin filter.
economy, premium_economy, business, first "economy"
DEPRECATED — send max_stops: 0 instead. Still accepted: direct_only is folded into max_stops (true becomes max_stops: 0) before the search runs, so only max_stops reaches the platform. Setting it beside a non-zero max_stops is rejected.
false
Maximum stops per leg: 0 non-stop (the way to ask for direct flights), 1 one connection, 2 two. Applies to every leg of the trip.
0 <= x <= 21
Branded fare ladder: several fares per itinerary (upsell options). Defaults to true when omitted; send false for a single fare per itinerary and a smaller response. An offer carries at most 10 fares, the cheapest fare of each cabin kept first; a provider that sells no fare ladder returns a single fare either way.
true
Drop fares whose total price (all passengers) exceeds this cap, in currency, major units. A fare priced in another currency is usually converted to currency with the platform’s FX rate before the comparison, but not always: a provider whose first priced offer is already in currency drops its offers in other currencies as unverifiable instead of converting them. A fare whose currency cannot be converted is not returned.
x > 0800
Keep only itineraries marketed by these IATA carriers. Matching means every segment is marketed by a listed carrier (codeshares count by marketing carrier). When nothing matches, the search returns no offers with result: no_matches; the platform never widens to other carriers.
^[A-Za-z0-9]{2}$["AF", "DL"]
Drop itineraries marketed by these IATA carriers. Must not overlap include_carriers.
^[A-Za-z0-9]{2}$["NK"]
Filter the OUTBOUND leg by local departure time-of-day.
Show child attributes
Show child attributes
Filter the OUTBOUND leg by local arrival time-of-day.
Show child attributes
Show child attributes
Filter the RETURN leg by local departure time-of-day (round-trip only).
Show child attributes
Show child attributes
Filter the RETURN leg by local arrival time-of-day (round-trip only).
Show child attributes
Show child attributes
Shortest acceptable layover, in minutes, applied to every connection of every leg. Must not exceed connection_time_max_minutes. Conservative, like refundable_only: an itinerary with a connection whose times are unknown cannot be checked and is dropped.
x >= 060
Longest acceptable layover, in minutes, applied to every connection of every leg. Conservative in the same way as connection_time_min_minutes: a connection whose times are unknown drops the itinerary.
x >= 0240
Cap each leg’s door-to-door elapsed travel time, in minutes.
x > 0900
Keep only fares that can be cancelled before departure (with or without a fee). Conservative: a fare whose rules the platform cannot verify is DROPPED, so carriers that publish no rule data disappear under this filter. The filter reads the before-departure cancellation rules only; is_refundable on a returned fare is a wider reading of the same rules (it is true on a fare whose only decided rule allows cancellation after departure), so the flag is not this filter.
true
Keep only fares that allow a voluntary change. Conservative in the same way as refundable_only: unverifiable fares are dropped. The filter reads the before-departure change rules only; is_changeable on a returned fare is the wider reading refundable_only describes.
true
Keep only fares whose price already includes a checked bag on EVERY segment. Conservative, like refundable_only: a segment that states no allowance makes the fare unverifiable and it is dropped. The response flag of the same name is read from the first segment that states an allowance, not from every segment, so without this filter a fare flagged checked_bag_included: true can still lack a free bag on a later segment.
true
Keep only itineraries marketed end-to-end by one carrier.
true
Restrict connections to these airports: an itinerary qualifies only when EVERY connection is one of them. Non-stop itineraries have no connection to check and are kept. Some providers are asked for at most the first 9 listed airports per leg; the whole list is still applied to what they return.
^[A-Za-z]{3}$["AMS"]
Ban connections at these airports. Must not overlap via_airports.
^[A-Za-z]{3}$["LHR"]
Keep only itineraries whose every segment flies one of these IATA equipment codes. Conservative, like refundable_only: a segment whose equipment is unknown makes the itinerary unverifiable and it is dropped, so a provider that reports no equipment (see aircraft on the segment) disappears under this filter entirely.
^[A-Za-z0-9]{3}$["320", "77W"]
ADDITIONAL departure airports searched alongside origin. Widening only — the anchor in origin is always searched, so this can add results but never remove any. THE ANCHOR DECIDES RANKING AND TRUNCATION, which makes the two airports NOT interchangeable: measured on one route, anchor JFK with alternate EWR returned 15 JFK / 35 EWR, while anchor EWR with alternate JFK returned 2 JFK / 48 EWR — 13 itineraries differed between the two. Put the airport that matters most in origin. Works with an airport or a city anchor: origin NYC with ["BOS"] searches New York's airports and Boston; an alternate inside the city is redundant and harmless. On a round trip the platform mirrors the list onto the return leg, so it also covers where the return lands. Some providers search only the anchor.
^[A-Za-z]{3}$["EWR", "LGA"]
ADDITIONAL arrival airports searched alongside destination. Widening only — the anchor in destination is always searched, so this can add results but never remove any. THE ANCHOR DECIDES RANKING AND TRUNCATION, which makes the two airports NOT interchangeable the same way origin_alternate_airports describes: put the airport that matters most in destination. Works with an airport or a city anchor, as origin_alternate_airports describes. On a round trip the platform mirrors the list onto the return leg, so it also covers where the return departs from. Some providers search only the anchor.
^[A-Za-z]{3}$["ORY"]
Also search the alternate airports around each leg’s origin and destination. Widening: more results, not fewer.
true
Keep only itineraries whose connections leave from the same airport they arrived at (no cross-town transfer).
true
Keep only round trips that return to the airport the trip departed from. Round trip only: on a one-way search it is accepted and has no effect.
true
Keep only round trips whose return departs from the airport the outbound arrived at. Round trip only: on a one-way search it is accepted and has no effect.
true
TOTAL number of flights to return (1–300), not a per-page size: limit: 5 returns at most five flights. Search mode only. Omit to let the platform choose: the cheapest flight plus up to 100 alternatives, so up to 101 flights. Applied after the cross-provider merge and sort, so it only trims the returned set — the providers still bound the real count.
1 <= x <= 30020
Adult travelers (12+). At most 9 travellers who need a seat: adults + children ≤ 9. Lap infants are not counted.
x >= 1Child travelers (2–11). At most 9 travellers who need a seat: adults + children ≤ 9. Lap infants are not counted.
x >= 0Infant travelers (under 2), traveling on an adult’s lap. Seated infants (own seat) are not supported.
x >= 0ISO 4217 currency code, case-insensitive (eur is EUR): prices come back with the upper-case code and a display. Defaults to USD. A currency the platform cannot price in is refused with 400.
Price-check mode: re-price one known offer instead of searching a route. Route and filter fields are not allowed beside it (422); the passenger counts and currency are. Two kinds of token behave differently. A cached-itinerary offer_token from flight_calendar, find_dates, lowest_fare, find_destination or a price monitor is re-shopped LIVE on its route and dates with no cabin, stop or carrier constraint: offers[0] is the cheapest live offer with the same flights and cabin when one exists, exact_match_found says whether it did, and up to 100 alternatives follow. An offer_id from an earlier flight_search is answered from the cache of that search without re-pricing (exact_match_found: true), unless the passenger counts or currency differ, in which case it is re-shopped; once every fare of the cached offer has passed its expires_at it answers 410 OFFER_EXPIRED: search again.
"offer__3a9f1b27"
Show child attributes
Show child attributes
Response
Priced offers. Every filter that narrows the results (cabin, stops, price, carriers, times, connections, fare conditions, aircraft) is applied exactly as sent: no returned offer breaks one. Options that widen a search (alternate or nearby airports) are searched where available. A search that completes and matches nothing is also a 200: offers is empty, result is no_matches and the body carries a recovery instruction. A search that could not be completed answers an error (UPSTREAM_REJECTED, UPSTREAM_ERROR, UPSTREAM_UNAVAILABLE or UPSTREAM_TIMEOUT) rather than an empty list. Offers that were found are returned even when part of the search could not be completed.
Show child attributes
Show child attributes
Price-check mode only (request carried offer_token): true when the live offer has the same flights as the cached one. Absent in search mode.
true
Search mode only. no_matches means the search completed and no offer matched: relay instruction, which asks which filter to relax only when the request sent a filter that narrows the results. offers is empty. Absent when offers were found. A search that could not be completed at all answers an error instead (UPSTREAM_REJECTED, UPSTREAM_ERROR, UPSTREAM_UNAVAILABLE or UPSTREAM_TIMEOUT), never an empty list.
no_matches Present with result: no_matches: what to tell the user or do next. It attributes the empty result to the filters only when the request sent a filter that narrows the results; otherwise it reads "Search completed successfully, but no flights were found for this route and dates. Ask the user whether to try other dates or airports before searching again."
"Search completed successfully, but no offers satisfied every filter sent: the filter combination is too restrictive for this route and dates. Ask the user which filter to relax before searching again."
