Offers

After you've searched for flights by creating an offer request, we'll send your search to a range of airlines, which may return offers.

Each offer represents flights you can buy from an airline at a particular price that meet your search criteria.

You'll see slices inside the offers. Each slice will also include a list of one or more specific flights (called segments) that the airline is offering to get the passengers where they want to go.

allowed_passenger_identity_document_types
string[]

The types of identity documents that may be provided for the passengers when creating an order based on this offer. Currently, the only supported type is passport. If this is [], then you must not provide identity documents.

Example: ["passport"]
available_services
list

The services that can be booked along with the offer but are not included by default, for example an additional checked bag. This field is only returned in the Get single offer endpoint. When there are no services available, or we don't support services for the airline, this list will be empty. If you want to know which airlines we support services for, please get in touch with the Duffel support team at help@duffel.com.

base_amount
string

The base price of the offer for all passengers, excluding taxes. It does not include the base amount of any service(s) that might be booked with the offer.

Example: "30.20"
base_currency
string

The currency of the base_amount, as an ISO 4217 currency code. It will match your organisation's billing currency unless you’re using Duffel as an accredited IATA agent, in which case it will be in the currency provided by the airline (which will usually be based on the country where your IATA agency is registered).

Example: "GBP"
conditions
object

The conditions associated with this offer, describing the kinds of modifications you can make post-booking and any penalties that will apply to those modifications. This information assumes the condition is applied to all of the slices and passengers associated with this offer - for information at the slice level (e.g. "what happens if I just want to change the first slice?") refer to the slices. If a particular kind of modification is allowed, you may not always be able to take action through the Duffel API. In some cases, you may need to contact the Duffel support team or the airline directly.

created_at
datetime

The ISO 8601 datetime at which the offer was created

Example: "2020-01-17T10:12:14.545Z"
expires_at
datetime

The ISO 8601 datetime at which the offer will expire and no longer be usable to create an order

Example: "2020-01-17T10:42:14.545Z"
id
string

Duffel's unique identifier for the offer

Example: "off_00009htYpSCXrwaB9DnUm0"
live_mode
boolean

Whether the offer request was created in live mode. This field will be set to true if the offer request was created in live mode, or false if it was created in test mode.

Example: true
owner
object

The airline which provided the offer

passenger_identity_documents_required
boolean

Whether identity documents must be provided for each of the passengers when creating an order based on this offer. If this is true, you must provide an identity document for every passenger.

Example: false
passengers
list

The passengers included in the offer

payment_requirements
object

The payment requirements for this offer

slices
list

The slices that make up this offer. Each slice will include one or more segments, the specific flights that the airline is offering to take the passengers from the slice's origin to its destination.

tax_amount
string
nullable

The amount of tax payable on the offer for all passengers

Example: "40.80"
tax_currency
string
nullable

The currency of the tax_amount, as an ISO 4217 currency code. It will match your organisation's billing currency unless you’re using Duffel as an accredited IATA agent, in which case it will be in the currency provided by the airline (which will usually be based on the country where your IATA agency is registered).

Example: "GBP"
total_amount
string

The total price of the offer for all passengers, including taxes. It does not include the total price of any service(s) that might be booked with the offer.

Example: "45.00"
total_currency
string

The currency of the total_amount, as an ISO 4217 currency code. It will match your organisation's billing currency unless you’re using Duffel as an accredited IATA agent, in which case it will be in the currency provided by the airline (which will usually be based on the country where your IATA agency is registered).

Example: "GBP"
total_emissions_kg
string

An estimate of the total carbon dioxide (CO₂) emissions when all of the passengers fly this offer's itinerary, measured in kilograms

Example: "460"
updated_at
datetime

The ISO 8601 datetime at which the offer was last updated

Example: "2020-01-17T10:12:14.545Z"

Some offer passenger fields are updateable. Each field that can be updated is detailed in the request object.

URL parameters

id
string
required

The identifier for the passenger. This ID will be generated by Duffel

Example: "pas_00009hj8USM7Ncg31cBCL"

Body parameters

family_name
string

The passenger's family name. Only space, -, ', and letters from the ASCII, Latin-1 Supplement and Latin Extended-A (with the exceptions of Æ, æ, IJ, ij, Œ, œ, Þ, and ð) Unicode charts are accepted. All other characters will result in a validation error. The minimum length is 1 character, and the maximum is 20 characters.

