Skip to navigation

Flights

Every Flight API call, in the order you make them: the booking flow first, then the calls you make after booking, then the extras.

Booking flow

The 8 calls, in the order you make them.

#CallMethodPathWhat it does
1OriginsPOST/v1/flights/originsList origin airports
2DestinationsPOST/v1/flights/destinationsList destinations for an origin
3Available datesPOST/v1/flights/availabilityList available dates for a route
4SearchPOST/v1/flights/searchSearch flights
5Fare quotePOST/v1/flights/fare-quoteRe-price an offer & get a quote token
6BookPOST/v1/flights/bookPlace a booking
7Get a bookingGET/v1/flights/bookings/{id}Get a booking
8CancelPOST/v1/flights/bookings/{id}/cancelCancel a booking

After booking

Find your bookings, follow one until it settles, and finish a hold, a request booking or a refund. Holds, ticketing and refunds work only with Kitionz Test Air today (see Going Live below).

CallMethodPathWhat it does
List bookingsGET/v1/flights/bookingsList your bookings
Poll statusGET/v1/flights/bookings/{id}/statusPoll a booking’s async status
RefreshPOST/v1/flights/bookings/{id}/refreshRefresh a booking from the supplier
Ticket a holdPOST/v1/flights/bookings/{id}/ticketTicket a HELD booking
Submit PNRPOST/v1/flights/bookings/{id}/fulfilSubmit the PNR for an offline (request) booking
RefundPOST/v1/flights/bookings/{id}/refundRequest a refund

Extras

What a fare allows, where a passenger can sit, and which suppliers your key reaches. Fare rules and seat maps work only with Kitionz Test Air today.

CallMethodPathWhat it does
Fare rulesGET/v1/flights/fare-rulesGet fare rules for an offer
Seat mapGET/v1/flights/seat-mapGet the seat map for an offer
Your suppliersGET/v1/flights/suppliersList the suppliers your searches use

When to take your customer’s money

Take your customer’s payment just before Book (the quote holds about 15 minutes). Then act on the booking’s status:

  • CONFIRMED or HELD → keep the payment.
  • FAILED, or any 4xx from Book → refund it: nothing was booked.
  • RESERVED or PENDING_CONFIRMATION (nextAction.code is WAIT), a 5xx, or no answer → keep it: do not refund and do not book again until the booking reads CONFIRMED or FAILED. Most settle within 10 minutes; still pending after 20 minutes, contact Kitionz support.

Kitionz takes no money for a booking: you pay the seller from your own account with that seller.

Which id to keep

FromKeepFor
SearchofferId (floffer_…)Fare quote and Book, until the offer’s expiresAt (about 15 minutes)
Fare quotequoteTokenBook, until quoteTokenExpiresAt; one booking per quote
You, before Bookyour Idempotency-Keysending Book again safely after a timeout
You, on BookexternalReferenceyour own order number: if you lose Book’s answer, list your bookings with it to find the booking
Bookid (bkg_…)every call after booking — key your orders on it
Bookpnrthe airline’s booking code, for check-in and the airline’s website; it can arrive minutes after Book, and a held booking has one before it is ticketed
BooksupplierReferencethe seller’s own booking number: quote it to the seller’s support

Key your orders on id, never on the PNR. Kitionz does not return e-ticket numbers or the ticket document: get them from the seller named in the booking’s seller.

Times and money

  • Times. A flight’s departureTime and arrivalTime are the airport’s local clock with its UTC offset (2027-01-15T06:00:00+05:30), and each flight’s origin.timezone / destination.timezone name the zone. Show the clock time as written; never convert a flight time to your server’s or your user’s zone. departureDate and returnDate are local dates at the departure airport. Kitionz’s own times (expiresAt, quoteTokenExpiresAt, nextAction.deadlineAt, createdAt) are UTC, ending in Z.
  • Money. Every amount is Indian rupees (currency: INR): a number with up to two decimals, so 4511.86 is ₹4,511.86 — not paise. A gateway that takes paise needs the amount × 100, worked out with exact decimals. Charge from the fare quote’s price.totalAmount; never add up the parts yourself. Offers, fare quotes and bookings carry the same price block.
  • Per-passenger prices. price.passengerFares has one row per passenger type (passengerType, count): total is the price of all passengers of that type together and perPerson is one passenger’s, to the paisa. When every row states a total, the rows add up to totalAmount. Charge totalAmount, never a sum of perPerson.

