Dear API Partners and Users,
We're excited to share an update on the significant enhancements and changes we've implemented on our platform over the past six months. These improvements are designed to boost performance, enhance stability, and offer new functionalities, all while maintaining backward compatibility. Many of these changes may be visible in BookingPad, and we're now opening them up for you to leverage directly through our API.
Here’s a summary of the key updates relevant to our API:
Flexible Order Changes and Payments: Our platform now supports adding order changes without immediate payment, offering greater flexibility. Key features include the ability to set "Changes on hold" and issue pending payments afterwards. You can check if a given airline accepts this using the allowedRequests > ticketed >
AncillariesOnHold
node.
Improved Offer Expiration Handling: Expired orders now trigger an OrderRetrieve in "airline" cache mode to ensure that's the real status from the airline. The system automatically updates segment statuses to "UN" (unknown) if errors occur or segments are missing. If we don't get a proper response from the airline we'll include the last version we cached + the warning or error received.
Contextual Airline Notifications: The API now includes a “contextMeaning” field within amendments, providing specific context for airline notifications. Now you don't need to handle this on your side, you'll receive full information to show the disruptions to your users, including the code from the airline and the root cause, for example:
"1": "Flight Number Change",
"2": "Flight Time Change",
"3": "Flight Cancellation",
"4": "Permanent Withdrawal",
"5": "Labor Disrupt",
"6": "Bereavement",
"7": "No Reason Given",
"8": "Illness",
"9": "Voluntary",
"10": "Need Documentation",
"11": "Strike",
"12": "Weather",
"13": "Natural Disaster",
"14": "Unacceptable Recommendation",
"15": "Flight Booking Cancelled Outside Schedule",
"101": "Seat Change",
"104": "Payment Time Limit Expired",
"112": "Change By Passenger Notification",
"113": "Passenger No Show Notification",
Enhanced Servicing Options: We've refined the logic for enabling and disabling servicing options based on pending payments, ensuring a smoother user experience. You can rely on allowedRequests > pending
node to know what's available for a given order. If there are pending payments, we disable rebooks, upgrades and splits too.
Streamlined Data Handling: You can now use the AG-Avoid-Disclosures header to exclude extensive disclosures from AirShopping responses, reducing data load. Check our docs for more information.
Optimized Timeout Management: The platform now includes an AG-Request-Timeout feature, cutting processing after the set timeout (in seconds), ensuring quicker responses. This header is mandatory.
"classOfService": {
"cabinDesignator": "XXXXXX",
"fare": {
"basisCode": "IAM7V2RCH/Y IAM7V2RIN/Y IAM7V2R/Y"
Expanded Data and Parameter Support:
Text
: Free textOSICode
: This can be blank, in this case, it won’t be included.ActionCode
: This can be blank, in this case, it won’t be included.PassengerRef
: Reference to the passenger who is attached to this OSI. It can be blank and in that case it’s not attached to any passenger.New order statuses: New statuses CANCELLING & VOIDING have been introduced to have more clarity of the orders. This is because some airlines take a little longer than expected to actually cancel or void orders and we want to give exactly the same information we receive.
Flexible Payment Options: Cash payments are now supported with BT.
New Filters: Added the possibility to filter by flight number in AirShopping
for all airlines. ItinShopping
makes use of this filter too so times have improved a lot. You can include the flight numbers in each segment of your AirShopping
, for example:
"originDestinations": [ { "arrival": { "airportCode": "MAD", "time": "" }, "departure": { "airportCode": "LHR", "date": "2025-02-27", "time": "" }, "flightNumbers": [ "IB0001", "IB0002" ] }, { "arrival": { "airportCode": "LHR", "time": "" }, "departure": { "airportCode": "MAD", "date": "2025-03-06", "time": "" } }
Error Message Clarification: We've renamed the method_not_allowed_for_provider_on_stage
error to method_not_allowed_for_provider_on_current_state
to provide a clearer understanding of the issue.
Improved data fields: Penalties are now returned in a new field called “penalty
” in OrderReshop
, OrderReshopReprice
, and PaymentInfo
.
Allowed adding seats and services on OrderCreate for FR and U2. Initially it was possible to add services once the order was created, before it was issued. Now we allow SeatAvailability and ServiceList pre-order and adding them to the OrderCreate with form of payment so the order is created and issued at the same moment.
Disabled cabins for a given airline will not work. You'll receive 403 - AGW_cabin_not_allowed
when a cabin is not available for a given airline.
Max number of segments allowed. Some airlines (for example, TAP) don't allow more than X number of segments per search. We've set these restrictions on our platform so you'll receive a 400 - AGW_too_many_segments
if you try to search more than expected.
410
when an order is Blocked.Cash payments with BT. Now we support Cash payments with AirBaltic.
History improvements. When we detect changes in HK segments, we return a summary of the changes in history, so you can see if there has been a time or date change or even a cancellation for some segments.
AirShopping
now. If you send a single AirShopping
for "all your providers", a regular search will be sent to all your airlines except those present in presets, which will be sent just with the information inside the presets. This allows you to do a regular search for all airlines but including another one with special fares from an specific airline. From our swagger docs:"presets": [ { "airlineID": "AF", "preferences": { "fareList": [ { "Code": "70E", "Definition": "TO" }, { "Code": "70F", "Definition": "VF" } ] }, "ptcMap": { "ADT": "JCB", "CHD": "JNN", "INF": "JNF" }, "qualifier": { "airline": "AF", "code": "XY32Z", "type": "account_id" }, "taxExemptions": [ "XXX", "YYY", "ZZZ" ] } ],
Starting in February 2025, a new header will be required for AirShopping requests.
Please refer to the documentation on AG-Request-timeout
here:
https://support.airgateway.com/kb/article/9/sending-requests
We recommend setting a value under 60 seconds, but you can adjust it to suit your application's wait time. This feature is already available in our sandbox environment for testing before the production release. You can also include it in your production environment now, but it will not take effect until February.
We've released several changes that we want to share with you.
Requirements for secure flights (like including Passport) have been removed and we only send a warning message instead:
“This is a secure flight. Passport/National ID and Date Of Birth information might be required by the provider before issuing. Please keep in mind we don't support passenger updates with all providers”
Some airlines do not require such information in some cases (for example, secure flights inside de USA with AA) so we leave it up to your agents to decide if they want to include all that information or not.
Sometimes we try to do an OrderRetrieve for an order that does not exist in the airline / provider systems. In some of these cases, we just get an error from the airline and we used to return the cached version of the order.
Now we return the cached version of the order but including the original error from the airline, for example:
ORDER ID XXXXXXXXXXX cancelled
A warning message indicating the problem is included too:
This order is no longer available on the airline system. This might be due to airline cancellation
We've included upselling offers in OfferPrice for those airlines who offer this. You can find that information inside "otherOffers
":
https://api.airgateway.net/v1.2/swagger-ui/#/NDC%20Methods/OfferPrice%23Post
This is included for BA, AF, AV, AY, KL, SQ, TP and LH currently, but we'll include it for all airlines adding such information in the future.
Sometimes cancellation workflow was not correctly done, including extra requests between OrderReshopRefund and OrderCancel.
https://support.airgateway.com/kb/article/13/servicing-workflows
Now an error is raised if the workflow is not accomplished as expected.
Now the document field is officially deprecated and we'll remove it in June 2024. You can safely use documents instead, currently both fields are supported to make transition easier.
https://api.airgateway.net/v1.2/swagger-ui/#/NDC%20Methods/OrderCreate%23Post
With documents you can add as many documents as you want and with many more types (if the airline supports it), including fiscal / tax ids.
We expect an array of numbers with the max stops per segments searched. If you sent less max stops than segments, we returned an error until now (for instance, if you sent 1 max stops number for a round trip). Now we use the first number we receive for all segments if the number of max stops is below the number of segments.
Tracer has a new button to copy an exact request from tracer to let you retry it directly in your terminal.
Errors in AirShopping
AirShopping errors were slightly different from the rest of the errors of the platform. Now they follow the same format we use in every single response, even when the error is no availability:
{
"code":"AGW_no_available_journey",
"detail":"no available journey for this search",
"group":"provider_error","offerExpiration":
"0001-01-01T00:00:00Z",
"provider":"XX"}
We use this as a way to offer more details to the customer about what's going on:
Today we're releasing a new change in sandbox environment to change the way the users login in our platform.
Your API tokens should still work as usual, but you'll need to recover your password to login in agency portal, tracer or BookingPad.
We expect some minutes of downtime in sandbox for the next few hours, thanks for your patience.
Today we've released a new and important change in our platform.
We've introduced "Airline Notifications" instead of "Disruptions". You can see the details about this change in BookingPad checking our help article:
On the API level, this change includes lots of new information that you can show and treat from your apps.
First of all, now we include a new airlineNotifications
field. You can check that documentation in our swagger, in OrderRetrieve
method:
https://api.airgateway.net/v1.2/swagger-ui/#/NDC%20Methods/OrderRetrieve%23Post
It consist of an array of notifications (there can be many notifications per order) with lots of information included:
If there's any following action needed, you'll receive it in actionRequired
. Information about the changes themselves will be included inside the amendments
field (there can be many amendments per notification). Inside you'll have context, type and remarks.
The message is just a free text explaining the context of the notification.
Apart from that, there are lots of new events that can be used and configured as emails or webhooks so you get notifications every time a new OrderChangeNotification is received:
FlightNumberChange
FlightTimeChange
FlightCancelation
PermanentWithfrawan
LaborDisrupt
Strike
Weather
NaturalDisaster
FlightBookingCancelledOutsideSchedule
SeatChange
Bereavement
NoReasonGiven
Illness
Voluntary
NeedDocumentation
UnacceptableReacomodation
PaymentTimeLimitExpired
PassengerNoShowNotification
ChangeByPassengerNotification
UnknownNotification
Finally, we've included a new endpoint so you can mark a given notification as seen (so it's not shown in BookingPad as a warning) but you'll always be able to see the full list of them under History.
If you need help or clarifications, please let us know through our support channels as usual.
Happy new year! During the last weeks of 2023 we released several features that we want to share with you.
First of all, we've moved to releasenotes as you can see, so you can find our updates here in https://airgateway.releasenotes.io.
You can use Bluebiz or Corporate codes in different ways and steps. You can test this in BookingPad directly, check our article about this here.
Blue Biz recognition at Shopping
You can send the Blue Biz code inside "corporateLoyaltyProgramCodes
" field so all the offers you'll receive will specifically for your corporate and if you create an order it will be tied to that corporate already.
{
"corporateLoyaltyProgramCodes": {
"AF": "XXXXXXX"
},
"metadata": {
"country": "DE",
"currency": "EUR",
"locale": "de_DE"
},
"originDestinations": [
{
"arrival": {
"airportCode": "MAD",
"time": ""
},
"departure": {
"airportCode": "CDG",
"date": "2023-12-04",
"time": ""
}
},
{
"arrival": {
"airportCode": "CDG",
"time": ""
},
"departure": {
"airportCode": "MAD",
"date": "2023-12-23",
"time": ""
}
}
],
"passengers": [
{
"passengerType": "ADT",
"travelerReference": "ADT0"
}
],
"preferences": {
"cabin": [
"7"
],
"nonStop": false
}
}
Blue Biz recognition at booking creation
You can search regularly but then add the Blue Biz code in OrderCreate request directly. You can use the field "loyaltyProgramAccount
" here (it will be for the current airline, obviously).
{ "corporateID": "XXXXXX", // Only needed if you're using our Traveler Profiles system "loyaltyProgramAccount": "XXXXXXXX", "passengers": [ { "data": { "address": { "cityName": "", "countryCode": "", "label": "addressAtHome", "postalCode": "", "street": "" }, "birthdate": "1992-11-30", "email": "test@test.com", "fqtvInfo": { "account": { "number": "" }, "airlineID": "" }, "gender": "Male", "name": "TEST", "phone": "+34666234234", "surname": "TEST", "title": "MR" }, "passengerType": "ADT", "travelerReference": "PAX1" } ], "shoppingResponseID": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }
Corporate Recognition with a Published fare
You can send corporate program account codes in OrderCreate too. You can use the same "loyaltyProgramAccount field like before, but instead of sending a Blue Biz code, just send a Corporate code.
{
"corporateID": "XXXXXXXXXXXXXXXXXXXX", // Only needed if you're using our Traveler Profiles system
"loyaltyProgramAccount": "XXXXXX",
"passengers": [
{
"data": {
"address": {
"cityName": "",
"countryCode": "",
"label": "addressAtHome",
"postalCode": "",
"street": ""
},
"birthdate": "1992-11-30",
"email": "test@test.com",
"fqtvInfo": {
"account": {
"number": ""
},
"airlineID": ""
},
"gender": "Male",
"name": "TEST",
"phone": "+34666234234",
"surname": "TEST",
"title": "MR"
},
"passengerType": "ADT",
"travelerReference": "PAX1"
}
],
"shoppingResponseID": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
Now you can use new "SEA
" PTCs to ask for Marine Private fares. You need to include the given fare preference and qualifier. Please try it in BookingPad if you want to get fresh examples (you have an article about this here).
{ "metadata": { "country": "DE", "currency": "EUR", "locale": "de_DE" }, "originDestinations": [ { "arrival": { "airportCode": "MAD", "time": "" }, "departure": { "airportCode": "HEL", "date": "2024-03-06", "time": "" } } ], "passengers": [ { "passengerType": "SEA", "travelerReference": "SEA0" } ], "preferences": { "cabin": [ "7" ], "fareList": [ { "Code": "758", "Definition": "M" } ], "nonStop": false }, "qualifier": { "airline": "AY", "code": "AYMARINE", "type": "account_id" } }
We've unified all coupon statuses to always use the PADIS codeset 4405.
700 - No active itinerary 701 - Notification 702 - Active 703 - Queue placement is inhibited 704 - Queue level notification 705 - Queue being printed 706 - Sub-queue present 707 - On hold 708 - Exchanged to FIM 709 - Passenger deleted 710 - Refund Taxes / Fees / Charges Only A - Add AC - Accrual AL - Airport Control ALL - Allocated AVA - Available B - Flown / Used BD - Lifted / Boarded C - Change CK - Checked-in CLO - Closed D - Reprint DB - Deboarded DN - Denied boarding E - Exchanged / Reissued F - Critical free text G - Non air segment I - Original Issue (Open for Use) IF - Information only INU - In use IO - Irregular operations K - Confirmed, effective, working, firm, etc LIM - Limitations on use NAV - Not available NC - Not checked in NS - Infant, no seat OF - Offloaded OK - Confirmed OLD - Replaced item OPE - Open for use P - Provisional, draft proposed subject to change, etc PAV - Partial Availability - Specified sub-elements only PE - Print Exchange PR - Printed PRF - Preferred PRP - Proposed/Intended Allocation R - Request RD - Redemption REP - Replacement REV - Revised RF - Refunded RQ - Requested S - Suspended SA - Space Available SB - Standby SRV - Serviceable T - Ticketed UNS - Unserviceable V - Void WL - Waitlisted X - Cancel PRTX - Printed Interline CTRL - Control NOGO - NO-GO UTL - Unable to Locate PRFD - Partially Refunded
The only exception to this is AERTiCKET which return different codes depending on each of their airlines, so we just rely on the information they return.
We have included bundles as "other offers" inside OfferPrice responses. So you can get details for a given offer from AirShopping but see more alternatives for the same offer with bundles which include other information like baggage or seats. This information is included in the same node we use for other airlines like BA when they include upsellings in their OfferPrice
"otherOffers": [ { "createdAt": 1704380647, "disclosures": [ { "descriptions": [ { "category": "BAGGAGE_CARRYON", "item": "BAGGAGE_CARRYON", "metadataToken": "", "originDestinationReference": "", "properties": [ { "UOM": "CM", "type": "Length", "value": "45" }, { "UOM": "CM", "type": "Width", "value": "36" }, { "UOM": "CM", "type": "Height", "value": "20" }, { "UOM": "CM", "type": "Length", "value": "56" }, { "UOM": "CM", "type": "Width", "value": "45" }, { "UOM": "CM", "type": "Height", "value": "25" } ], "text": "One small cabin bag (Maximum size 45 x 36 x 20 cm.Must fit under the seat in front of you.)\nOne large cabin bag (Maximum size 56 x 45 x 25 cm.)", "units": "1" }, { "category": "BOARDING", "item": "HIGH_PRIORITY", "metadataToken": "", "originDestinationReference": "", "text": "Speedy Boarding (Be amongst the first to board, or board at your leisure.)", "units": "" }, { "category": "SEAT", "item": "SEAT_RESERVATION", "metadataToken": "", "originDestinationReference": "", "text": "Free Up Front seat", "units": "" } ], "listKey": "PC2" } ], ...
Until now, you could try voiding an order whenever you prefer, but this could lead to problems sometimes.
Until know, you could call OrderReshopRefund
to know how much you'd get in a refund, but you could call OrderCancel
directly too. You need to include the type
in OrderCancel
payload:
{
"id": "AGW-JHTE1543KJ",
"type": "void"
}
In order to improve this, we included a flag in our allowedRequests
section so you could check if an order was still allowed to void or not.
"allowedRequests": { "pending": { "OrderCancel": true, "OrderReprice": true, "OrderSplit": false, "SeatAvailability": true, "ServiceList": true, "TicketIssue": true }, "started": { "OrderCancel": false, "OrderReshop": true, "OrderReshopRefund": false }, "ticketed": { "AncillariesOnHold": true, "OrderCancel": true, "OrderCancelToVoucher": false, "OrderReshop": true, "OrderReshopRefund": true, "OrderReshopRouteChange": true, "OrderSplit": false, "OrderVoid": false, "SeatAvailability": true, "ServiceList": true }
The problem with this approach is that, sometimes, new rules were introduced and we didn't know so maybe we expected an order to be voideable but the airline ended up saying "this is not voideable anymore". This OrderVoid
flag is now deprecated and you should stop using it.
Now we have improved OrderReshopRefund a little bit so we can give you more information about airline's allowance to void:
We've improved the workflow to know if you can void an order or you need to cancel and refund. Now, whenever you try to cancel or void an order, you should call OrderReshopRefund
first. Now, on top of previous information that we already included (the expected amount you'd receive in an refund), you'll receive another node with the type of OrderCancel
you should call.
{ "trace": { "requestID": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "sessionID": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }, "type": "void" }
There are three different values you can receive here:
Void
and Refund
are self-explanatory. If you receive an unknown
it means that we can't know if it's in voiding period or not. This is only happening with IB
, BA
and LA
and, in these cases, you can decide if you try to void or refund. For instance, we have solved this in BookingPad by showing both buttons in those cases so the agents can decide what to do.
Remember that you can always check our dev guides and swagger docs to get the most up to date docs using our API.
Tomorrow 2023/10/31 from 13:00 to 15:00 (CET) maintenance tasks will be carried out in our sandbox environment.
This will cause a disruption in Sandbox and it is expected to last 2 hours.
Sorry for the inconvenience.
Last week we did a new release with some interesting updates.
AirShopping
and ItinShopping
(check below)AirShopping
when calling our ItinShopping
endpoint tooUntil now, we were receiving passenger's information like this:
"travelers": { "ADT": 1, "CHD": 0, "INF": 0, "V14": 0, "VFR": 0, "VNF": 0, "VNN": 0, "YAD": 0 }
We've introduced a new way to send more information:
"passengers": [ { "infantReference": "INF0", "passengerType": "ADT", "travelerReference": "ADT0" }, { "passengerType": "ADT", "travelerReference": "ADT1" }, { "passengerType": "YAD", "travelerReference": "YAD0" }, { "passengerType": "CHD", "travelerReference": "CHD0" }, { "passengerType": "INF", "travelerReference": "INF0" } ],
With this new approach, you'll be able to send more information like the type of the passenger and its reference (so you can say details like "this infant travels with this adult", for example).
This new approach lets you send any PTCs you want, which is something basic when trying to get private fares.
The old approach is still valid but we encourage you to move ASAP to the new approach. The old "travelers
" node will eventually be deprecated so we'd like to get your confirmation once you start using "passengers
".
Some services are added once but they are "available" in many segments. For example if you add a service for extra luggage in a three segments flight, you'll pay once but it will be included in all your segments.
Until now we were returning the details of the service in each segment, but that can lead to missunderstandings (like thinking it's paid in each segment). To solve this, we're returning such services with a single reference to the first segment they're present inside segmentReferences
, but we've added a new field called segmentReferencesIncluded
which contains all the references to segments where it's available.
For example, this service is included in both segments S3 and S4, but it's paid only once (we show S3 as segment references for that):
"services": [ { "bookingInstructions": { "mandatoryText": "", "pattern": "", "placeHolder": "", "type": "" }, "bundledWith": "", "isSSR": false, "maximumQuantity": 1, "minimumQuantity": 1, "name": "EXTRA BAGGAGE", "objectKey": "C-OC-0CC-BG", "pendingPayment": false, "price": { "consumer": { "base": 0, "currency": "EUR", "surcharge": 0, "tax": { "total": 0 }, "total": 31 }, "provider": { "base": 0, "currency": "EUR", "surcharge": 0, "tax": { "total": 0 }, "total": 31 } }, "ref": "Service", "removable": true, "segmentReferences": "S3", "segmentReferencesIncluded": [ "S3", "S4" ], "serviceID": "C-OC-0CC-BG", "travelerReferences": "T1" },
As we said in our previous release note, we've changed the behaviour of our Ag-OrderRetrieve-Mode
header.
Now we have 2 different modes:
airline
- sends request to airline to get up-to-date contentdefault
- gets cached orderRemember that you can always check our dev guides and swagger docs to get the most up to date docs using our API.
Last week we did a new release with some interesting updates.
AG-Search-Mode
.cheapest_flights
-> This will return the cheapest flights from each airline response only.cheapest_flights_per_cabin
-> This will return the cheapest flights for each cabin type.combine_same_fares_only
-> This works for some airlines like EK or LH only. These airlines will send offers for each leg and rules for combinations. With this search mode we'll just combine offers with the same fare (for example, Economy Basic Plus with Economy Basic Plus, Business Basic with Business Basic...)application
-> type of discount applieddescription
-> what this discount is aboutvalue
-> amount of the discount"discount":{"application":"BP","description":"Residente Baleares","value":45.38}
We're planning to change the behaviour of our Ag-OrderRetrieve-Mode
header.
Currently we have 3 different modes:
airline
- sends request to airline to get up-to-date contentcached
- forces to get cached orderdefault
(or not provided) - sends request to airlineNext month we'll release a change to return the cached version by default, so you'll have to send the "airline" value if you want to refresh information from airline at any point. You can avoid sending cached too, since that's going to be the default behaviour now.
It will be available in sandbox next week and in production next October 17th.
Remember that you can always check our dev guides and swagger docs to get the most up to date docs using our API.
Next 2023-09-05, Tuesday, we'll release a change in sandbox to remove and old and misleading field:
fare > standardName
This field is returned in many of our responses right now (AirDocIssue, AirShopping, OfferPrice, OrderChange, OrderReshop, OrderReshopRefund, OrderReshopReprice, OrderRetrieve, OrderUpdate, SeatAvailability, ServiceList and ItinShopping) in this path:
flights > segments > detail > classOfService > fare > standardName
This was used as a way to homogenize all fares between airlines, but we finally realized that it's better to rely on airlines information (use fare > marketingName instead).
This change will be in sandbox for 2 months before we release it to production, so please stop using it ASAP to be prepared.
Remember that you can always check our dev guides and swagger docs to get the most up to date docs using our API.