Test your integration

This page includes test scenarios for our Duffel test environment to make sure your integration works as planned. Use it to trigger different flows in your integration and ensure they are handled accordingly.

Airline Routes

Flight search results can change without notice, even for the same routes on the same dates.
To test individual behaviours in your shopping experience, we provide a set of specific routes, origin (IATA Code) to destination (IATA Code), in our test environment that provides a predictable result for each request.

Offer Request API

NameOriginDestinationDescription
No FlightsRhode Island T.F. Green International Airport (PVD)Praia Nelson Mandela International Airport (RAI)No offers will be returned as a result of this request
Hold OrdersJohn F. Kennedy International Airport (JFK)Newark Liberty International Airport (EWR)Offers returned will all have requires_instant_payment=false
Connecting FlightsHeathrow Airport (LHR)Dubai International Airport (DXB)Offers returned will all have more than one segment, also known as a connecting flight
No Segment Passenger BaggagesBratislava Airport (BTS)Sir Seewoosagur Ramgoolam International Airport (MRU)Offers returned will have no baggages for all passengers across all segments
TimeoutLondon Stansted Airport (STN)Heathrow Airport (LHR)The offer request will timeout
Has StopsDubai Airport (DXB)Amsterdam Airport Schiphol (AMS)Offers will have one stop in the segment

No Flights

Whenever you search for flights, there is always a chance of no results being found for that specific data or itinerary. In order to cover that scenario, you can specifically search for a one-way flight from Rhode Island T.F. Green International Airport (PVD) to Praia Nelson Mandela International Airport (RAI) which will be guaranteed to never return any offers back.

Shell

curl -X POST --compressed "https://api.duffel.com/air/offer_requests" \
-H "Content-Type: application/json" \
-H "Accept-Encoding: gzip" \
-H "Duffel-Version: v1" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
-d '{
"data": {
"cabin_class": "economy",
"slices": [
{
"departure_date": "2023-01-08",
"destination": "RAI",
"origin": "PVD"
}
],
"passengers": [
{
"type": "adult"
}
]
}
}'

Hold Orders

Some airlines allow you to hold space on a flight and pay for it at a later time - known as a hold order that is indicated by the requires_instant_payment flag being false. In order to reliably cover this scenario, using the Duffel test environment, you can request a one way flight from John F. Kennedy International Airport (JFK) to Newark Liberty International Airport (EWR) which will return a DuffelAirways flight that can be used to create a hold order.

Shell

curl -X POST --compressed "https://api.duffel.com/air/offer_requests" \
-H "Content-Type: application/json" \
-H "Accept-Encoding: gzip" \
-H "Duffel-Version: v1" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
-d '{
"data": {
"cabin_class": "economy",
"slices": [
{
"departure_date": "2023-01-08",
"destination": "EWR",
"origin": "JFK"
}
],
"passengers": [
{
"type": "adult"
}
]
}
}'

Connecting Flights

A single trip might be composed of multiple connecting flights, for example, if you are flying from London to New York you might find flights that make a stop-over in Frankfurt first. In order to cover this scenario, using the Duffel test environment, you can request a one-way flight from Heathrow Airport (LHR) to Dubai International Airport (DXB) which will be guaranteed to return you flights with at least one stop-over flight in-between the origin and destination.

Shell

curl -X POST --compressed "https://api.duffel.com/air/offer_requests" \
-H "Content-Type: application/json" \
-H "Accept-Encoding: gzip" \
-H "Duffel-Version: v1" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
-d '{
"data": {
"cabin_class": "economy",
"slices": [
{
"departure_date": "2023-01-08",
"destination": "DXB",
"origin": "LHR"
}
],
"passengers": [
{
"type": "adult"
}
]
}
}'

No Segment Passenger Baggages

When you book a flight, there is a possibility that the airline does not give you any baggage. In order to cover this scenario, you can search for a one-way flight from Bratislava Airport (BTS) to Sir Seewoosagur Ramgoolam International Airport (MRU) which will return no baggages for any passenger across all segments for the flight.

Shell