Passengers

  • Types. ADULT is 12 or older, CHILD 2–11, INFANT under 2, by age on the date of the last flight (the return flight on a round trip). A passenger whose age does not fit the type answers 422 PASSENGER_FIELD_REQUIRED (”… Search again with this passenger as a child.”): search again with that count. Search, quote and book with the same adults, children and infants: another party answers 400 PASSENGER_COUNTS_CHANGED. At most 9 adults and children in one booking.
  • Infants. Each infant sits on an adult’s lap: send guardianPassengerIndex, the position in passengers (0 = the first) of that ADULT. One infant per adult. An infant who turns 2 before the return flight travels as a CHILD.
  • Names. Send firstName and lastName for everyone. A traveller with one name: send it as both.
  • Titles. Mr, Mrs or Ms for adults; Master (boy) or Miss (girl) for children and infants. Kitionz sets gender from the title; with any other title (Dr, Prof), send gender (MALE or FEMALE).
  • Date of birth. A CHILD or INFANT always needs dateOfBirth. A domestic ADULT sent without one is sent to the seller with 1 January of (this year − 20), because some sellers refuse a booking without a date of birth. The booking answers dateOfBirth: null with dateOfBirthDefaulted: true for that passenger, so you never show a date nobody gave.
  • Contact. The seller receives your organisation’s registered email and mobile as the booking contact, not booker. E-tickets, schedule changes and cancellations from the seller or the airline come to you: pass them on to your traveller. booker is your record of who made the booking; Kitionz sends booker.name as the contact name. Phone numbers: an Indian mobile, 10 digits, +91 optional.
  • International trips. Every offer has isInternational (true when a flight crosses a border, or when Kitionz cannot tell) and requiredPassengerFields.fields, each MANDATORY or OPTIONAL. On an international offer every passenger needs dateOfBirth, passportNumber, passportExpiryDate and nationality, and the passport must be valid at least 6 months after the last flight. Send countries as two-letter codes (IN, not Indian). Leave passportIssuingCountry out unless the passport was issued by another country than nationality. Collect all of this before you take payment: a missing field answers 422 PASSENGER_FIELD_REQUIRED, a passport that expires too soon 422 PASSPORT_EXPIRY_TOO_SOON; error.details.invalidFields lists every passenger and field, and nothing is sent to the seller.
  • Test is lenient. Kitionz Test Air accepts any title, phone or country. Live sellers refuse a detail they cannot take with 400 BOOK_PASSENGER_TITLE_UNSUPPORTED, BOOK_CONTACT_PHONE_UNSUPPORTED or BOOK_PASSENGER_COUNTRY_UNSUPPORTED: follow these rules in Test too.

Going Live

  • KYC. Your organisation’s KYC must be approved before Live flight calls work; until then they answer 403 KYC_NOT_APPROVED. Test needs none.
  • IP allow-list. Put your server’s IP address on the Live key’s allow-list (kitionz.com → API → API keys). A call from another address answers 403 IP_NOT_ALLOWED. Test keys have no allow-list.
  • Suppliers. A supplier serves your Live traffic only after you request go-live for it on kitionz.com → Suppliers and Kitionz approves it.
  • Money. Kitionz takes no money for a booking. You pay each seller from your own account with that seller: a low balance answers 402 SUPPLIER_INSUFFICIENT_BALANCE (nothing booked; top up with the seller, then quote and book again). For a request booking you book and pay on the seller’s own site.
  • What only Test does today. Holds, ticketing, cancel, refund, fare rules and seat maps work only with Kitionz Test Air. Cancel a Live booking with the seller named in the booking’s seller: the seller refunds you on their own terms, and the Kitionz booking stays CONFIRMED.
  • After booking. Kitionz does not watch confirmed bookings for airline changes yet, and sends no webhook for them: sellers and airlines send changes to your registered email and mobile. Watch each booked flight with Flight Status (POST /v1/flight-status/monitors) and refresh the booking the day before departure.
  • Values. Live sellers often leave values not stated (null, NOT_GIVEN). Kitionz Test Air is built to look like them, so a screen that shows “Not stated” in Test should hold in Live.

Renamed fields

These pages use only the new names. “The next release” is the next Flight API update that removes the old names. It has no date yet. Move to the new names now: until then both work, and sending an old and a new name with different values is 400 VALIDATION_ERROR.

Requests, renamed on 2026-10-27

