Search flights
Search for flights across one, several or every enabled supplier. Start here, then expand the examples by route, passenger, filter, supplier or itinerary type.
POST/api/v1/get_flights
Search available flight offers across every compatible supplier. Results are grouped under suppliers[]: each supplier has its own searchId and its own list of offers.
Permission: Read (a read key is enough; so is a read+write key). Rate group: search, 6,000 requests per minute per key.
What to expect
- Size. A search returns 0.7 MB (one-way, two suppliers) to 14 MB of JSON (a busy round trip with 2,000 offers). Send
Accept-Encoding: gzip: the same 695 KB response is 26 KB on the wire. There is no pagination:results.totalOffersalways equals the length ofresults.offers. - Time. Two to eight seconds, because the response waits for the slowest supplier. To show the first fares after about two seconds, read the results as a stream.
- Partial results are normal. If at least one supplier answers, the status is
200and the others are listed infailures[]. Only when no supplier answers is the status503. - Values are read generously, garbage is refused. A value a real client can send (
"2"for a count,premium economyfor a cabin, a space between airline codes) is read, with acoerced_valuewarning when its meaning had to be guessed (Conventions). Only a value that makes no sense is a400with a stable code, before any supplier is called. - Identical searches are merged. Searches with the same parameters that arrive at the same moment from the same agency, environment and currency are merged into one supplier fan-out. Nothing is kept afterwards, and every caller still gets its own
requestIdand headers and asearchIdthat works withprice_flight. - Sandbox suppliers.
amadeus_aqc_dz_1(Amadeus Algeria, only for routes that touch Algeria; supports hold, void and flexible dates) andduffel_1(Duffel, worldwide; instant ticketing only). See Supplier selection.
Request fields
Route
| Field | Type | Required | Description |
|---|---|---|---|
origin | string | Yes¹ | Departure IATA code: three ASCII letters, an airport (ALG, CDG) or a city (PAR, LON). Lower case is accepted and read as upper case. |
destination | string | Yes¹ | Arrival IATA code. Must differ from origin. |
departure_date | string | Yes¹ | YYYY-MM-DD, a real calendar date from yesterday (time-zone slack) up to 365 days ahead (date_too_far beyond). |
return_date | string | No | Makes the search a round trip. On or after departure_date, and within the same 365 days. |
segments | array | No² | 1 to 6 flights { origin, destination, departure_date } instead of the four fields above. Dates must not go backwards. See Open-jaw and multi-city. |
url | string | No | A path-style search used by FX-Port's own site, for example flights/. It wins over every route field. Prefer the fields above: they are validated field by field. |
¹ Required unless segments or url is sent. ² A list of segments replaces origin, destination, departure_date and return_date.
The type of the search comes from the route: one segment is ONE_WAY; two segments where the second is the exact reverse of the first (or return_date) is ROUND_TRIP; two segments that are not reverses is OPEN_JAW; three or more is MULTI_CITY.
Several airports can be written "ALG,ORN" or as a list ["ALG","ORN"] (up to five, in origin and destination only: a segment takes one code): the first one is searched and the others are kept as alternatives that a supplier may ignore (Duffel does). Search one airport per request when you need a predictable result.
Passengers and cabin
| Field | Type | Required | Description |
|---|---|---|---|
passengers | object | No | Counts and age lists. Optional: the default is one adult. See Flight passengers & ages. |
cabin_class | string | No | economy (default), premium_economy, business, first or any (no cabin restriction). Case, spaces, dashes and underscores do not matter: Premium Economy, premium-economy and PREMIUM_ECONOMY are the same cabin. premium, economy_class, business_class, first_class and premium_economy_class are read as their cabin with a coerced_value warning, and an empty text means the default cabin. Any other value (coach, Y) is rejected with 400 invalid_cabin_class. |
The cabin you send is lower case; the cabin of each segment in the response is upper case (ECONOMY, PREMIUM_ECONOMY, BUSINESS, FIRST).
Filters
| Field | Type | Description |
|---|---|---|
nonstop | boolean | true returns non-stop offers only. |
refundable | boolean | true asks the supplier for refundable fares. A hint, not a guarantee: see the table below. |
checked_bags | boolean | true asks for fares with a checked bag included. |
max_price | number | A price ceiling. Not enforced in the sandbox; see below. 0, an empty text and null mean no ceiling: the field is ignored (0 and an empty text add a coerced_value warning). Numeric text ("1500") is read as a number with a warning. A negative or non-numeric value ("cheap", "150000 DZD") is 400 invalid_field_type. |
included_airlines | string[] or text | Up to 20 airline codes: ["AF","AH"], or a text with the codes separated by commas, semicolons, bars or spaces ("AF,AH", "AF AH"). Only these carriers. |
excluded_airlines | string[] or text | Up to 20 airline codes to remove, written like included_airlines. |
preferred_airlines | string[] or text | Behaves exactly like included_airlines: a strict allow-list, not a ranking. |
flexible | boolean | Also returns the date matrix (flexPrices) from suppliers that support it, next to the offers. See Flexible-date search. |
flexible_only | boolean | The matrix without offers. POST / sends it for you. |
from_cc, to_cc | string | ISO country codes of the origin and the destination: exactly two letters (DZ; a three-letter value is 400 invalid_country_code). Used to choose suppliers; see Supplier selection. |
countries | string[] | Up to 10 country codes of the route, when you want to override the countries FX-Port infers from the airports. |
filters | object | Only the three airline lists above are read from it. Any other key ({"max_stops": 0}) is ignored. |
What each supplier enforces. filtersApplied in the response repeats what you asked for, for every supplier, not what the supplier honoured:
| Filter | Amadeus Algeria (amadeus_aqc_dz_1) | Duffel (duffel_1) |
|---|---|---|
nonstop | Enforced. | Enforced. |
refundable | Sent to the supplier; the result still mixes refundable and non-refundable fares (70 offers became 53, still mixed). | Ignored. |
checked_bags | Enforced (included checked bags only). | Ignored: offers with no checked bag are returned. |
max_price | Sent in the supplier's currency (DZD), and not enforced in the sandbox: with max_price: 40000 offers up to 242,844 DZD came back. | Never sent; offers up to 280,279 DZD came back. |
included_airlines, preferred_airlines | Native carrier restriction: the validating carrier is in the list. | A filter on the returned offers: an offer stays when any marketing, operating or validating carrier matches, so validatingAirline can be a carrier you did not list. |
excluded_airlines | Native. | A filter on the returned offers. |
Always read the offer itself (pricing, travelerPricing[].fareDetailsBySegment[].includedCheckedBags, conditions) and filter again on your side when a filter is a hard requirement. You can send included_airlines and excluded_airlines together: the excluded codes are taken out of the included list.
Supplier selection
| Field | Type | Description |
|---|---|---|
| (none) | Recommended. FX-Port selects the compatible suppliers. | |
supplier_id | string | Restrict the search to one supplier id (a comma separated list is accepted). Strict: an unknown or disabled id is 400 invalid_supplier_selection. |
supplier_ids | string[] | Restrict the search to this set. Strict, up to 10. Merged with supplier_id. |
preferred_suppliers | string[] | A hint: ids that are not usable are ignored and the automatic selection applies. |
max_suppliers | integer | Keep only the first N selected suppliers, in priority order. "3" and 3.0 are read as 3 with a coerced_value warning; an empty text means no limit. |
Other fields
| Field | Type | Description |
|---|---|---|
loyalty_program_accounts | array | Up to 10 frequent-flyer accounts { airline_iata_code, account_number, first_name, last_name }. They are stored with the search and matched by passenger name at booking. |
acd_exempt_company_id | string | For agencies that settle in DZD and have an ACD-exempt company: its id, to price the fares without ACD. A company that is not linked to your agency is 403 acd_exemption_invalid, a non-DZD agency 403 acd_exemption_currency. See ACD passport uploads. |
agent_id | string | Your own id of the agent who searches; stored with the search and the booking. |
Legacy names
These spellings still work. The response says so in warnings (deprecated_field) and in the headers Deprecation and X-FX-Deprecated-Fields. New code should send the name in the second column. If a request holds a legacy name and its replacement with different values (direct and nonstop), the replacement wins and an ignored_field warning names the dropped one.
| Legacy name | Use instead |
|---|---|
departureDate, returnDate, cabinClass | departure_date, return_date, cabin_class |
travelers | passengers |
direct | nonstop |
checkedBags, maxPrice, flexibleOnly | checked_bags, max_price, flexible_only |
fromCc, toCc | from_cc, to_cc |
supplierId, supplierIds, preferredSuppliers, maxSuppliers | supplier_id, supplier_ids, preferred_suppliers, max_suppliers |
includedAirlines, include_airlines, includeAirlines, included_airline, include_airline, airline_include, airlineInclude | included_airlines |
excludedAirlines, exclude_airlines, excludeAirlines, excluded_airline, exclude_airline, airline_exclude, airlineExclude | excluded_airlines |
preferredAirlines, airlines | preferred_airlines |
passengers.young, passengers.youngAdults | passengers.young_adults |
passengers.toddlers, passengers.seatedInfants | passengers.seated_infants |
passengers.childAges, youngAdultAges, seatedInfantAges, infantAges | passengers.child_ages, young_adult_ages, seated_infant_ages, infant_ages |
segments[].date, segments[].departureDate, segments[].departure | segments[].departure_date |
agentId, acdExemptCompanyId, loyaltyProgramAccounts | agent_id, acd_exempt_company_id, loyalty_program_accounts |
A key the endpoint does not read at all (a typo, the flat adults, max_stops inside filters) never fails the request: it is ignored and reported as an ignored_field warning.
Examples by category
Minimal request
curl https://api.fx-port.com/api/v1/get_flights \
-H "Authorization: Bearer fxp_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"origin": "ALG",
"destination": "CDG",
"departure_date": "2026-12-15",
"cabin_class": "economy",
"passengers": {
"adults": 1
}
}'Response essentials
The example is a trimmed real sandbox response to the request above: the Duffel entry with one non-stop offer (the sandbox airline ZZ is Duffel's test carrier). The other supplier's entry has the same shape. Arrays are cut and the amenities list is shortened; the field tables below describe everything that is not shown.
{
"environment": "sandbox",
"success": true,
"requestId": "54139f32",
"searchType": "ONE_WAY",
"flexible": false,
"processingTime": 2.243,
"suppliers": [
{
"success": true,
"searchId": "fs_dfx_a3aeaa36-74ad-424b-b88d-e6bdc9a4ba94",
"supportHold": false,
"supportVoid": false,
"voidDeadline": null,
"filtersApplied": {},
"warnings": [],
"meta": {
"supplierId": "duffel_1",
"technologyType": "duffel",
"supplierName": "Duffel",
"processingTime": 1.34,
"supplierCurrency": "USD",
"agencyCurrency": "DZD"
},
"results": {
"totalOffers": 92,
"supplierCurrency": "USD",
"agencyCurrency": "DZD",
"offers": [
{
"id": "fx_offer_9ab6d940",
"type": "flight_offer",
"supplier": { "id": "duffel_1", "name": "Duffel", "originalId": "off_034q6JKdiQDZ8HIDMFus64" },
"bookableSeats": null,
"supportHold": false,
"supportVoid": false,
"voidDeadline": null,
"filtersApplied": {},
"warnings": [],
"instantTicketingRequired": false,
"lastTicketingDate": "2026-11-01",
"lastTicketingDateTime": "2026-11-01T15:52:40.830072Z",
"pricing": {
"supplierCurrency": "USD",
"agencyCurrency": "DZD",
"basePrice": 16385.0,
"taxesAndFees": 5226.2,
"agencyCommission": 21.62,
"finalPrice": 21632.82,
"b2bPrice": 21611.2,
"additionalServices": []
},
"itinerary": [
{
"direction": "outbound",
"duration": "PT2H24M",
"stops": 0,
"segments": [
{
"id": "seg_0000BC0a5iUChSV6Qrz0Co",
"departure": {
"airportCode": "ALG",
"airportName": "Houari Boumediene Airport",
"cityName": "Algiers",
"countryCode": "DZ",
"terminal": "2",
"datetime": "2026-12-15T10:50:00",
"timeZone": "Africa/Algiers"
},
"arrival": {
"airportCode": "CDG",
"airportName": "Paris Charles de Gaulle Airport",
"cityName": "Paris",
"countryCode": "FR",
"terminal": "1",
"datetime": "2026-12-15T13:14:00",
"timeZone": "Europe/Paris"
},
"flight": {
"carrierCode": "ZZ",
"carrierName": "Duffel Airways",
"carrierLogoUrl": "https://assets.duffel.com/img/airlines/for-light-background/full-color-logo/ZZ.svg",
"flightNumber": "7426",
"aircraftCode": null,
"aircraftName": null,
"operatingCarrier": "ZZ",
"operatingCarrierName": "Duffel Airways"
},
"duration": "PT2H24M",
"cabin": "ECONOMY",
"bookingClass": null,
"fareBasis": "Y20LGTN2",
"brandedFare": "BASIC",
"brandedFareLabel": "Basic"
}
],
"conditions": {
"changeBeforeDeparture": { "allowed": false },
"refundBeforeDeparture": { "allowed": false }
}
}
],
"travelerPricing": [
{
"travelerId": "pas_0000BC0a5iH5UE0bmBqWkl",
"travelerType": "ADULT",
"fareOption": "STANDARD",
"price": {
"supplierCurrency": "USD",
"agencyCurrency": "DZD",
"base": 16385.0,
"total": 21632.82,
"b2bPrice": 21611.2
},
"fareDetailsBySegment": [
{
"segmentId": "seg_0000BC0a5iUChSV6Qrz0Co",
"cabin": "ECONOMY",
"fareBasis": "Y20LGTN2",
"brandedFare": "BASIC",
"brandedFareLabel": "Basic",
"bookingClass": null,
"includedCheckedBags": { "quantity": 1 },
"includedCabinBags": { "quantity": 1 },
"amenities": [
{ "description": "WIFI", "isChargeable": true, "amenityType": "WIFI", "amenityProvider": { "name": "BrandedFare" } }
]
}
]
}
],
"conditions": {
"refundBeforeDeparture": { "allowed": false },
"changeBeforeDeparture": { "allowed": false }
},
"fareRules": {
"exchange": { "allowed": false },
"refund": { "allowed": false },
"revalidation": { "allowed": false },
"supplierCurrency": "USD",
"agencyCurrency": "DZD"
},
"validatingAirline": [{ "code": "ZZ", "name": "Duffel Airways" }]
}
]
},
"exchangeRate": 250.0
}
],
"summary": { "totalSuppliers": 2, "successfulSuppliers": 2, "failedSuppliers": 0, "totalOffers": 158 }
}Names: next to the keys you feed back into the next calls the response adds snake_case twins with the same value. At the top level: request_id, processing_time, search_type. In each supplier entry: search_id, support_hold, support_void, void_deadline, exchange_rate, filters_applied, and meta.supplier_id, meta.supplier_name, meta.processing_time. In each offer: offer_id (next to id), support_hold, support_void, void_deadline, pricing.base_price, pricing.taxes_and_fees, pricing.agency_commission, pricing.final_price, pricing.b2b_price, and passenger_id and passenger_type in each travelerPricing entry. Add ?naming=snake to get every key in snake_case. See Conventions and naming.
Top-level response fields
| Field | Type | Meaning |
|---|---|---|
environment | string | sandbox or live, from your key. |
success | boolean | true on every 200, even if some suppliers failed: read suppliers[n].success and failures. |
requestId | string | The id of this search, for support. |
searchType | string | ONE_WAY, ROUND_TRIP, OPEN_JAW or MULTI_CITY, derived from your route. |
flexible | boolean | Whether the date matrix was requested. |
flexibleOnly | boolean | Only present (and true) for flexible search. |
processingTime | number | Seconds spent by the whole search. |
suppliers | array | One entry per supplier that answered; see below. |
summary | object | totalSuppliers and successfulSuppliers (both count the suppliers that answered), failedSuppliers (the ones listed in failures) and totalOffers. |
failures | array | Only when a supplier failed: { supplierId, error, cause } (twin: supplier_id). cause is a stable code: supplier_timeout, supplier_api_error, supplier_auth_error, supplier_error, supplier_temporarily_unavailable (the supplier is skipped for a short while), supplier_busy (FX-Port's capacity towards that supplier is full for a moment: the supplier was not called, retry in a few seconds) or service_overloaded (FX-Port was too busy to prepare that supplier's results: retry in a few seconds). error is a fixed sentence about the cause, never the supplier's own text. |
warnings | array | Only when the request used a legacy name, an ignored field or a value that was adjusted. See Conventions and naming. |
suppliers[n] fields
| Field | Type | Meaning |
|---|---|---|
success | boolean | Whether this supplier returned usable results. |
searchId | string | Save this. fs_<uuid> (Amadeus Algeria) or fs_dfx_<uuid> (Duffel). Required as search_id by price_flight and book_flight. It is valid for 24 hours, but a supplier withdraws offers earlier: price soon after you show an offer. |
supportHold, supportVoid | boolean | What the supplier can do in general; re-read them on the priced offer before you choose between hold and issue. |
voidDeadline | string or null | ISO 8601 UTC: the end of the same-day void window (midnight in the supplier's time zone, Africa/ for Amadeus Algeria). null when the supplier cannot void. |
filtersApplied | object | The filters you asked for, echoed (see above). |
warnings | array | Notes of the supplier; empty in every sample. |
meta | object | supplierId, supplierName, technologyType (amadeus_aqc, duffel), processingTime, supplierCurrency, agencyCurrency. |
results | object | totalOffers, supplierCurrency, agencyCurrency, offers. |
exchangeRate | number | Only when the supplier's currency is not your agency's (Duffel, USD to DZD: 250.0). |
flexPrices | object | Only with flexible: true from a supplier that supports it. |
offers[n] fields
| Field | Type | Meaning |
|---|---|---|
id | string | Save this. fx_offer_ and 8 hex characters. Required as offer_id by price and book. |
type | string | Always flight_offer. |
supplier | object | id, name and originalId (the supplier's own id of the offer: for support only). |
bookableSeats | integer or null | Seats left at this fare, when the supplier says (Amadeus: up to 9). |
supportHold, supportVoid, voidDeadline | As on the supplier, for this offer. | |
instantTicketingRequired | boolean | true: the fare cannot be held; book it with booking_type: "issue". |
lastTicketingDate, lastTicketingDateTime | string | Duffel only: when the offer stops being sellable. Typically 15 to 60 minutes after the search. |
pricing | object | Every field is explained in Flight pricing. Amadeus Algeria adds acd. |
itinerary | array | One entry per direction; see below. |
travelerPricing | array | One entry per priced traveler; see below. |
conditions | object | refundBeforeDeparture.allowed and changeBeforeDeparture.allowed: indicative, not a promise. |
fareRules | object | exchange, refund, revalidation (each { allowed }) and the two currencies. |
validatingAirline | array | { code, name } of the airline whose rules and ticket stock govern the fare. |
additionalServices | array | Amadeus only: paid extras the supplier lists. |
requiresACD | boolean | Amadeus Algeria only, present only when true: after booking, passports must be uploaded. See ACD passport uploads. |
filtersApplied, warnings | As on the supplier. |
itinerary[n] and segments[n] fields
| Field | Type | Meaning |
|---|---|---|
direction | string | outbound, return, and segment_3, segment_4 ... for the third and later legs of a multi-city search. |
duration | string | ISO 8601 duration of the direction, for example PT2H24M. |
stops | integer | Number of stops (0 is non-stop). |
segments[n].id | string | Id of the segment; fareDetailsBySegment[].segmentId points to it. |
segments[n].departure, .arrival | object | airportCode, airportName, cityName, countryCode, terminal (can be null), datetime (local time, no zone), timeZone (IANA). |
segments[n].flight | object | carrierCode, carrierName, carrierLogoUrl, flightNumber (without the carrier code: 7426), aircraftCode, aircraftName (can be null), operatingCarrier, operatingCarrierName. Different carriers mean a codeshare. |
segments[n].duration | string | ISO 8601 duration of the flight. |
segments[n].cabin | string | ECONOMY, PREMIUM_ECONOMY, BUSINESS or FIRST for this segment; it can differ from the cabin you asked for. |
segments[n].bookingClass | string or null | Booking class letter (Amadeus: Q, O; Duffel: null). |
segments[n].fareBasis, .brandedFare, .brandedFareLabel | string | Fare basis code, fare family code and its display label. |
conditions | object | Refund and change rules of this direction. |
travelerPricing[n] fields
| Field | Type | Meaning |
|---|---|---|
travelerId | string | "1", "2" ... (Amadeus) or pas_... (Duffel). |
travelerType | string | ADULT, SENIOR, YOUNG, CHILD, SEATED_INFANT or HELD_INFANT (a lap infant). |
fareOption | string | The fare option, for example STANDARD. |
price | object | The traveler's share: supplierCurrency, agencyCurrency, base, total, b2bPrice. |
fareDetailsBySegment[n] | array | segmentId, cabin, fareBasis, brandedFare, brandedFareLabel, bookingClass, includedCheckedBags.quantity, includedCabinBags.quantity and amenities[] (description, isChargeable, amenityType, amenityProvider). |
The entries are grouped by type (adults, then seniors, children ...), not in the order you would list the travelers: a request has no passenger order. Each traveler's price.total adds up to the offer's pricing.finalPrice.
Save these values
| Value | Where | Used by |
|---|---|---|
searchId | suppliers[n].searchId | price_flight.search_id, then book_flight.search_id |
offer id | suppliers[n].results.offers[m].id | price_flight.offer_id, then book_flight.offer_id |
supportHold | supplier and priced offer | Choose hold only when it is still true after pricing |
requiresACD | offer | Plan the ACD passport upload |
Streaming
Add ?stream=true (or send Accept: text/) to receive the same search as server-sent events: a first event after about half a second, the first offers after about two seconds, and the rest as each supplier answers. See Streaming search results for the events, the merge rules, the client code in nine languages and the Cloudflare notes. Keep at most 4 streams open at the same time for one API key.
Errors
The error body is described in Errors. Branch on errors[0].code.
| Status | Code | When | What to do |
|---|---|---|---|
400 | invalid_json, invalid_body | The body is not JSON, or not a JSON object, or is nested more than 24 levels deep, or holds a text longer than 256 characters. | Send one JSON object with Content-Type: application/. |
400 | missing_search_params | Neither a url, nor segments, nor the three fields origin, destination and departure_date. The body has example_params and example_url. | Send a route. |
400 | missing_field | A segment lacks origin, destination or departure_date. errors[0].field is the path, for example segments[1].departure_date. | Send the field it names. |
400 | invalid_airport_code | An IATA code that is not three ASCII letters (up to five codes in "ALG,ORN"), or an origin equal to the destination. | Use three letters; PAR and LON city codes are valid. |
400 | invalid_date, date_in_past, date_too_far, return_before_departure | A date that is not a real YYYY-MM-DD, is earlier than yesterday, is more than 365 days ahead, or a return (or a later segment) before the departure. | Fix the date. |
400 | invalid_cabin_class | cabin_class is not one of the five values, once case, spaces, dashes and underscores are ignored. errors[0].details.allowed lists them. | Send one of the five values. |
400 | invalid_passenger_count, invalid_passenger_age | A count that is not a whole number from 0 to 99, or an age that is not a whole number from 0 to 17. Numeric text and integral floats ("2", 2.0) are read with a coerced_value warning; words, fractions, booleans, negatives and bigger numbers are refused. | Fix the number. |
400 | traveler_rule_violation | The mix breaks a rule: more than 9 seated passengers, more lap infants than adults and seniors, or more seated infants under 2 than adults and seniors. This answer keeps its older flat body: error: "TRAVELER_RULE_VIOLATION" and violations[] with one entry per broken rule. | See Flight passengers & ages. |
400 | invalid_supplier_selection | An unknown or disabled supplier, or a supplier that cannot do flexible search. availableSuppliers lists the usable ids. | Remove the selector or use an available id. |
400 | supplier_passenger_combination_unsupported | No selected supplier can serve the passenger mix (for example one adult with a seated and a lap infant, with only Duffel available). | Change the mix, or select another supplier. |
400 | invalid_airline_filter, invalid_field_type, invalid_segments, invalid_country_code, invalid_currency, invalid_url | A filter or a field has the wrong type or shape; errors[0].field names it. | Fix the field. |
403 | acd_exemption_invalid, acd_exemption_currency | acd_exempt_company_id is not usable by this agency. | Remove it, or use a company linked to your agency. |
413 | request_too_large | The body is larger than 64 KB, or holds more than 5,000 values. | Send a smaller body. |
422 | no_supplier_supports_flexible_search | flexible_only (or POST /) on a route that no flexible-capable supplier serves. | Use get_flights for fixed dates. |
503 | all_suppliers_failed | No supplier returned results. supplierErrors[] lists { supplierId, cause, message } with cause one of supplier_timeout, supplier_api_error, supplier_auth_error, supplier_error, supplier_temporarily_unavailable, supplier_busy, service_overloaded and a fixed sentence: the supplier's own text is never returned. | A well-formed airport code that does not exist, a date the supplier has no schedule for, or a supplier outage all end here. Wait, then retry with backoff, or search another route. |
503 | supplier_busy | Every supplier refused the search because FX-Port's capacity towards it is full for a moment. The suppliers were not called, nothing was booked and nothing was charged. The answer carries Retry-After (seconds). | Wait for Retry-After, then send the same request again: it is safe. |
503 | service_overloaded | FX-Port was busy preparing other large search answers and no worker became free within a few seconds, so this search could not be completed. Nothing was booked and nothing was charged. The answer carries Retry-After (seconds). | Retry with backoff: wait for Retry-After, then send the same request again. |
Invalid input is refused before any supplier is called, so it never costs a supplier request and never counts against a supplier. A supplier that keeps failing is skipped for a short while and listed in failures[] with the cause supplier_temporarily_unavailable; the others still answer. A supplier whose capacity is full for a moment is listed the same way with the cause supplier_busy while the others answer; only when every supplier is busy is the whole search refused with 503 supplier_busy and Retry-After. service_overloaded works like supplier_busy when FX-Port itself was too busy to prepare a supplier's results (one supplier: failures[]; all of them: 503). Neither makes FX-Port skip the supplier for later searches.
Test it in the sandbox
| You want | Send |
|---|---|
| Both suppliers | ALG to CDG, one adult, a date 30 days ahead |
| A fare you can hold | A route that touches Algeria; read supportHold on the offer and the supplier amadeus_aqc_dz_1 |
| An instant-only fare | "supplier_id": "duffel_1" |
| An offer that needs ACD passports | CDG to ALG with "supplier_id": "amadeus_aqc_dz_1": every offer has pricing.acd.applied: true |
| Round trip, open-jaw, multi-city | The examples of Basic routes and Open-jaw and multi-city |
| An error | "cabin_class": "luxury" returns 400 invalid_cabin_class before any supplier is called |
| A value that is read, with a warning | "passengers": { "adults": "2" } is searched as 2 adults and the answer carries a coerced_value warning; "adults": "two" is 400 invalid_passenger_count |
Related
- Price a flight offer: the required next step.
- Streaming search results and Flexible-date search.
- API reference: Search flights and the Flight offer object.