Book a flight offer
Book an offer you have priced: ticketed at once (booking_type: issue) or held without payment (hold).
/api/v1/flights/book_flightPrice the offer first with price_flight: an offer that was not priced is refused with 404 offer_not_priced. Send the search_id and the offer_id, one object for each traveler in passengers (lap infants included, at most 18) and contact_details with the email and the phone_number, both required. Send the passport of every traveler: airlines can require it. booking_type is issue by default; hold is only valid when supportHold is true on the priced offer (400 hold_not_supported otherwise), and a hold is paid later with pay_order. An unknown booking_type is refused with 400: it never becomes an order.
The answer is the order: booking.pnr, the supplier's order id in booking.reference (use it as order_id afterwards) and in postProcessing.bookingDbId the FX-Port id (a UUID, the stable key of the booking), then the price block, the passengers and the itinerary. In the sandbox nothing is charged (balanceDebited: false); send send_email: false to keep the confirmation e-mail from going out. A fare with pricing.acd.applied: true also carries requiresACD: true: the booking needs one passport copy for every traveler, see Upload ACD documents.
A failed booking is always a JSON body: 409 when the offer or the search was already booked, 503 when the supplier failed with a 5xx status, 422 for every other refusal of the supplier. You never receive an HTML 502 page. Duffel allows one booking per search: book a second offer of a search that was booked and you get 409.
curl https://api.fx-port.com/api/v1/flights/book_flight \
-H "Authorization: Bearer fxp_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"search_id": "fs_85ac5f12-7456-4edf-a2fb-1d51239d278b",
"offer_id": "fx_offer_9de60e2a",
"booking_type": "hold",
"send_email": false,
"passengers": [
{
"type": "adult",
"gender": "MALE",
"first_name": "James",
"last_name": "Smith",
"date_of_birth": "1988-06-15",
"identity_documents": [
{
"type": "passport",
"number": "A12345678",
"issuing_country": "DZ",
"expiry_date": "2031-04-18"
}
]
}
],
"contact_details": {
"email": "[email protected]",
"phone_number": "+15555550123"
}
}'{
"environment": "sandbox",
"success": true,
"requestId": "66e4b1a8",
"searchId": "fs_85ac5f12-7456-4edf-a2fb-1d51239d278b",
"offerId": "fx_offer_9de60e2a",
"processingTime": 2.6235511302948,
"booking": {
"reference": "eJzTd9ePNA9wdA0FAAs8AmE",
"status": "pending",
"pnr": "Y7PAEU",
"type": "hold",
"createdAt": "2026-11-01T15:26:00.000",
"cancelledAt": null,
"content": "managed",
"syncedAt": "2026-11-01T15:26:00.000",
"availableActions": [
"confirm",
"cancel"
],
"voidableUntil": null,
"cancellation": null
},
"supplier": {
"id": "amadeus_aqc_dz_1",
"technology": "amadeus_aqc",
"name": "Amadeus AQC",
"offerId": "3"
},
"agency": {
"currency": "DZD"
},
"pricing": {
"supplierCurrency": "DZD",
"agencyCurrency": "DZD",
"basePrice": 3160,
"taxesAndFees": 1765.44,
"agencyCommission": 4.93,
"finalPrice": 4930.37,
"b2bPrice": 4925.44,
"additionalServices": [],
"acd": {
"applied": false
}
},
"payment": {
"status": "awaiting_payment",
"paidAt": null,
"paymentRequiredBy": null,
"priceGuaranteeExpiresAt": null,
"awaitingPayment": true
},
"documents": [],
"bookingReferences": [
{
"pnr": "Y7PAEU",
"carrier": {
"iataCode": "AH",
"name": "Air Algerie",
"logoUrl": "https://assets.duffel.com/img/airlines/for-light-background/full-color-logo/AH.svg",
"logoLockupUrl": "https://assets.duffel.com/img/airlines/for-light-background/full-color-lockup/AH.svg"
}
}
],
"passengers": [
{
"id": "1",
"type": "ADULT",
"title": "mr",
"givenName": "JAMES",
"familyName": "SMITH",
"gender": "male",
"bornOn": "1988-06-15",
"email": "[email protected]",
"phoneNumber": "15555550123",
"infantPassengerId": null,
"loyaltyProgrammeAccounts": [],
"ticketNumber": null
}
],
"travelerPricing": [
{
"travelerId": "1",
"travelerType": "ADULT",
"fareOption": "STANDARD",
"price": {
"supplierCurrency": "DZD",
"agencyCurrency": "DZD",
"base": 3160,
"total": 4930.37,
"b2bPrice": 4925.44
},
"fareDetailsBySegment": [
{
"segmentId": "3",
"cabin": "ECONOMY",
"fareBasis": "Y",
"brandedFare": "STANDARD",
"brandedFareLabel": "STANDARD",
"bookingClass": "Y",
"includedCheckedBags": {
"quantity": 1
},
"includedCabinBags": {
"quantity": 1
},
"amenities": []
}
]
}
],
"itinerary": [
{
"direction": "outbound",
"duration": "PT1H",
"stops": 0,
"fareBrandName": "",
"origin": {
"airportCode": "ALG",
"airportName": "Houari Boumediene Airport",
"cityName": "Algiers",
"countryCode": "DZ",
"timeZone": "Africa/Algiers"
},
"destination": {
"airportCode": "ORN",
"airportName": "Oran International Airport",
"cityName": "Oran",
"countryCode": "DZ",
"timeZone": "Africa/Algiers"
},
"segments": [
{
"id": "3",
"departure": {
"airportCode": "ALG",
"airportName": "Houari Boumediene Airport",
"cityName": "Algiers",
"countryCode": "DZ",
"terminal": "1",
"datetime": "2026-12-22T19:45:00",
"timeZone": "Africa/Algiers"
},
"arrival": {
"airportCode": "ORN",
"airportName": "Oran International Airport",
"cityName": "Oran",
"countryCode": "DZ",
"terminal": null,
"datetime": "2026-12-22T20:45:00",
"timeZone": "Africa/Algiers"
},
"flight": {
"carrierCode": "AH",
"carrierName": "Air Algerie",
"carrierLogoUrl": "https://assets.duffel.com/img/airlines/for-light-background/full-color-logo/AH.svg",
"flightNumber": "6106",
"aircraftCode": "73H",
"aircraftName": null,
"operatingCarrier": "AH",
"operatingCarrierName": "Air Algerie",
"operatingFlightNumber": "6106"
},
"duration": "PT1H",
"distance": null,
"stops": [],
"cabin": "ECONOMY",
"cabinMarketingName": "Economy",
"fareBasis": "Y",
"brandedFare": "",
"brandedFareLabel": "",
"passengerDetails": [
{
"passengerId": "1",
"cabin": "ECONOMY",
"cabinMarketingName": "Economy",
"seat": null,
"checkedBags": {
"quantity": 1
},
"cabinBags": {
"quantity": 1
}
}
]
}
],
"conditions": {
"changeBeforeDeparture": {
"allowed": true
}
}
}
],
"conditions": {
"refundBeforeDeparture": {
"allowed": true
},
"changeBeforeDeparture": {
"allowed": true
}
},
"owner": {
"id": null,
"iataCode": "AH",
"name": "Air Algerie",
"logoUrl": "https://assets.duffel.com/img/airlines/for-light-background/full-color-logo/AH.svg",
"logoLockupUrl": "https://assets.duffel.com/img/airlines/for-light-background/full-color-lockup/AH.svg",
"conditionsOfCarriageUrl": null
},
"services": [],
"meta": {
"supportHold": true,
"supportVoid": true,
"voidDeadline": "2026-11-01T23:00:00Z",
"voidWindowEndsAt": null,
"airlineInitiatedChanges": [],
"changes": [],
"users": [],
"orderMetadata": null
},
"fareRules": {
"refund": {
"allowed": true
},
"exchange": {
"allowed": true
},
"agencyCurrency": "DZD"
},
"postProcessing": {
"bookingDbId": "711371c3-00aa-4be2-b790-9f0ca2ccfdb7",
"bucketLink": null,
"emailSent": false
},
"balanceDebited": false,
"transactionCreated": false,
"payoutCreated": false
}{
"environment": "sandbox",
"success": true,
"requestId": "7b166b31",
"searchId": "fs_dfx_88eb64c9-6c36-47e6-bdaa-9ad3c1377ac4",
"offerId": "fx_offer_b7a95439",
"processingTime": 0.40790867805480957,
"booking": {
"reference": "ord_0000BC0UuqWJKkrDO331Xc",
"status": "confirmed",
"pnr": "BOKT52",
"type": "instant",
"createdAt": "2026-11-01T14:24:41.453265Z",
"cancelledAt": null,
"content": "managed",
"syncedAt": "2026-11-01T14:24:41Z",
"availableActions": [
"cancel",
"change"
],
"voidableUntil": null,
"cancellation": null
},
"supplier": {
"id": "duffel_1",
"technology": "duffel",
"name": "Duffel",
"offerId": "off_034q4rP6NMvbRSHMkUPbTE"
},
"agency": {
"currency": "DZD"
},
"pricing": {
"supplierCurrency": "USD",
"agencyCurrency": "DZD",
"basePrice": 16342.51,
"taxesAndFees": 5216.69,
"agencyCommission": 21.56,
"finalPrice": 21580.76,
"b2bPrice": 21559.2,
"additionalServices": []
},
"payment": {
"status": "paid",
"paidAt": "2026-11-01T14:24:41Z",
"paymentRequiredBy": null,
"priceGuaranteeExpiresAt": null,
"awaitingPayment": false
},
"documents": [
{
"type": "electronic_ticket",
"uniqueIdentifier": "1",
"passengerIds": [
"pas_0000BC0UogJGYlTqCNHhye"
]
}
],
"bookingReferences": [
{
"pnr": "BOKT52",
"carrier": {
"iataCode": "ZZ",
"name": "Duffel Airways",
"logoUrl": "https://assets.duffel.com/img/airlines/for-light-background/full-color-logo/ZZ.svg",
"logoLockupUrl": null
}
}
],
"passengers": [
{
"id": "pas_0000BC0UogJGYlTqCNHhye",
"type": "ADULT",
"title": "mr",
"givenName": "James",
"familyName": "Smith",
"gender": "m",
"bornOn": "1990-01-15",
"email": "[email protected]",
"phoneNumber": "+15555550123",
"infantPassengerId": null,
"loyaltyProgrammeAccounts": [],
"ticketNumber": "1"
}
],
"travelerPricing": [
{
"travelerId": "pas_0000BC0UogJGYlTqCNHhye",
"travelerType": "ADULT",
"fareOption": "STANDARD",
"price": {
"supplierCurrency": "USD",
"agencyCurrency": "DZD",
"base": 16342.51,
"total": 21580.76,
"b2bPrice": 21559.2
},
"fareDetailsBySegment": [
{
"segmentId": "seg_0000BC0UogVJpx7ankvKl6",
"cabin": "ECONOMY",
"fareBasis": "Y20LGTN2",
"brandedFare": "Basic",
"brandedFareLabel": "Basic",
"bookingClass": "Economy",
"includedCheckedBags": {
"quantity": 1
},
"includedCabinBags": {
"quantity": 1
},
"amenities": []
}
]
}
],
"itinerary": [
{
"direction": "outbound",
"duration": "PT2H24M",
"stops": 0,
"fareBrandName": "Basic",
"origin": {
"airportCode": "ALG",
"airportName": "Houari Boumediene Airport",
"cityName": "Algiers",
"countryCode": "DZ",
"timeZone": "Africa/Algiers"
},
"destination": {
"airportCode": "CDG",
"airportName": "Paris Charles de Gaulle Airport",
"cityName": "Paris",
"countryCode": "FR",
"timeZone": "Europe/Paris"
},
"segments": [
{
"id": "seg_0000BC0UogVJpx7ankvKl6",
"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": "773",
"aircraftName": "Boeing 777-300",
"operatingCarrier": "ZZ",
"operatingCarrierName": "Duffel Airways",
"operatingFlightNumber": "7426"
},
"duration": "PT2H24M",
"distance": "1370.3019844730272",
"stops": [],
"cabin": "ECONOMY",
"cabinMarketingName": "Economy",
"fareBasis": "",
"brandedFare": "BASIC",
"brandedFareLabel": "Basic",
"passengerDetails": [
{
"passengerId": "pas_0000BC0UogJGYlTqCNHhye",
"cabin": "ECONOMY",
"cabinMarketingName": "Economy",
"seat": null,
"checkedBags": {
"quantity": 1
},
"cabinBags": {
"quantity": 1
}
}
]
}
],
"conditions": {
"changeBeforeDeparture": {
"allowed": true
}
}
}
],
"conditions": {
"refundBeforeDeparture": {
"allowed": false
},
"changeBeforeDeparture": {
"allowed": true
}
},
"owner": {
"id": "arl_00009VME7D6ivUu8dn35WK",
"iataCode": "ZZ",
"name": "Duffel Airways",
"logoUrl": "https://assets.duffel.com/img/airlines/for-light-background/full-color-logo/ZZ.svg",
"logoLockupUrl": null,
"conditionsOfCarriageUrl": "https://duffelairways.com/dummy-url/conditions-of-carriage"
},
"services": [],
"exchangeRate": 250,
"meta": {
"supportHold": false,
"supportVoid": false,
"voidDeadline": null,
"voidWindowEndsAt": null,
"airlineInitiatedChanges": [],
"changes": [],
"users": [],
"orderMetadata": null
},
"postProcessing": {
"bookingDbId": "d47fc805-23b6-44f0-a892-99c65fbbc363",
"bucketLink": null,
"emailSent": false
},
"balanceDebited": false,
"transactionCreated": false,
"payoutCreated": false
}{
"environment": "sandbox",
"success": true,
"requestId": "c501d0d3",
"searchId": "fs_92df8ed2-bd63-4dfc-bede-e27f72b04f2f",
"offerId": "fx_offer_40738cc9",
"processingTime": 9.402973413467407,
"booking": {
"reference": "eJzTd9ePNPcI93UBAAtdAmY",
"status": "confirmed",
"pnr": "Y7HWMD",
"type": "instant",
"createdAt": "2026-11-01T14:18:00.000",
"cancelledAt": null,
"content": "managed",
"syncedAt": "2026-11-01T14:18:00.000",
"availableActions": [],
"voidableUntil": "2026-11-01T23:00:00Z",
"cancellation": null
},
"supplier": {
"id": "amadeus_aqc_dz_1",
"technology": "amadeus_aqc",
"name": "Amadeus AQC",
"offerId": "3"
},
"agency": {
"currency": "DZD"
},
"pricing": {
"supplierCurrency": "DZD",
"agencyCurrency": "DZD",
"basePrice": 16390,
"taxesAndFees": 62312.01,
"agencyCommission": 78.71,
"finalPrice": 78780.72,
"b2bPrice": 78702.01,
"additionalServices": [],
"acd": {
"applied": true,
"scenario": "B"
}
},
"requiresACD": true,
"payment": {
"status": "paid",
"paidAt": "2026-11-01T14:18:00.000",
"paymentRequiredBy": null,
"priceGuaranteeExpiresAt": null,
"awaitingPayment": false
},
"documents": [],
"bookingReferences": [
{
"pnr": "Y7HWMD",
"carrier": {
"iataCode": "AZ",
"name": "ITA",
"logoUrl": "https://assets.duffel.com/img/airlines/for-light-background/full-color-logo/AZ.svg",
"logoLockupUrl": "https://assets.duffel.com/img/airlines/for-light-background/full-color-lockup/AZ.svg"
}
}
],
"passengers": [
{
"id": "1",
"type": "ADULT",
"title": "mr",
"givenName": "JOHN",
"familyName": "DOE",
"gender": "male",
"bornOn": "1985-04-10",
"email": "[email protected]",
"phoneNumber": "15555550123",
"infantPassengerId": null,
"loyaltyProgrammeAccounts": [],
"ticketNumber": null
}
],
"travelerPricing": [
{
"travelerId": "1",
"travelerType": "ADULT",
"fareOption": "STANDARD",
"price": {
"supplierCurrency": "DZD",
"agencyCurrency": "DZD",
"base": 16390,
"total": 78780.72,
"b2bPrice": 78702
},
"fareDetailsBySegment": [
{
"segmentId": "31",
"cabin": "ECONOMY",
"fareBasis": "SETCLSE9",
"brandedFare": "COMFORT",
"brandedFareLabel": "COMFORT",
"bookingClass": "S",
"includedCheckedBags": {
"quantity": 1
},
"includedCabinBags": {
"quantity": 1
},
"amenities": []
},
{
"segmentId": "32",
"cabin": "ECONOMY",
"fareBasis": "SETCLSE9",
"brandedFare": "COMFORT",
"brandedFareLabel": "COMFORT",
"bookingClass": "S",
"includedCheckedBags": {
"quantity": 1
},
"includedCabinBags": {
"quantity": 1
},
"amenities": []
}
]
}
],
"itinerary": [
{
"direction": "outbound",
"duration": "PT10H45M",
"stops": 1,
"fareBrandName": "COMFORT",
"origin": {
"airportCode": "CDG",
"airportName": "Paris Charles de Gaulle Airport",
"cityName": "Paris",
"countryCode": "FR",
"timeZone": "Europe/Paris"
},
"destination": {
"airportCode": "ALG",
"airportName": "Houari Boumediene Airport",
"cityName": "Algiers",
"countryCode": "DZ",
"timeZone": "Africa/Algiers"
},
"segments": [
{
"id": "31",
"departure": {
"airportCode": "CDG",
"airportName": "Paris Charles de Gaulle Airport",
"cityName": "Paris",
"countryCode": "FR",
"terminal": "2B",
"datetime": "2026-12-16T06:10:00",
"timeZone": "Europe/Paris"
},
"arrival": {
"airportCode": "FCO",
"airportName": "Leonardo da Vinci-Fiumicino Airport",
"cityName": "Rome",
"countryCode": "IT",
"terminal": "1",
"datetime": "2026-12-16T08:15:00",
"timeZone": "Europe/Rome"
},
"flight": {
"carrierCode": "AZ",
"carrierName": "ITA",
"carrierLogoUrl": "https://assets.duffel.com/img/airlines/for-light-background/full-color-logo/AZ.svg",
"flightNumber": "317",
"aircraftCode": "32N",
"aircraftName": null,
"operatingCarrier": "AZ",
"operatingCarrierName": "ITA",
"operatingFlightNumber": "317"
},
"duration": "PT2H5M",
"distance": null,
"stops": [],
"cabin": "ECONOMY",
"cabinMarketingName": "Economy",
"fareBasis": "SETCLSE9",
"brandedFare": "COMFORT",
"brandedFareLabel": "COMFORT",
"passengerDetails": [
{
"passengerId": "1",
"cabin": "ECONOMY",
"cabinMarketingName": "Economy",
"seat": null,
"checkedBags": {
"quantity": 1
},
"cabinBags": {
"quantity": 1
}
}
]
},
{
"id": "32",
"departure": {
"airportCode": "FCO",
"airportName": "Leonardo da Vinci-Fiumicino Airport",
"cityName": "Rome",
"countryCode": "IT",
"terminal": "1",
"datetime": "2026-12-16T15:00:00",
"timeZone": "Europe/Rome"
},
"arrival": {
"airportCode": "ALG",
"airportName": "Houari Boumediene Airport",
"cityName": "Algiers",
"countryCode": "DZ",
"terminal": "I",
"datetime": "2026-12-16T16:55:00",
"timeZone": "Africa/Algiers"
},
"flight": {
"carrierCode": "AZ",
"carrierName": "ITA",
"carrierLogoUrl": "https://assets.duffel.com/img/airlines/for-light-background/full-color-logo/AZ.svg",
"flightNumber": "800",
"aircraftCode": "319",
"aircraftName": null,
"operatingCarrier": "AZ",
"operatingCarrierName": "ITA",
"operatingFlightNumber": "800"
},
"duration": "PT1H55M",
"distance": null,
"stops": [],
"cabin": "ECONOMY",
"cabinMarketingName": "Economy",
"fareBasis": "SETCLSE9",
"brandedFare": "COMFORT",
"brandedFareLabel": "COMFORT",
"passengerDetails": [
{
"passengerId": "1",
"cabin": "ECONOMY",
"cabinMarketingName": "Economy",
"seat": null,
"checkedBags": {
"quantity": 1
},
"cabinBags": {
"quantity": 1
}
}
]
}
],
"conditions": {
"changeBeforeDeparture": {
"allowed": true
}
}
}
],
"conditions": {
"refundBeforeDeparture": {
"allowed": false
},
"changeBeforeDeparture": {
"allowed": true
}
},
"owner": {
"id": null,
"iataCode": "AZ",
"name": "ITA",
"logoUrl": "https://assets.duffel.com/img/airlines/for-light-background/full-color-logo/AZ.svg",
"logoLockupUrl": "https://assets.duffel.com/img/airlines/for-light-background/full-color-lockup/AZ.svg",
"conditionsOfCarriageUrl": null
},
"services": [],
"meta": {
"supportHold": true,
"supportVoid": true,
"voidDeadline": "2026-11-01T23:00:00Z",
"voidWindowEndsAt": null,
"airlineInitiatedChanges": [],
"changes": [],
"users": [],
"orderMetadata": null
},
"fareRules": {
"refund": {
"allowed": false
},
"exchange": {
"allowed": true
},
"agencyCurrency": "DZD"
},
"postProcessing": {
"bookingDbId": "2acf8907-f5c5-4d5d-93b5-3e4a038ccdf1",
"bucketLink": null,
"emailSent": false
},
"balanceDebited": false,
"transactionCreated": false,
"payoutCreated": false
}Request
Body
Required, JSON.
search_idstringrequiredThe searchId of the supplier entry the priced offer came from.
offer_idstringrequiredThe id of the priced offer.
booking_typestringissue (default) for instant ticketing, hold for an unpaid reservation when supportHold is true after pricing. Any letter case; any other value is 400 invalid_booking_type.
One of issue, hold. Default issue.
passengersarray of objectrequiredOne object per traveler, lap infants included. At most 18.
At most 18 items.
ShowHide 21 attributes
typestringrequiredadult, senior, young_adult, child, seated_infant or infant (a lap infant), in any letter case. Also accepted: young, young_adults, infant_with_seat, held_infant, infant_without_seat.
genderstringrequiredMALE or FEMALE (M and F too), in any letter case. X, U or UNSPECIFIED for a passport marked X.
first_namestringrequiredGiven name as in the passport. Latin letters are what airlines need. Spaces and line breaks around it are removed before the checks.
At most 64 characters.
last_namestringrequiredFamily name as in the passport. Spaces and line breaks around it are removed before the checks.
At most 64 characters.
date_of_birthstringrequiredYYYY-MM-DD, a real date that is not in the future (tomorrow is still accepted: time-zone slack).
identity_documentsarray of objectThe passport, up to 5 documents.
At most 5 items.
ShowHide 12 attributes
typestringpassport (default).
numberstringThe document number: 1 to 40 letters, digits, spaces and - . /. A JSON number is read as text with a coerced_value warning.
issuing_countrystringThe country that issued the document: ISO 3166-1 alpha-2 (DZ). Any code of 2 to 4 letters, optionally followed by - and 1 to 3 letters or digits (GB-SCT, USPR), is accepted and passed on in upper case without conversion. Anything else is 400 invalid_country_code.
expiry_datestringYYYY-MM-DD.
nationalitystringAccepted and ignored: suppliers use the issuing country.
issuingCountrystringdeprecatedLegacy name, still accepted. Use issuing_country instead.
The previous spelling of issuing_country: The country that issued the document: ISO 3166-1 alpha-2 (DZ).
issuing_country_codestringdeprecatedLegacy name, still accepted. Use issuing_country instead.
The previous spelling of issuing_country: The country that issued the document: ISO 3166-1 alpha-2 (DZ).
issuingCountryCodestringdeprecatedLegacy name, still accepted. Use issuing_country instead.
The previous spelling of issuing_country: The country that issued the document: ISO 3166-1 alpha-2 (DZ).
expiryDatestringdeprecatedLegacy name, still accepted. Use expiry_date instead.
The previous spelling of expiry_date: YYYY-MM-DD.
expires_onstringdeprecatedLegacy name, still accepted. Use expiry_date instead.
The previous spelling of expiry_date: YYYY-MM-DD.
documentNumberstringdeprecatedLegacy name, still accepted. Use number instead.
The previous spelling of number: The document number: 1 to 40 letters, digits, spaces and `- .
unique_identifierstringdeprecatedLegacy name, still accepted. Use number instead.
The previous spelling of number: The document number: 1 to 40 letters, digits, spaces and `- .
idstringAn id of yours for the passenger.
firstNamestringdeprecatedLegacy name, still accepted. Use first_name instead.
The previous spelling of first_name: Given name as in the passport.
givenNamestringdeprecatedLegacy name, still accepted. Use first_name instead.
The previous spelling of first_name: Given name as in the passport.
given_namestringdeprecatedLegacy name, still accepted. Use first_name instead.
The previous spelling of first_name: Given name as in the passport.
lastNamestringdeprecatedLegacy name, still accepted. Use last_name instead.
The previous spelling of last_name: Family name as in the passport.
familyNamestringdeprecatedLegacy name, still accepted. Use last_name instead.
The previous spelling of last_name: Family name as in the passport.
family_namestringdeprecatedLegacy name, still accepted. Use last_name instead.
The previous spelling of last_name: Family name as in the passport.
surnamestringdeprecatedLegacy name, still accepted. Use last_name instead.
The previous spelling of last_name: Family name as in the passport.
dateOfBirthstringdeprecatedLegacy name, still accepted. Use date_of_birth instead.
The previous spelling of date_of_birth: YYYY-MM-DD, a real date that is not in the future (tomorrow is still accepted: time-zone slack).
bornOnstringdeprecatedLegacy name, still accepted. Use date_of_birth instead.
The previous spelling of date_of_birth: YYYY-MM-DD, a real date that is not in the future (tomorrow is still accepted: time-zone slack).
born_onstringdeprecatedLegacy name, still accepted. Use date_of_birth instead.
The previous spelling of date_of_birth: YYYY-MM-DD, a real date that is not in the future (tomorrow is still accepted: time-zone slack).
dobstringdeprecatedLegacy name, still accepted. Use date_of_birth instead.
The previous spelling of date_of_birth: YYYY-MM-DD, a real date that is not in the future (tomorrow is still accepted: time-zone slack).
identityDocumentsarraydeprecatedLegacy name, still accepted. Use identity_documents instead.
The previous spelling of identity_documents: The passport, up to 5 documents.
documentsarraydeprecatedLegacy name, still accepted. Use identity_documents instead.
The previous spelling of identity_documents: The passport, up to 5 documents.
passengerTypestringdeprecatedLegacy name, still accepted. Use type instead.
The previous spelling of type: adult, senior, young_adult, child, seated_infant or infant (a lap infant), in any letter case.
contact_detailsobjectrequiredHow to reach the traveler. Both fields are required.
ShowHide 6 attributes
emailstringrequiredThe e-mail of the contact, 254 characters at most.
phone_numberstringrequiredAn international phone number (+213...): Duffel validates the format. FX-Port accepts digits with spaces, dots, dashes, slashes and brackets, one leading +, 5 to 24 digits and 32 characters at most; a dial code alone (+213) is 400 invalid_phone_number.
phonestringdeprecatedLegacy name, still accepted. Use phone_number instead.
The previous spelling of phone_number: An international phone number (+213...): Duffel validates the format.
phoneNumberstringdeprecatedLegacy name, still accepted. Use phone_number instead.
The previous spelling of phone_number: An international phone number (+213...): Duffel validates the format.
mobilestringdeprecatedLegacy name, still accepted. Use phone_number instead.
The previous spelling of phone_number: An international phone number (+213...): Duffel validates the format.
emailAddressstringdeprecatedLegacy name, still accepted. Use email instead.
The previous spelling of email: The e-mail of the contact, 254 characters at most.
send_emailbooleanfalse suppresses the confirmation e-mail. Default true.
commission_overrideobjectReplaces your agency commission for this booking: pricing.agencyCommission and pricing.finalPrice change, b2bPrice does not.
ShowHide 2 attributes
typestringrequiredpercentage is a share of b2bPrice; fixed is value times the number of travelers.
One of percentage, fixed.
valuenumberrequiredA number from 0. Numeric text such as "10" is read as a number with a coerced_value warning.
At least 0.
agent_idstringYour own id of the agent who books; stored on the booking.
agency_idstringNot needed: the agency of a call is always the one of your API key. The field is accepted so that older clients keep working, and it is ignored.
searchIdstringdeprecatedLegacy name, still accepted. Use search_id instead.
The previous spelling of search_id: The searchId of the supplier entry the priced offer came from.
offerIdstringdeprecatedLegacy name, still accepted. Use offer_id instead.
The previous spelling of offer_id: The id of the priced offer.
bookingTypestringdeprecatedLegacy name, still accepted. Use booking_type instead.
The previous spelling of booking_type: issue (default) for instant ticketing, hold for an unpaid reservation when supportHold is true after pricing.
sendEmailbooleandeprecatedLegacy name, still accepted. Use send_email instead.
The previous spelling of send_email: false suppresses the confirmation e-mail.
commissionOverrideobjectdeprecatedLegacy name, still accepted. Use commission_override instead.
The previous spelling of commission_override: commission_override.
agentIdstringdeprecatedLegacy name, still accepted. Use agent_id instead.
The previous spelling of agent_id: Your own id of the agent who books; stored on the booking.
contactobjectdeprecatedLegacy name, still accepted. Use contact_details instead.
The previous spelling of contact_details: contact_details.
contactsobjectdeprecatedLegacy name, still accepted. Use contact_details instead.
The previous spelling of contact_details: contact_details.
contactDetailsobjectdeprecatedLegacy name, still accepted. Use contact_details instead.
The previous spelling of contact_details: contact_details.
agencyIdstringdeprecatedLegacy name, still accepted. Use agency_id instead.
The previous spelling of agency_id: Not needed: the agency of a call is always the one of your API key.
Response
200The order. Keep booking.reference (the supplier's order id), booking.pnr and postProcessing.bookingDbId.
environmentstringThe environment of the key that made the call: sandbox for fxp_test_ keys, live for fxp_live_ keys. Present in every JSON body.
One of sandbox, live.
request_idstringThe id of the request, also in the X-Request-Id header.
warningsarray of objectPresent only when the request used a previous spelling of a field or something the endpoint ignored.
ShowHide 5 attributes
codestringWhat the warning is about.
One of deprecated_field, ignored_field, coerced_value, deprecated_value, deprecated_endpoint.
fieldstringThe request field the warning is about.
replacementstringThe name to use instead, for deprecated_* warnings.
messagestringA sentence that says what happened and what to do.
documentation_urlstringWhere the naming rules are explained.
successbooleantrue when the order was created (booking) or paid (payment).
requestIdstringdeprecatedLegacy name, still accepted. Use request_id instead.
The id of this request, 8 characters, for support.
paymentSucceededbooleanpay_order only: whether the payment succeeded. Read it together with success.
searchIdstringdeprecatedLegacy name, still accepted. Use search_id instead.
book_flight only: the search_id you sent.
search_idstringbook_flight only: the search_id you sent. The snake_case twin of searchId, with the same value: use this name.
offerIdstringdeprecatedLegacy name, still accepted. Use offer_id instead.
book_flight only: the offer_id you sent.
offer_idstringbook_flight only: the offer_id you sent. The snake_case twin of offerId, with the same value: use this name.
orderIdstringdeprecatedLegacy name, still accepted. Use order_id instead.
pay_order only: the supplier's order id.
order_idstringpay_order only: the supplier's order id. The snake_case twin of orderId, with the same value: use this name.
processingTimenumberdeprecatedLegacy name, still accepted. Use processing_time instead.
Seconds spent.
processing_timenumberSeconds spent. The snake_case twin of processingTime, with the same value: use this name.
paymentDetailsobjectpay_order only: paymentId, status, type (issuance), paymentAmount, currency, createdAt, message.
bookingobjectThe order as the supplier knows it.
ShowHide 12 attributes
referencestringdeprecatedLegacy name, still accepted. Use order_id instead.
The supplier's order id (ord_... for Duffel, a base64-like text for Amadeus; for a cancelled hold of Amadeus Algeria the PNR). Send it as order_id to pay_order, cancel_order and cancel_quote.
order_idstringThe supplier's order id (ord_... for Duffel, a base64-like text for Amadeus; for a cancelled hold of Amadeus Algeria the PNR). Send it as order_id to pay_order, cancel_order and cancel_quote. The snake_case twin of reference, with the same value: use this name.
statusstringconfirmed, pending (a hold that is not paid yet), awaiting_payment, cancelled, failed or partial_refund.
pnrstringThe airline record locator. Not unique across suppliers and airlines.
typestringinstant: ticketed at once. hold: reserved, not paid.
One of instant, hold.
createdAtstringWhen the order was created.
cancelledAtstringnullableWhen the order was cancelled.
contentstringWho manages the order: managed.
syncedAtstringWhen FX-Port last synchronised the order with the supplier.
availableActionsarray of stringWhat can still be done with the order.
voidableUntilstringnullableISO 8601 UTC end of the same-day void window.
cancellationobjectnullableHow the order was cancelled: type, deleted, deletedAt.
supplierobjectThe supplier of the order.
ShowHide 7 attributes
idstringdeprecatedLegacy name, still accepted. Use supplier_id instead.
Id of the supplier.
supplier_idstringId of the supplier. The snake_case twin of id, with the same value: use this name.
technologystringThe technology of the supplier: amadeus_aqc or duffel.
namestringdeprecatedLegacy name, still accepted. Use supplier_name instead.
Name of the supplier.
supplier_namestringName of the supplier. The snake_case twin of name, with the same value: use this name.
offerIdstringnullabledeprecatedLegacy name, still accepted. Use supplier_offer_id instead.
The supplier's own id of the offer.
supplier_offer_idstringnullableThe supplier's own id of the offer. The snake_case twin of offerId, with the same value: use this name.
agencyobjectYour agency. The id of the agency is not returned: you know it.
ShowHide 1 attribute
currencystringISO 4217 currency of your agency. Every amount of the response is in it.
pricingobjectThe agency-facing price of an offer, a booking or a quote. Every amount is in agencyCurrency; the rate, when the currencies differ, is exchangeRate at the top level of the response.
ShowHide 17 attributes
supplierCurrencystringISO 4217 currency in which the supplier prices the fare.
agencyCurrencystringISO 4217 currency of your agency. Every amount of the block is in it.
basePricenumberdeprecatedLegacy name, still accepted. Use base_price instead.
The airline's base fare, before taxes, in the agency currency.
base_pricenumberThe airline's base fare, before taxes, in the agency currency. The snake_case twin of basePrice, with the same value: use this name.
taxesAndFeesnumberdeprecatedLegacy name, still accepted. Use taxes_and_fees instead.
Taxes plus the platform's fees, folded together. Excludes your agency commission.
taxes_and_feesnumberTaxes plus the platform's fees, folded together. Excludes your agency commission. The snake_case twin of taxesAndFees, with the same value: use this name.
agencyCommissionnumberdeprecatedLegacy name, still accepted. Use agency_commission instead.
The commission of your agency on this sale.
agency_commissionnumberThe commission of your agency on this sale. The snake_case twin of agencyCommission, with the same value: use this name.
finalPricenumberdeprecatedLegacy name, still accepted. Use final_price instead.
What the traveler pays: basePrice + taxesAndFees + agencyCommission.
final_pricenumberWhat the traveler pays: basePrice + taxesAndFees + agencyCommission. The snake_case twin of finalPrice, with the same value: use this name.
b2bPricenumberdeprecatedLegacy name, still accepted. Use b2b_price instead.
The amount debited from your agency balance: finalPrice - agencyCommission.
b2b_pricenumberThe amount debited from your agency balance: finalPrice - agencyCommission. The snake_case twin of b2bPrice, with the same value: use this name.
totalAmountnumberOrder quote only: an alias of b2bPrice.
taxAmountnumberOrder quote of a Duffel order only: the airline's taxes in your agency currency.
originalTaxAmountnumberOrder quote of a Duffel order only: the same taxes in the supplier currency.
additionalServicesarray of objectPaid extras. A list in the offers of a search (empty for most offers).
acdobjectWhether the fare is an ACD fare. Present on the offers of Amadeus Algeria, absent on Duffel offers. An ACD fare carries more keys with the amounts of the adjustment: they are informational, can change without notice and are not part of the contract.
ShowHide 4 attributes
appliedbooleantrue for an ACD fare: the booking needs one passport copy for every traveler, sent with upload_acd_documents. false for an ordinary fare.
scenariostringOnly on an ACD fare: the rule that adjusted the price. Informational.
One of A, B.
exemptbooleantrue when the search named an ACD-exempt company of your agency: the fare is priced without ACD.
reasonstringOnly on some ACD fares: why the rule applied. Informational; the wording can change.
requiresACDbooleanPresent only when true: the booking needs one passport copy for every traveler: see upload_acd_documents.
paymentobjectThe payment state of the order.
ShowHide 5 attributes
statusstringawaiting_payment for a hold, paid once ticketed.
paidAtstringnullableWhen the order was paid.
paymentRequiredBystringnullableThe payment deadline of a hold, when the supplier gives one.
priceGuaranteeExpiresAtstringnullableUntil when the price is guaranteed.
awaitingPaymentbooleantrue for a hold that still has to be paid.
documentsarray of objectThe e-tickets. Empty for a hold.
ShowHide 6 attributes
typestringelectronic_ticket.
uniqueIdentifierstringThe ticket number (Duffel sandbox: the text 1).
passengerIdsarray of stringThe passengers the document is for.
documentTypestringETICKET.
statusstringISSUED.
segmentIdsarray of stringThe segments the document covers.
bookingReferencesarray of objectThe record locators.
ShowHide 2 attributes
pnrstringThe airline record locator.
carrierobjectThe airline that issued the record locator.
ShowHide 4 attributes
iataCodestringIATA code of the airline.
namestringName of the airline.
logoUrlstringAddress of the logo.
logoLockupUrlstringnullableAddress of the wide logo.
passengersarray of objectThe passengers.
ShowHide 18 attributes
idstringdeprecatedLegacy name, still accepted. Use passenger_id instead.
Id of the passenger on the order: "1" (Amadeus) or pas_... (Duffel).
passenger_idstringId of the passenger on the order: "1" (Amadeus) or pas_... (Duffel). The snake_case twin of id, with the same value: use this name.
typestringdeprecatedLegacy name, still accepted. Use passenger_type instead.
ADULT, CHILD, INFANT_WITHOUT_SEAT ... as the supplier writes it.
passenger_typestringADULT, CHILD, INFANT_WITHOUT_SEAT ... as the supplier writes it. The snake_case twin of type, with the same value: use this name.
titlestringmr, mrs ... derived from the gender.
givenNamestringdeprecatedLegacy name, still accepted. Use first_name instead.
Given name, as stored (Amadeus writes it in upper case).
first_namestringGiven name, as stored (Amadeus writes it in upper case). The snake_case twin of givenName, with the same value: use this name.
familyNamestringdeprecatedLegacy name, still accepted. Use last_name instead.
Family name, as stored.
last_namestringFamily name, as stored. The snake_case twin of familyName, with the same value: use this name.
genderstringmale or female.
bornOnstringdeprecatedLegacy name, still accepted. Use date_of_birth instead.
Date of birth, YYYY-MM-DD.
date_of_birthstringDate of birth, YYYY-MM-DD. The snake_case twin of bornOn, with the same value: use this name.
emailstringThe e-mail of the contact.
phoneNumberstringdeprecatedLegacy name, still accepted. Use phone_number instead.
The phone number of the contact.
phone_numberstringThe phone number of the contact. The snake_case twin of phoneNumber, with the same value: use this name.
infantPassengerIdstringnullableThe id of the lap infant this adult carries.
loyaltyProgrammeAccountsarray of objectFrequent-flyer accounts.
ticketNumberstringnullableThe ticket number of this passenger. null until the airline returns it.
travelerPricingarray of objectThe price of each traveler.
ShowHide 7 attributes
travelerIdstringdeprecatedLegacy name, still accepted. Use passenger_id instead.
"1", "2" ... for Amadeus, pas_... for Duffel.
passenger_idstring"1", "2" ... for Amadeus, pas_... for Duffel. The snake_case twin of travelerId, with the same value: use this name.
travelerTypestringdeprecatedLegacy name, still accepted. Use passenger_type instead.
ADULT, SENIOR, YOUNG, CHILD, SEATED_INFANT or HELD_INFANT (a lap infant).
passenger_typestringADULT, SENIOR, YOUNG, CHILD, SEATED_INFANT or HELD_INFANT (a lap infant). The snake_case twin of travelerType, with the same value: use this name.
fareOptionstringThe fare option, for example STANDARD.
priceobjectThe price of one traveler.
ShowHide 5 attributes
supplierCurrencystringISO 4217 currency in which the supplier prices the fare.
agencyCurrencystringISO 4217 currency of your agency.
basenumberThe traveler's base fare in the agency currency.
totalnumberThe traveler's final price: what this traveler pays. The totals of all travelers add up to pricing.finalPrice.
b2bPricenumberThe traveler's share of the amount debited from your balance.
fareDetailsBySegmentarray of objectThe fare of this traveler on every segment.
ShowHide 9 attributes
segmentIdstringThe id of the segment this fare detail is about.
cabinstringCabin of the fare on this segment.
One of ECONOMY, PREMIUM_ECONOMY, BUSINESS, FIRST.
fareBasisstringnullableFare basis code.
brandedFarestringnullableFare family code.
brandedFareLabelstringnullableDisplay label of the fare family.
bookingClassstringnullableBooking class letter.
includedCheckedBagsobjectThe checked baggage included in the fare.
ShowHide 1 attribute
quantityintegerNumber of checked bags included in the fare.
includedCabinBagsobjectThe cabin baggage included in the fare.
ShowHide 1 attribute
quantityintegerNumber of cabin bags included in the fare.
amenitiesarray of objectWhat else the fare includes or sells (seat, bag, meal, Wi-Fi ...).
itineraryarray of objectThe flights of the order.
ShowHide 8 attributes
directionstringoutbound, return ...
durationstringISO 8601 duration.
stopsintegerNumber of stops.
fareBrandNamestringName of the fare brand.
originobjectWhere this direction starts.
ShowHide 5 attributes
airportCodestringIATA code of the airport.
airportNamestringName of the airport.
cityNamestringName of the city.
countryCodestringISO 3166-1 alpha-2 country code.
timeZonestringIANA time zone.
destinationobjectWhere this direction ends.
ShowHide 5 attributes
airportCodestringIATA code of the airport.
airportNamestringName of the airport.
cityNamestringName of the city.
countryCodestringISO 3166-1 alpha-2 country code.
timeZonestringIANA time zone.
segmentsarray of objectThe flights of this direction.
ShowHide 8 attributes
idstringId of the segment.
departureobjectWhere and when a segment leaves or arrives.
ShowHide 7 attributes
airportCodestringIATA code of the airport.
airportNamestringName of the airport.
cityNamestringName of the city.
countryCodestringISO 3166-1 alpha-2 country code.
terminalstringnullableTerminal, when the supplier says.
datetimestringLocal date and time at the airport, YYYY-MM-DDTHH:MM:SS, without a time zone.
timeZonestringIANA time zone of the airport.
arrivalobjectWhere and when a segment leaves or arrives.
ShowHide 7 attributes
airportCodestringIATA code of the airport.
airportNamestringName of the airport.
cityNamestringName of the city.
countryCodestringISO 3166-1 alpha-2 country code.
terminalstringnullableTerminal, when the supplier says.
datetimestringLocal date and time at the airport, YYYY-MM-DDTHH:MM:SS, without a time zone.
timeZonestringIANA time zone of the airport.
flightobjectThe airline and the number of the flight.
ShowHide 3 attributes
carrierCodestringIATA code of the marketing airline.
flightNumberstringThe flight number.
operatingCarrierstringIATA code of the operating airline.
durationstringISO 8601 duration.
cabinstringThe cabin.
fareBasisstringnullableFare basis code.
passengerDetailsarray of objectWhat each passenger has on this segment.
conditionsobjectnullableWhat the fare allows before departure. Indicative only. A Duffel order can carry null for both when the airline does not say.
ShowHide 2 attributes
refundBeforeDepartureobjectnullableWhat the fare says about a refund before departure.
ShowHide 1 attribute
allowedbooleanWhether a refund is allowed before departure. Indicative, not a promise: the fare rules of the airline decide.
changeBeforeDepartureobjectnullableWhat the fare says about a change before departure.
ShowHide 1 attribute
allowedbooleanWhether a change is allowed before departure. Indicative, not a promise: the fare rules of the airline decide.
conditionsobjectWhat the fare allows before departure. Indicative only. A Duffel order can carry null for both when the airline does not say.
ShowHide 2 attributes
refundBeforeDepartureobjectnullableWhat the fare says about a refund before departure.
ShowHide 1 attribute
allowedbooleanWhether a refund is allowed before departure. Indicative, not a promise: the fare rules of the airline decide.
changeBeforeDepartureobjectnullableWhat the fare says about a change before departure.
ShowHide 1 attribute
allowedbooleanWhether a change is allowed before departure. Indicative, not a promise: the fare rules of the airline decide.
fareRulesobjectWhat exchange, refund and revalidation allow.
ownerobjectThe airline that owns the order.
ShowHide 6 attributes
idstringnullableDuffel's id of the airline.
iataCodestringIATA code of the airline that owns the order.
namestringName of the airline.
logoUrlstringAddress of the logo.
logoLockupUrlstringnullableAddress of the wide logo.
conditionsOfCarriageUrlstringnullableAddress of the conditions of carriage.
servicesarray of objectExtra services of the order (bags, seats). Empty.
metaobjectCapabilities of the order and what the supplier reports about it.
ShowHide 11 attributes
supportHoldbooleandeprecatedLegacy name, still accepted. Use support_hold instead.
Whether the supplier can hold.
support_holdbooleanWhether the supplier can hold. The snake_case twin of supportHold, with the same value: use this name.
supportVoidbooleandeprecatedLegacy name, still accepted. Use support_void instead.
Whether the supplier can void the ticket the same day.
support_voidbooleanWhether the supplier can void the ticket the same day. The snake_case twin of supportVoid, with the same value: use this name.
voidDeadlinestringnullabledeprecatedLegacy name, still accepted. Use void_deadline instead.
End of the same-day void window.
void_deadlinestringnullableEnd of the same-day void window. The snake_case twin of voidDeadline, with the same value: use this name.
voidWindowEndsAtstringnullableEnd of the void window, when the supplier gives it.
airlineInitiatedChangesarray of objectSchedule changes the airline made.
changesarray of objectChanges of the order.
usersarray of objectUsers of the order.
orderMetadataobjectnullableSupplier-specific metadata of the order.
exchangeRatenumberdeprecatedLegacy name, still accepted. Use exchange_rate instead.
Only when the supplier's currency is not your agency's.
exchange_ratenumberOnly when the supplier's currency is not your agency's. The snake_case twin of exchangeRate, with the same value: use this name.
internalBookingobjectThe FX-Port identifiers of the booking.
ShowHide 2 attributes
bookingIdstringThe PNR.
internalIdstringThe FX-Port id of the booking (a UUID), the same as postProcessing.bookingDbId of the booking call.
postProcessingobjectWhat FX-Port did after the supplier call.
ShowHide 5 attributes
bookingDbIdstringThe FX-Port id of the booking (a UUID). The best key to store: it is accepted as booking_id by get_booking.
bucketLinkstringnullableAddress of the PDF of the ticket, null until it is generated. A public link.
emailSentbooleanWhether the confirmation e-mail went out.
bookingStatusUpdatedbooleancancel_order: whether the FX-Port booking was updated.
refundMethodstringconfirm_cancel: where the refund went: balance.
balanceDebitedbooleanbook_flight only. Always false in the sandbox: nothing is charged.
transactionCreatedbooleanbook_flight only. Always false in the sandbox.
payoutCreatedbooleanbook_flight only. Always false in the sandbox.
errorobjectOnly when success is false: the refusal of the supplier for pay_order.
ShowHide 5 attributes
messagestringThe supplier's message.
codestringThe supplier's code: a number as text for Amadeus (4926), a name for Duffel (order_not_cancellable).
typestringThe supplier's error type.
detailsarray of objectThe supplier's details, in its own format.
userMessagestringA sentence the supplier wrote for the traveler, when there is one.
errorsarray of objectOnly when success is false: the unified error list. errors[0].code is the supplier's code in lower case and errors[0].type is supplier_error.
ShowHide 7 attributes
codestringStable, machine-readable code in snake_case. Branch on this, never on the message.
typestringThe family of the error: tells you how to react.
One of authentication_error, permission_error, validation_error, not_found, conflict, payment_error, rate_limit_error, supplier_error, internal_error.
titlestringA short label of the error.
messagestringA sentence for a human: what is wrong and how to fix it. Wording can change; the code does not.
fieldstringnullableThe request field the error is about, when there is one.
detailsobjectnullableStructured extras of the error (for example available and required for an insufficient balance).
documentation_urlstringThe documentation of this error code.
Errors
| Status | Code | Example message |
|---|---|---|
| 400 | bad_request | Missing required parameters: search_id and offer_id are required |
| 400 | missing_field | `passengers[0].first_name` is required. |
| 400 | invalid_booking_type | `booking_type` must be "issue" (instant ticket) or "hold". |
| 400 | hold_not_supported | This offer cannot be held; it must be booked instantly. |
| 400 | too_many_passengers | A booking takes at most 18 passengers. |
| 402 | insufficient_balance | Agency balance is insufficient. Available: 120.0 DZD, Required: 29876.81 DZD. |
| 403 | read_write_permission_required | This endpoint requires an API key with read_write permission. |
| 404 | SEARCH_EXPIRED_OR_NOT_FOUND | Search ID 'fs_does_not_exist' not found or has expired |
| 404 | OFFER_NOT_FOUND_IN_SEARCH | Offer ID 'fx_offer_00000000' not found in search results |
| 404 | OFFER_NOT_PRICED | Priced offer 'fx_offer_250b4eb7' not found in cache. Please price the offer first before booking. |
| 409 | OFFER_ALREADY_BOOKED | This offer has already been booked successfully (PNR: BOKT52). Duplicate submissions are not allowed. |
| 409 | offer_request_already_booked | Field 'selected_offers' has offers included in a offer request that has already been booked; please perform a new search |
| 422 | validation_type | Field 'born_on' is invalid. Expected a date in ISO 8601 format (YYYY-MM-DD) |
| 500 | post_booking_failed | The booking was placed but could not be recorded completely. Contact support with this request id before retrying. |
| 503 | supplier_temporarily_unavailable | Supplier 'duffel_1' circuit breaker is open: retry in a few moments. |
| 503 | balance_lock_timeout | The agency balance is busy with another operation. Retry in a few seconds. |
The shape of the error body depends on the endpoint. See Errors for every shape and code.