This is only required if you're also including Loyalty Programme Accounts.

Example: "Earhart"
given_name
string

The passenger's given name. Only space, -, ', and letters from the ASCII, Latin-1 Supplement and Latin Extended-A (with the exceptions of Æ, æ, IJ, ij, Œ, œ, Þ, and ð) Unicode charts are accepted. All other characters will result in a validation error. The minimum length is 1 character, and the maximum is 20 characters.

This is only required if you're also including Loyalty Programme Accounts.

Example: "Amelia"
loyalty_programme_accounts
list

The Loyalty Programme Accounts for this passenger

Endpoint

PATCH https://api.duffel.com/air/offers/{id}/passengers/{id}

Request

curl -X PATCH --compressed "https://api.duffel.com/air/offers/{id}/passengers/{id}" \
-H "Accept-Encoding: gzip" \
-H "Accept: application/json" \
-H "Duffel-Version: beta" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
-d '{
"data": {
"loyalty_programme_accounts": [
{
"airline_iata_code": "BA",
"account_number": "12901014"
}
],
"given_name": "Amelia",
"family_name": "Earhart"
}
}'

Response

{
"data": {
"type": "adult",
"loyalty_programme_accounts": [
{
"airline_iata_code": "BA",
"account_number": "12901014"
}
],
"id": "pas_00009hj8USM7Ncg31cBCL",
"given_name": "Amelia",
"family_name": "Earhart",
"age": 14
}
}

Retrieves a list of offers for a given offer request specified by its ID. Unless you specify a sort parameter, the results may be returned in any order.

This endpoint does not return the complete, up-to-date information on each offer. The Get a single offer endpoint should be called for a given offer in order to get complete and up-to-date information.

Query Parameters

after
string

A cursor pointing to the previous page of records. For more information on how to paginate through records, see the Pagination section.

Example: "g2wAAAACbQAAABBBZXJvbWlzdC1LaGFya2l2bQAAAB="
before
string

A cursor pointing to the next page of records. For more information on how to paginate through records, see the Pagination section.

Example: "g2wAAAACbQAAABBBZXJvbWlzdC1LaGFya2l2bQAAAB="
limit
integer

The maximum number of records to return per page. Defaults to 50. May be set to any integer between 1 and 200. For more information on how to paginate through records, see the Pagination section.

Example: 1
Default value: 50
offer_request_id
string
required

Duffel's unique identifier for the offer request, returned when it was created

Example: "orq_00009htyDGjIfajdNBZRlw"
sort
enum

By default, the offers will be returned sorted by ID in ascending order. This parameter allows you to sort the list of offers by total_amount or total_duration. By default the sorting order will be ascending, if you wish to sort in descending order a - will need to be prepended to the sorting attribute (i.e: -total_amount).

Possible values: "total_amount" or "total_duration"
max_connections
integer

Allows to filter the offers list by the maximum number of connections in a given offer. e.g. a return flight with three flights outbound and a direct inbound flight would be filtered out if max_connections=1 was passed.

Example: 2

Endpoint

GET https://api.duffel.com/air/offers

Request

curl -X GET --compressed "https://api.duffel.com/air/offers?after=g2wAAAACbQAAABBBZXJvbWlzdC1LaGFya2l2bQAAAB=&before=g2wAAAACbQAAABBBZXJvbWlzdC1LaGFya2l2bQAAAB=&limit=1&offer_request_id=orq_00009htyDGjIfajdNBZRlw&sort=total_amount&max_connections=2" \
-H "Accept-Encoding: gzip" \
-H "Accept: application/json" \
-H "Duffel-Version: beta" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>"

Response