curl -X POST --compressed "https://api.duffel.com/air/offer_requests" \
-H "Content-Type: application/json" \
-H "Accept-Encoding: gzip" \
-H "Duffel-Version: v1" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
-d '{
"data": {
"cabin_class": "economy",
"slices": [
{
"departure_date": "2023-01-08",
"destination": "MRU",
"origin": "BTS"
}
],
"passengers": [
{
"type": "adult"
}
]
}
}'

Timeout

Whenever you search for flights, there is a chance of the request timing out. In order to cover that scenario, you can specifically search for a one-way flight from London Stansted Airport (STN) to Heathrow Airport (LHR) which is guaranteed to timeout.

Shell

curl -X POST --compressed "https://api.duffel.com/air/offer_requests" \
-H "Content-Type: application/json" \
-H "Accept-Encoding: gzip" \
-H "Duffel-Version: v1" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
-d '{
"data": {
"cabin_class": "economy",
"slices": [
{
"departure_date": "2023-01-08",
"destination": "LHR",
"origin": "STN"
}
],
"passengers": [
{
"type": "adult"
}
]
}
}'
See more details about how to create an offer request here.

Offer API

NameOriginDestinationDescription
No Additional ServicesBratislava Airport (BTS)Abuja Airport (ABV)No services (e.g. additional baggage) will be included in this offer. In order to use this scenario return_available_services must be true.
Offer no longer availableGatwick Airport (LGW)Heathrow Airport (LHR)Offer no longer available
Offer price changeHeathrow Airport (LHR)London Stansted Airport (STN)Offer price change. The price of the offer will be different than what it was during offer request

No Additional Services

This scenario allows you to test your integration for when you've requested to see the services available for a particular offer and no services are found. Using the Duffel test environment, you can request a one-way flight from Bratislava Airport (BTS) to Abuja Airport (ABV) to test this scenario.
In order for this scenario to work, you'll need to provide as a query parameters the option return_available_services=true.

Shell

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: v1" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>"

Offer no longer available

This scenario allows you to test your integration when you have made your offer request and now ready to book the offer. There is no guarantee that the offer will be available to book as they can expire. That is why it is recommended to always use the GET offer endpoint to get up-to-date information about the offer. In order handle the offer expiry scenario, you can use the Duffel test environment, by creating an offer request for one-way flight from Gatwick Airport (LGW) to Heathrow Airport (LHR).

Shell

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

Offer price change

This scenario allows you to test your integration when you have made your offer request and now ready to book the offer. It is recommended to get the offer just before booking to get the latest state of the offer from the airlines. Sometimes the price of an offer can change. When this happens, you can see the latest state of the offer along with pricing with this endpoint. To simulate this you can use one-way flight from Heathrow Airport (LHR) to London Stansted Airport (STN) while creating the offer request and then use this endpoint to see a pricing change.

Shell

curl -X GET --compressed "https://api.duffel.com/air/offers/{id}" \
-H "Accept-Encoding: gzip" \
-H "Accept: application/json" \
-H "Duffel-Version: v1" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>"
See more details here about how to get an offer.

Order API

NameOriginDestinationDescription
Order creation errorHeathrow Airport (LHR)Gatwick Airport (LGW)Order creation error
Insufficient balance errorGatwick Airport (LGW)London Stansted Airport (STN)Insufficient balance error
Requested offer is no longer availableHeathrow Airport (LHR)London Stansted Airport (STN)Requested offer is no longer available (due to price change)
Card payment 200London Luton Airport (LTN)London Stansted Airport (STN)Reservation successful but order is not yet available
Card payment 202London Southend Airport (SEN)London Stansted Airport (STN)Request accepted but not yet confirmed

Order creation error

Sometimes due to unreliability of airlines, order creation fails. You can simulate this scenario using the Duffel test environment, by creating an offer request for a one-way flight from Heathrow Airport (LHR) to Gatwick Airport (LGW)
In order for this scenario to work, you'll need to create an offer request with the one-way route specified above. You will then have to use an offer from that offer request as the selected offer when creating the order.

Shell

curl -X POST --compressed "https://api.duffel.com/air/offer_requests" \
-H "Content-Type: application/json" \
-H "Accept-Encoding: gzip" \
-H "Duffel-Version: v1" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
-d '{
"data": {
"cabin_class": "economy",
"slices": [
{
"departure_date": "2023-01-08",
"destination": "LGW",
"origin": "LHR"
}
],
"passengers": [
{
"type": "adult"
}
]
}
}'