Old nameNew nameSent on
supplierOfferRefofferIdFare quote, Book, Fare rules, Seat map
passengers[].travelerTypepassengers[].passengerTypeBook
passengers[].guardianpassengers[].guardianPassengerIndex (was the adult’s name; now the adult’s position in passengers, 0 = the first)Book
bookingMode: "LIVE"bookingMode: "INSTANT"Book
sourcessupplierCodesSearch, Origins, Destinations, Available dates
sourceCodesupplierCode (the filter only; bookings still carry sourceCode)List bookings, Fare rules, Seat map
fromDate / toDatedepartureFrom / departureToList bookings

Not needed: originCode, destCode on Book (Kitionz takes the route from the offer). No longer accepted (400): selectedSeats, selectedSSRs, formOfPayment, privateFareCodes, passengers[].frequentFlyer on Book, and departureDate on Fare rules and Seat map.

Answers, renamed on 2026-10-28

Every answer carries the new name beside the old one, with the same value. The next release removes the old one: read the new names now.

Old nameNew nameIn
supplierOfferRefofferIdSearch offer
pricingprice (one block with every part, the same on the booking)Search offer, Fare quote
pricing.perPax.adult / child / infantprice.passengerFares[] (one row per passengerType, with count, perPerson, total, baseFare, taxes)Search offer, Fare quote
pricing.infantFareprice.infantFareSearch offer, Fare quote
fareBreakdownpriceBooking
fareBreakdown.perPax[].perHeadTotalprice.passengerFares[].perPerson (perPerson is to the paisa; perHeadTotal rounds to whole rupees — switch every read at once)Booking
totalAmount / currencyprice.totalAmount / price.currencyBooking, List bookings
booking.viaSupplierApibooking.requestBooking (true where viaSupplierApi was false; always present, read bookable first)Search offer
suppliersellerBooking (and Search offer, when your organisation sees suppliers before booking)
supplierNameseller.nameList bookings
sourceCodesupplierCodeBooking, List bookings (and Search offer, Fare quote, when your organisation sees suppliers before booking)
returnSupplier(none) (always null; removed)Booking
policy.refundPolicy / policy.changePolicypolicy.refund / policy.changeSearch offer, Booking
originCode / destCodeorigin.iataCode / destination.iataCode (origin and destination are airport objects: iataCode, name, city, countryCode, timezone)legs, flights, Booking, List bookings
originName / destNameorigin.name / destination.namelegs, flights
departureTimezone / arrivalTimezoneorigin.timezone / destination.timezonelegs, flights
originTerminal / destinationTerminaldepartureTerminal / arrivalTerminalflights
marketingCarrier.codemarketingCarrier.iataCodeSearch offer flights
airlineCode / airlineName / flightNumbermarketingCarrier.iataCode / name / flightNumberBooking flights
technicalStops[].airportCode / airportNametechnicalStops[].airport.iataCode / nameflights
cabin (offer, booking, fareFamily) / cabinClass (legs, flights)segments[].cabin (read each flight’s cabin)Search offer, Booking
requiredPassengerFields.internationalisInternationalSearch offer
passengers[].travelerTypepassengers[].passengerTypeBooking
passengers[].guardianpassengers[].guardianPassengerIndex (the adult’s position in passengers, not their name)Booking
airportName / isInternationalname / hasInternationalFlightsairports (Origins, Destinations, airport search)

Not renamed yet (the next release changes these too):

  • Bookings show bookingMode: "LIVE" for a booking made with INSTANT, and the fare quote’s eligibility.bookingModesSupported says LIVE for what /book calls INSTANT.
  • Baggage rows use paxType ADT, CHD, INF for ADULT, CHILD, INFANT.
  • Search data.meta supplier lists (suppliersFailed, …) and GET /v1/flights/suppliers rows still name the supplier sourceCode.
  • Webhook booking events (flight_booking.confirmed, flight_booking.rejected) still name the seller supplier and returnSupplier.

Try the calls on these pages

Each call has a Try it button. Choose the Test address and enter your Test key as keyId:secret. Never enter a Live key on a website.

Use Postman

Prefer Postman? Download the collection and the Test environment, import both (File → Import), fill in keyId and secret, and send the calls in order. The collection holds the booking flow; each call stores what the next one needs.

Every example answer here was recorded from the real API on 2026-10-28, in Test, against Kitionz Test Air. Live answers have the same shape: Test Air is built to look like a Live seller.