{
"meta": {
"limit": 50,
"after": "g2wAAAACbQAAABBBZXJvbWlzdC1LaGFya2l2bQAAAB="
},
"data": [
{
"total_emissions_kg": "460",
"total_currency": "GBP",
"total_amount": "45.00",
"tax_currency": "GBP",
"tax_amount": "40.80",
"slices": [
{
"segments": [
{
"passengers": [
{
"passenger_id": "passenger_0",
"fare_basis_code": "OXZ0RO",
"cabin_class_marketing_name": "Economy Basic",
"cabin_class": "economy",
"baggages": [
{
"type": "checked",
"quantity": 1
}
]
}
],
"origin_terminal": "B",
"origin": {
"time_zone": "Europe/London",
"name": "Heathrow",
"longitude": -141.951519,
"latitude": 64.068865,
"id": "arp_lhr_gb",
"icao_code": "EGLL",
"iata_country_code": "GB",
"iata_code": "LHR",
"city_name": "London",
"city": {
"name": "London",
"id": "cit_lon_gb",
"iata_country_code": "GB",
"iata_code": "LON"
}
},
"operating_carrier_flight_number": "4321",
"operating_carrier": {
"name": "British Airways",
"id": "aln_00001876aqC8c5umZmrRds",
"iata_code": "BA"
},
"marketing_carrier_flight_number": "1234",
"marketing_carrier": {
"name": "British Airways",
"id": "aln_00001876aqC8c5umZmrRds",
"iata_code": "BA"
},
"id": "seg_00009htYpSCXrwaB9Dn456",
"duration": "PT02H26M",
"distance": "424.2",
"destination_terminal": "5",
"destination": {
"time_zone": "America/New_York",
"name": "John F. Kennedy International Airport",
"longitude": -73.778519,
"latitude": 40.640556,
"id": "arp_jfk_us",
"icao_code": "KJFK",
"iata_country_code": "US",
"iata_code": "JFK",
"city_name": "New York",
"city": {
"name": "New York",
"id": "cit_nyc_us",
"iata_country_code": "US",
"iata_code": "NYC"
}
},
"departing_at": "2020-06-13T16:38:02",
"arriving_at": "2020-06-13T16:38:02",
"aircraft": {
"name": "Airbus Industries A380",
"id": "arc_00009UhD4ongolulWd91Ky",
"iata_code": "380"
}
}
],
"origin_type": "airport",
"origin": {
"type": "airport",
"time_zone": "Europe/London",
"name": "Heathrow",
"longitude": -141.951519,
"latitude": 64.068865,
"id": "arp_lhr_gb",
"icao_code": "EGLL",
"iata_country_code": "GB",
"iata_code": "LHR",
"iata_city_code": "LON",
"city_name": "London",
"city": {
"name": "London",
"id": "cit_lon_gb",
"iata_country_code": "GB",
"iata_code": "LON"
},
"airports": [
{
"time_zone": "Europe/London",
"name": "Heathrow",
"longitude": -141.951519,
"latitude": 64.068865,
"id": "arp_lhr_gb",
"icao_code": "EGLL",
"iata_country_code": "GB",
"iata_code": "LHR",
"city_name": "London",
"city": {
"name": "London",
"id": "cit_lon_gb",
"iata_country_code": "GB",
"iata_code": "LON"
}
}
]
},
"id": "sli_00009htYpSCXrwaB9Dn123",
"fare_brand_name": "Basic",
"duration": "PT02H26M",
"destination_type": "airport",
"destination": {
"type": "airport",
"time_zone": "America/New_York",
"name": "John F. Kennedy International Airport",
"longitude": -73.778519,
"latitude": 40.640556,
"id": "arp_jfk_us",
"icao_code": "KJFK",
"iata_country_code": "US",
"iata_code": "JFK",
"iata_city_code": "NYC",
"city_name": "New York",
"city": {
"name": "New York",
"id": "cit_nyc_us",
"iata_country_code": "US",
"iata_code": "NYC"
},
"airports": [
{
"time_zone": "America/New_York",
"name": "John F. Kennedy International Airport",
"longitude": -73.778519,
"latitude": 40.640556,
"id": "arp_jfk_us",
"icao_code": "KJFK",
"iata_country_code": "US",
"iata_code": "JFK",
"city_name": "New York",
"city": {
"name": "New York",
"id": "cit_nyc_us",
"iata_country_code": "US",
"iata_code": "NYC"
}
}
]
},
"conditions": {
"change_before_departure": {
"penalty_currency": "GBP",
"penalty_amount": "100.00",
"allowed": true
}
}
}
],
"payment_requirements": {
"requires_instant_payment": false,
"price_guarantee_expires_at": "2020-01-17T10:42:14.545Z",
"payment_required_by": "2020-01-17T10:42:14.545Z"
},
"passengers": [
{
"type": "adult",
"loyalty_programme_accounts": [
{
"airline_iata_code": "BA",
"account_number": "12901014"
}
],
"id": "pas_00009hj8USM7Ncg31cBCL",
"given_name": "Amelia",
"family_name": "Earhart",
"age": 14
}
],
"passenger_identity_documents_required": false,
"owner": {
"name": "British Airways",
"id": "aln_00001876aqC8c5umZmrRds",
"iata_code": "BA"
},
"live_mode": true,
"id": "off_00009htYpSCXrwaB9DnUm0",
"expires_at": "2020-01-17T10:42:14.545Z",
"created_at": "2020-01-17T10:12:14.545Z",
"conditions": {
"refund_before_departure": {
"penalty_currency": "GBP",
"penalty_amount": "100.00",
"allowed": true
},
"change_before_departure": {
"penalty_currency": "GBP",
"penalty_amount": "100.00",
"allowed": true
}
},
"base_currency": "GBP",
"base_amount": "30.20",
"allowed_passenger_identity_document_types": [
"passport"
]
}
]
}