Shell

curl -X POST --compressed "https://api.duffel.com/air/orders" \
-H "Accept-Encoding: gzip" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Duffel-Version: v1" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
-d '{
"data": {
"type": "instant",
"selected_offers": [
"ID_OF_OFFER_FROM_OFFER_REQUEST_OF_ABOVE_SPECIFIED_ROUTE"
],
"payments": [
{
"currency": "GBP",
"amount": "30.20",
"type": "balance"
}
],
"passengers": [
{
"phone_number": "+442080160509",
"email": "amelia@duffel.com",
"born_on": "1987-07-24",
"title": "mrs",
"gender": "f",
"family_name": "Earhart",
"given_name": "Amelia",
"type": "adult",
"id": "pas_00009hj8USM7Ncg31cBCLL"
}
]
}
}'

Insufficient balance error

If you are a Managed Content customer using the Duffel wallet, you can sometimes run into insufficient balance error. This happens when your wallet does not have enough funds to pay for the order you are trying to book. You can simulate this scenario using the Duffel test environment, by requesting a one-way flight from GatwickAirport (LGW) to London Stansted Airport (STN)
In order for this scenario to work, you'll need to create an offer request with the one-way route specified above. You will then have to use an offer from that offer request as the selected offer when creating the order.

Shell

curl -X POST --compressed "https://api.duffel.com/air/offer_requests" \
-H "Content-Type: application/json" \
-H "Accept-Encoding: gzip" \
-H "Duffel-Version: v1" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
-d '{
"data": {
"cabin_class": "economy",
"slices": [
{
"departure_date": "2023-01-08",
"destination": "STN",
"origin": "LGW"
}
],
"passengers": [
{
"type": "adult"
}
]
}
}'

Shell

curl -X POST --compressed "https://api.duffel.com/air/orders" \
-H "Accept-Encoding: gzip" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Duffel-Version: v1" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
-d '{
"data": {
"type": "instant",
"selected_offers": [
"ID_OF_OFFER_FROM_OFFER_REQUEST_OF_ABOVE_SPECIFIED_ROUTE"
],
"payments": [
{
"currency": "GBP",
"amount": "30.20",
"type": "balance"
}
],
"passengers": [
{
"phone_number": "+442080160509",
"email": "amelia@duffel.com",
"born_on": "1987-07-24",
"title": "mrs",
"gender": "f",
"family_name": "Earhart",
"given_name": "Amelia",
"type": "adult",
"id": "pas_00009hj8USM7Ncg31cBCLL"
}
]
}
}'

Requested offer is no longer available

Sometimes the price of an offer can change between offer request creation and order creation and manifest itself as offer no longer available error while creating the order with that offer. To minimise this happening, it is recommended to always get the offer before booking to get its latest state from the airlines. Your integration should handle error code offer_no_longer_available resulting from this while creating an order. You can simulate this scenario using the Duffel test environment, by requesting a one-way flight from London Heathrow (LHR) to London Stansted Airport (STN)
In order for this scenario to work, you'll need to create an offer request with the one-way route specified above. You will then have to use an offer from that offer request as the selected offer when creating the order.

Shell

curl -X POST --compressed "https://api.duffel.com/air/offer_requests" \
-H "Content-Type: application/json" \
-H "Accept-Encoding: gzip" \
-H "Duffel-Version: v1" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
-d '{
"data": {
"cabin_class": "economy",
"slices": [
{
"departure_date": "2023-01-08",
"destination": "STN",
"origin": "LHR"
}
],
"passengers": [
{
"type": "adult"
}
]
}
}'

Shell

curl -X POST --compressed "https://api.duffel.com/air/orders" \
-H "Accept-Encoding: gzip" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Duffel-Version: v1" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
-d '{
"data": {
"type": "instant",
"selected_offers": [
"ID_OF_OFFER_FROM_OFFER_REQUEST_OF_ABOVE_SPECIFIED_ROUTE"
],
"payments": [
{
"currency": "GBP",
"amount": "30.20",
"type": "balance"
}
],
"passengers": [
{
"phone_number": "+442080160509",
"email": "amelia@duffel.com",
"born_on": "1987-07-24",
"title": "mrs",
"gender": "f",
"family_name": "Earhart",
"given_name": "Amelia",
"type": "adult",
"id": "pas_00009hj8USM7Ncg31cBCLL"
}
]
}
}'

