Skip to main content

Onboarding — from credentials to a cancelled order

This walks the whole journey against the sandbox (https://ndc.retailaer.com) in six calls. Every XML body below is exactly what the airline's own sandbox scenarios send; the Postman collection carries the same requests. What each message can do today is on the Capabilities page — the sandbox answers every implemented message, and flags the parts that rest on simulated supply (flight inventory, the card processor, settlement, the operations clock) with a simulated_* warning.

1. Credentials​

The airline registers your agency as an NDC client and gives you a client_id, a client_secret (shown once) and your agency id. Ask for the scopes you need:

ScopeLets you send
ndc:shopAirShopping, OfferPrice, ServiceList, SeatAvailability
ndc:orderOrderRetrieve, OrderHistory, OrderList, OrderRules, ServiceDelivery
ndc:order:writeOrderCreate, OrderChange, OrderReshop, OrderQuote
ndc:settlethe PaymentClearance messages (settlement)
ndc:notif:subscribenotification subscriptions

Get a token (it lives 30 minutes — cache it):

curl -X POST https://ndc.retailaer.com/oauth/token \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-d grant_type=client_credentials
export TOKEN="…" # access_token

Every NDC call is an XML POST to https://ndc.retailaer.com/24.4/<Message> with Authorization: Bearer $TOKEN, Content-Type: application/xml and IATA-Message-Name: IATA_<Message>. See Authentication.

2. Shop — AirShoppingRQ​

curl -X POST https://ndc.retailaer.com/24.4/AirShoppingRQ \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/xml' \
-H 'IATA-Message-Name: IATA_AirShoppingRQ' --data-binary @shop.xml
shop.xml
<IATA_AirShoppingRQ xmlns="http://www.iata.org/IATA/2015/EASD/00/IATA_OffersAndOrdersMessage">
<DistributionChain>
<DistributionChainLink xmlns="http://www.iata.org/IATA/2015/EASD/00/IATA_OffersAndOrdersCommonTypes">
<Ordinal>1</Ordinal>
<OrgRole>Seller</OrgRole>
<ParticipatingOrg>
<Name>Skyline Travel</Name>
<OrgID>YOUR-AGENCY-ID</OrgID>
</ParticipatingOrg>
</DistributionChainLink>
<DistributionChainLink xmlns="http://www.iata.org/IATA/2015/EASD/00/IATA_OffersAndOrdersCommonTypes">
<Ordinal>2</Ordinal>
<OrgRole>Carrier</OrgRole>
<ParticipatingOrg>
<OrgID>RT</OrgID>
</ParticipatingOrg>
</DistributionChainLink>
</DistributionChain>
<PayloadAttributes>
<CorrelationID xmlns="http://www.iata.org/IATA/2015/EASD/00/IATA_OffersAndOrdersCommonTypes">corr-scn-1</CorrelationID>
<TrxID xmlns="http://www.iata.org/IATA/2015/EASD/00/IATA_OffersAndOrdersCommonTypes">trx-scn-1</TrxID>
<VersionNumber xmlns="http://www.iata.org/IATA/2015/EASD/00/IATA_OffersAndOrdersCommonTypes">24.4</VersionNumber>
</PayloadAttributes>
<Request>
<FlightRequest xmlns="http://www.iata.org/IATA/2015/EASD/00/IATA_OffersAndOrdersCommonTypes">
<FlightRequestOriginDestinationsCriteria>
<OriginDestCriteria>
<DestArrivalCriteria>
<IATA_LocationCode>AMS</IATA_LocationCode>
</DestArrivalCriteria>
<OriginDepCriteria>
<Date>2027-03-15</Date>
<IATA_LocationCode>MAD</IATA_LocationCode>
</OriginDepCriteria>
<OriginDestID>OD1</OriginDestID>
</OriginDestCriteria>
</FlightRequestOriginDestinationsCriteria>
</FlightRequest>
<PaxList xmlns="http://www.iata.org/IATA/2015/EASD/00/IATA_OffersAndOrdersCommonTypes">
<Pax>
<PaxID>PAX1</PaxID>
<PTC>ADT</PTC>
</Pax>
</PaxList>
</Request>
</IATA_AirShoppingRQ>

The DistributionChain and PayloadAttributes are the same on every request below — the Seller is your agency id, the Carrier is RT. Keep one CorrelationID per journey and a fresh TrxID per transaction: a retried OrderCreateRQ with the same pair returns the order it already created instead of booking twice.

From the IATA_AirShoppingRS, take an offer: Response/OffersGroup/CarrierOffers/Offer/OfferID, its OfferItem/OfferItemID and its TotalPrice.

3. Price — OfferPriceRQ​

Re-price the offer you chose (the envelope as above; only Request shown):

<Request>
<PricedOffer xmlns="http://www.iata.org/IATA/2015/EASD/00/IATA_OffersAndOrdersCommonTypes">
<SelectedOfferList>
<SelectedOffer>
<OfferRefID>OFFER-ID</OfferRefID>
<OwnerCode>RT</OwnerCode>
<SelectedOfferItem>
<OfferItemRefID>OFFER-ITEM-ID</OfferItemRefID>
<PaxRefID>PAX1</PaxRefID>
</SelectedOfferItem>
</SelectedOffer>
</SelectedOfferList>
</PricedOffer>
</Request>

An offer past its validity answers offer_stale — shop again.

4. Book and pay — OrderCreateRQ​

Name the passenger and pay the priced total with a PSP token — never a card number (a request carrying one is refused with pan_not_accepted before it is read). The sandbox card processor approves tok_visa_approve, declines tok_card_declined and asks for 3-D Secure on tok_3ds_required.

<Request>
<CreateOrder xmlns="http://www.iata.org/IATA/2015/EASD/00/IATA_OffersAndOrdersCommonTypes">
<AcceptSelectedQuotedOfferList>
<SelectedPricedOffer>
<OfferRefID>OFFER-ID</OfferRefID>
<OwnerCode>RT</OwnerCode>
<SelectedOfferItem>
<OfferItemRefID>OFFER-ITEM-ID</OfferItemRefID>
<PaxRefID>PAX1</PaxRefID>
</SelectedOfferItem>
</SelectedPricedOffer>
</AcceptSelectedQuotedOfferList>
</CreateOrder>
<DataLists xmlns="http://www.iata.org/IATA/2015/EASD/00/IATA_OffersAndOrdersCommonTypes">
<ContactInfoList>
<ContactInfo>
<ContactInfoID>CI1</ContactInfoID>
<EmailAddress>
<EmailAddressText>ada@example.com</EmailAddressText>
</EmailAddress>
</ContactInfo>
</ContactInfoList>
<PaxList>
<Pax>
<ContactInfoRefID>CI1</ContactInfoRefID>
<Individual>
<GivenName>Ada</GivenName>
<Surname>Lovelace</Surname>
</Individual>
<PaxID>PAX1</PaxID>
<PTC>ADT</PTC>
</Pax>
</PaxList>
</DataLists>
<PaymentFunctions xmlns="http://www.iata.org/IATA/2015/EASD/00/IATA_OffersAndOrdersCommonTypes">
<PaymentProcessingDetails>
<Amount CurCode="EUR">189.90</Amount>
<PaymentMethod>
<PaymentCard>
<CardBrandCode>VI</CardBrandCode>
<TokenizedCardID>tok_visa_approve</TokenizedCardID>
</PaymentCard>
</PaymentMethod>
</PaymentProcessingDetails>
</PaymentFunctions>
</Request>

The IATA_OrderViewRS carries the order — Response/Order/OrderID — with its items, tickets (TicketDocInfo) and the payment (PaymentFunctions, at the message root). Other ways to pay: a voucher, your agency's settlement plan, several tenders at once, or none now (pay later) — see Capabilities (PAYVCH, PAYSET, PAYMIX, ORDWPM).

5. Retrieve — OrderRetrieveRQ​

<Request>
<OrderValidationFilterCriteria xmlns="http://www.iata.org/IATA/2015/EASD/00/IATA_OffersAndOrdersCommonTypes">
<OrderFilterCriteria>
<OrderID>ORDER-ID</OrderID>
<OwnerCode>RT</OwnerCode>
</OrderFilterCriteria>
</OrderValidationFilterCriteria>
</Request>

You only ever see your own orders — another seller's order answers order_not_found, exactly like one that does not exist.

6. Cancel — OrderReshopRQ, then OrderChangeRQ​

Changes are quoted before they are made. Ask what cancelling costs and returns:

<Request>
<OrderRefID xmlns="http://www.iata.org/IATA/2015/EASD/00/IATA_OffersAndOrdersCommonTypes">ORDER-ID</OrderRefID>
<UpdateOrder xmlns="http://www.iata.org/IATA/2015/EASD/00/IATA_OffersAndOrdersCommonTypes">
<CancelOrderRef>
<OrderRefID>ORDER-ID</OrderRefID>
</CancelOrderRef>
</UpdateOrder>
</Request>

The IATA_OrderReshopRS prices it — the penalty, the refund and where it goes — as a reshop offer, Response/ReshopResults/ReshopOffers/Offer/OfferID, valid for a few minutes. Accept it to cancel:

<Request>
<ChangeOrderChoice xmlns="http://www.iata.org/IATA/2015/EASD/00/IATA_OffersAndOrdersCommonTypes">
<AcceptCancelledOffer>
<OfferID>RESHOP-OFFER-ID</OfferID>
<OwnerCode>RT</OwnerCode>
</AcceptCancelledOffer>
</ChangeOrderChoice>
<Order xmlns="http://www.iata.org/IATA/2015/EASD/00/IATA_OffersAndOrdersCommonTypes">
<OrderID>ORDER-ID</OrderID>
<OwnerCode>RT</OwnerCode>
</Order>
</Request>

The refund goes back to the tenders that paid, newest first. If the order changed after it was quoted you get stale_version — reshop and accept the new offer. A passenger who has checked in can no longer be cancelled (passenger_checked_in).

Next​

  • Handle every error the sandbox can answer: the Postman Negative tests folder has one request per documented error, each asserting its status and X-NDC-Error code.
  • Get told when the airline changes your order: Notifications.
  • Everything else the API does: Capabilities and the services reference.