You should use this API to get the complete, up-to-date information about an offer. This endpoint does not guarantee that the offer will be available at the time of booking.

Due to limitations in airlines' systems, you may see changes to the offer (e.g a changed total_amount). Additionally, you may receive information that may have not been included in the original offer such as baggage allowances.

Optionally, you can request information about additional available_services that you can book with this offer by specifying the return_available_services query parameter.

URL parameters

id
string
required

Duffel's unique identifier for the offer

Example: "off_00009htYpSCXrwaB9DnUm0"

Query Parameters

return_available_services
boolean

When set to true, the offer resource returned will include all the available_services returned by the airline. If set to false, the offer resource won't include any available_services.

Example: true
Default value: false

Endpoint

GET https://api.duffel.com/air/offers/{id}

Request

curl -X GET --compressed "https://api.duffel.com/air/offers/{id}?return_available_services=true" \
-H "Accept-Encoding: gzip" \
-H "Accept: application/json" \
-H "Duffel-Version: beta" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>"

Response

{
"data": {
"updated_at": "2020-01-17T10:12:14.545Z",
"total_emissions_kg": "460",
"total_currency": "GBP",
"total_amount": "45.00",
"tax_currency": "GBP",
"tax_amount": "40.80",
"slices": [
{
"segments": [
{
"passengers": [
{
"passenger_id": "passenger_0",
"fare_basis_code": "OXZ0RO",
"cabin_class_marketing_name": "Economy Basic",
"cabin_class": "economy",
"baggages": [
{
"type": "checked",
"quantity": 1
}
]
}
],
"origin_terminal": "B",
"origin": {
"time_zone": "Europe/London",
"name": "Heathrow",
"longitude": -141.951519,
"latitude": 64.068865,
"id": "arp_lhr_gb",
"icao_code": "EGLL",
"iata_country_code": "GB",
"iata_code": "LHR",
"city_name": "London",
"city": {
"name": "London",
"id": "cit_lon_gb",
"iata_country_code": "GB",
"iata_code": "LON"
}
},
"operating_carrier_flight_number": "4321",
"operating_carrier": {
"name": "British Airways",
"id": "aln_00001876aqC8c5umZmrRds",
"iata_code": "BA"
},
"marketing_carrier_flight_number": "1234",
"marketing_carrier": {
"name": "British Airways",
"id": "aln_00001876aqC8c5umZmrRds",
"iata_code": "BA"
},
"id": "seg_00009htYpSCXrwaB9Dn456",
"duration": "PT02H26M",
"distance": "424.2",
"destination_terminal": "5",
"destination": {
"time_zone": "America/New_York",
"name": "John F. Kennedy International Airport",
"longitude": -73.778519,
"latitude": 40.640556,
"id": "arp_jfk_us",
"icao_code": "KJFK",
"iata_country_code": "US",
"iata_code": "JFK",
"city_name": "New York",
"city": {
"name": "New York",
"id": "cit_nyc_us",
"iata_country_code": "US",
"iata_code": "NYC"
}
},
"departing_at": "2020-06-13T16:38:02",
"arriving_at": "2020-06-13T16:38:02",
"aircraft": {
"name": "Airbus Industries A380",
"id": "arc_00009UhD4ongolulWd91Ky",
"iata_code": "380"
}
}
],
"origin_type": "airport",
"origin": {
"type": "airport",
"time_zone": "Europe/London",
"name": "Heathrow",
"longitude": -141.951519,
"latitude": 64.068865,
"id": "arp_lhr_gb",
"icao_code": "EGLL",
"iata_country_code": "GB",
"iata_code": "LHR",
"iata_city_code": "LON",
"city_name": "London",
"city": {
"name": "London",
"id": "cit_lon_gb",
"iata_country_code": "GB",
"iata_code": "LON"
},
"airports": [
{
"time_zone": "Europe/London",
"name": "Heathrow",
"longitude": -141.951519,
"latitude": 64.068865,
"id": "arp_lhr_gb",
"icao_code": "EGLL",
"iata_country_code": "GB",
"iata_code": "LHR",
"city_name": "London",
"city": {
"name": "London",
"id": "cit_lon_gb",
"iata_country_code": "GB",
"iata_code": "LON"
}
}
]
},
"id": "sli_00009htYpSCXrwaB9Dn123",
"fare_brand_name": "Basic",
"duration": "PT02H26M",
"destination_type": "airport",
"destination": {
"type": "airport",
"time_zone": "America/New_York",
"name": "John F. Kennedy International Airport",
"longitude": -73.778519,
"latitude": 40.640556,
"id": "arp_jfk_us",
"icao_code": "KJFK",
"iata_country_code": "US",
"iata_code": "JFK",
"iata_city_code": "NYC",
"city_name": "New York",
"city": {
"name": "New York",
"id": "cit_nyc_us",
"iata_country_code": "US",
"iata_code": "NYC"
},
"airports": [
{
"time_zone": "America/New_York",
"name": "John F. Kennedy International Airport",
"longitude": -73.778519,
"latitude": 40.640556,
"id": "arp_jfk_us",
"icao_code": "KJFK",
"iata_country_code": "US",
"iata_code": "JFK",
"city_name": "New York",
"city": {
"name": "New York",
"id": "cit_nyc_us",
"iata_country_code": "US",
"iata_code": "NYC"
}
}
]
},
"conditions": {
"change_before_departure": {
"penalty_currency": "GBP",
"penalty_amount": "100.00",
"allowed": true
}
}
}
],
"payment_requirements": {
"requires_instant_payment": false,
"price_guarantee_expires_at": "2020-01-17T10:42:14.545Z",
"payment_required_by": "2020-01-17T10:42:14.545Z"
},
"passengers": [
{
"type": "adult",
"loyalty_programme_accounts": [
{
"airline_iata_code": "BA",
"account_number": "12901014"
}
],
"id": "pas_00009hj8USM7Ncg31cBCL",
"given_name": "Amelia",
"family_name": "Earhart",
"age": 14
}
],
"passenger_identity_documents_required": false,
"owner": {
"name": "British Airways",
"id": "aln_00001876aqC8c5umZmrRds",
"iata_code": "BA"
},
"live_mode": true,
"id": "off_00009htYpSCXrwaB9DnUm0",
"expires_at": "2020-01-17T10:42:14.545Z",
"created_at": "2020-01-17T10:12:14.545Z",
"conditions": {
"refund_before_departure": {
"penalty_currency": "GBP",
"penalty_amount": "100.00",
"allowed": true
},
"change_before_departure": {
"penalty_currency": "GBP",
"penalty_amount": "100.00",
"allowed": true
}
},
"base_currency": "GBP",
"base_amount": "30.20",
"available_services": [
{
"type": "baggage",
"total_currency": "GBP",
"total_amount": "15.00",
"segment_ids": [
"seg_00009hj8USM7Ncg31cB456"
],
"passenger_ids": [
"pas_00009hj8USM7Ncg31cBCLL"
],
"maximum_quantity": 1,
"id": "ase_00009UhD4ongolulWd9123"
}
],
"allowed_passenger_identity_document_types": [
"passport"
]
}
}