200 Success and 202 Accepted responses when paying by card

When paying for an order by card, there may be cases when the reservation is confirmed but order information is not immediately available. Your integration should handle the 200 HTTP response resulting from this when creating an order. You can simulate this scenario using the Duffel test environment, by requesting a one-way flight from London Luton Airport (LTN) to London Stansted Airport (STN).
In addition, in rare cases the reservation can not be immediately confirmed. Your integration should handle a 202 HTTP response resulting from this when creating an order. You can simulate this scenario similarly with a London Southend Airport (SEN) to London Stansted Airport (STN) flight.
In order for this scenario to work, you'll need to create an offer request with one of the one-way route specified above. You will then have to use an offer from that offer request as the selected offer when creating the order.
In both cases, the order will be immediately available after receiving 200/202 response. You can find more details about locating an order by offer ID here. An order.created webhook notification will be sent 30 seconds after. Please note that in actuality, we anticipate resolution within an hour in most cases, but in rare instances it could take longer.

Shell

curl -X POST --compressed "https://api.duffel.com/air/offer_requests" \
-H "Content-Type: application/json" \
-H "Accept-Encoding: gzip" \
-H "Duffel-Version: v1" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
-d '{
"data": {
"cabin_class": "economy",
"slices": [
{
"departure_date": "2024-01-08",
"destination": "STN",
"origin": "LTN"
}
],
"passengers": [
{
"type": "adult"
}
]
}
}'

Shell

curl -X POST --compressed "https://api.duffel.com/air/orders" \
-H "Accept-Encoding: gzip" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Duffel-Version: v1" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
-d '{
"data": {
"type": "instant",
"selected_offers": [
"ID_OF_OFFER_FROM_OFFER_REQUEST_OF_ABOVE_SPECIFIED_ROUTE"
],
"payments": [
{
"currency": "GBP",
"amount": "30.20",
"type": "card",
"card_id": "tcd_123"
}
],
"passengers": [
{
"phone_number": "+442080160509",
"email": "amelia@duffel.com",
"born_on": "1987-07-24",
"title": "mrs",
"gender": "f",
"family_name": "Earhart",
"given_name": "Amelia",
"type": "adult",
"id": "pas_00009hj8USM7Ncg31cBCLL"
}
]
}
}'
See more details here about how to get an offer.
See more details here about how to create an order.

Airline-Initiated Changes API

NameOriginDestinationDescription
Simulating a changeHeathrow Airport (LHR)London Luton Airport (LTN)Creates a fake airline-initiated change

Simulating a change

Sometimes there can be changes to your flight initiated by the airline, for example a delay in departure time. You can simulate this by creating an order for a one-way flight from Heathrow Airport (LHR) to London Luton Airport (LTN) Once you have done that, you should call the API to list airline-initiated changes for that order. A new change will be created for each API call.

Shell

curl -X GET --compressed "https://api.duffel.com/air/airline_initiated_changes?order_id=<your_order_id>" \
-H "Accept: application/json" \
-H "Accept-Encoding: gzip" \
-H "Duffel-Version: v1" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>"
See more details here about airline-initiated changes.

Airline Credits

NameOriginDestinationDescription
Simulating a refund to airline creditsLondon Luton Airport (LTN)London Stansted Airport (STN)Creates an order which will be refunded to airline credits if cancelled

Simulating a refund to airline credits

Sometimes when a flight is cancelled it will be refunded to airline credits. You can simulate this by creating an order for a one-way flight from London Luton Airport (LTN) to London Stansted Airport (STN) You should then call the API and create an order cancellation. The cancellation returned will have the refund_to property as airline_credits and when the cancellation is confirmed you will be able to see the credit codes.

Shell

curl -X POST --compressed "https://api.duffel.com/air/order_cancellations" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Accept-Encoding: gzip" \
-H "Duffel-Version: v1" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
-d '{
"data": {
"order_id": "<your_order_id>"
}
}'
See more details here about order cancellations.