Skip to navigation

4 · Search

Search flights.

What: find bookable offers for a route, date(s) and passenger mix across every supplier you have enabled.

When: the start of every booking — or on its own to display fares.

Before / After: optionally call /origins + /destinations to build the form → here → pick one offer’s supplierOfferRef → /fare-quote.

Gotchas

  • tripType is optional. Leave it out and you get every trip kind leaving on departureDate: one-way fares AND round-trip offers. ROUND_TRIP gives round trips only.
  • ONE_WAY can also return round trips. Some suppliers answer a one-way search with round-trip packages too. Kitionz returns them: each says tripType: "ROUND_TRIP" and has its returnDate. Read tripType on every offer and show it as what it is; never assume an offer is the kind you searched. To get every package, send ROUND_TRIP or leave tripType out: a supplier that keeps one route list per trip kind is asked in a one-way search only where its one-way list has the route and date.
  • returnDate is the day your traveller flies back. With it, every round-trip offer has that returnDate: the local date its return leg leaves. Round-trip offers that return on other days are not in offers: meta.otherReturnDates counts them per day. Search again with that returnDate to see them. otherReturnDates counts only the round trips suppliers already sent; it is not a calendar of every return day. Without a returnDate, you get the round trips leaving on departureDate, each with its own returnDate.
  • A returnDate with no tripType is a return journey: one-way offers and the round trips back on returnDate. Read each one-way offer’s route (legs[0].originCode → destCode); never assume it flies your way out. Today they all do; one-way offers flying back will come in this same answer later. A returnDate is refused (400) with tripType: "ONE_WAY", and with slices (the date of your second slice is your return date).
  • Each offer says which trip it is: tripType (ONE_WAY | ROUND_TRIP), departureDate, and — for a round trip — returnDate, fixed by the fare. A round trip’s price covers both ways: label it so in your screen. Send departureDate back unchanged on /fare-quote and /book. Book each offer by its own labels: send the offer’s tripType and returnDate, never the search’s. They may be left out there (the offer’s own are used); when sent they must be the offer’s (a different trip → 400 OFFER_TRIP_MISMATCH).
  • A round trip is ONE offer with legs: [OUTBOUND, RETURN], one totalAmount, one supplierOfferRef: one fare for both ways, booked with one /fare-quote and one /book. It can be a series package (seats bought in advance and sold as a pair) or a return fare. Never staple two one-ways together.
  • Today round trips come only from suppliers whose catalogue offers them. With tripType: "ROUND_TRIP", every other supplier is listed in meta.suppliersExcluded with reason ROUND_TRIP_NOT_OFFERED (left out, not a failure).
  • Some suppliers need your return date to find round trips. With a returnDate, Kitionz asks them for that day only, never for other days, so their other return days are not in otherReturnDates. When Kitionz already holds such a supplier’s list of return days and your day is not on it, the supplier is not asked and is listed in meta.suppliersExcluded with reason RETURN_DATE_NOT_LISTED (left out, not a failure).
  • A supplier whose fares are all of a category your filters.inventoryCategories (or your connection) leaves out — e.g. a series-only supplier when you ask for ONLINE — is not asked at all: it is listed in meta.suppliersExcluded with reason INVENTORY_NOT_REQUESTED (left out, not a failure).
  • A supplier that publishes a date list is asked on every date its list shows. When its current list leaves the date out, it is not asked and is listed in meta.suppliersExcluded with reason DATE_NOT_LISTED (left out, not a failure). A supplier with no date list is asked on every one-way search (a round trip goes only to suppliers whose catalogue offers round trips, see above).
  • Some suppliers return their round-trip packages together with their one-way fares, from one date list for both. Their listed dates count for both trip kinds: a tripType: "ROUND_TRIP" search asks them on any listed date, and a search with no tripType asks them once and returns both kinds.
  • With slices the slices decide the kind (one slice = one-way, two = round trip); send tripType only if it agrees. Never send returnDate with slices: the date of your second slice is your return date, and meta.otherReturnDates is filled for it too.
  • meta.tripTypes lists the kinds this search covered; each meta.suppliers, meta.suppliersFailed and meta.suppliersExcluded entry carries the tripType of its part (one supplier can appear once per kind) — so the same supplier can be in suppliersSucceeded (one kind answered) and in suppliersFailed (the other failed). supplierCounts, when present, counts distinct suppliers in each list. A DEADLINE_EXCEEDED entry with tookMs: 0 means the search ran out of time before that part asked the supplier.
  • Search prices are indicative — never charge off them; re-price at /fare-quote.
  • Pax fields are adults / children / infants (same names across the whole flow).
  • With infants, read pricing.infantFare.status. PRICED: the supplier’s infant price is in pricing.perPax.infant and inside totalAmount. NOT_GIVEN: the supplier gave no infant price, so perPax.infant is absent and totalAmount covers adults and children only. Add your own infant charge (the supplier or airline may still charge for the infant), or hide such fares — your choice. Kitionz never hides a fare and never shows ₹0 for a missing infant price. Treat any other status as NOT_GIVEN, and add your infant charge before you sort by price.
  • sources is optional — leave it out. Kitionz already knows which suppliers your key is enabled for and searches all of them. Send sources only to narrow to a subset of THOSE (blanks ignored; a non-enabled code → 403). Don’t send the empty [""] from the example skeleton.
  • Each offer carries capabilities { seatSelection, meals, extraBaggage, hold, fareRules, cancellation: REALTIME|OFFLINE|NONE } — render your seat/meal/hold/cancel buttons off it. It’s a supplier-level hint; the exact per-offer answer comes at /fare-quote (eligibility), and /book//seat-map reject an unsupported action with a typed 422 (e.g. CAPABILITY_NOT_SUPPORTED) — so a wrong button can’t cause a bad booking.
  • Each offer carries booking — read bookable FIRST. bookable: false → show the fare, don’t offer to book it (viaSupplierApi is then absent, not false). bookable: true + viaSupplierApi: true → /book books with the supplier; the booking’s status tells you whether the PNR came back on that call or follows. bookable: true + viaSupplierApi: false → /book records a request (PENDING_FULFILMENT); book on the supplier’s portal, then /bookings/:id/fulfil. In code: if (!booking.bookable) … else if (booking.viaSupplierApi) … else … — never test !booking.viaSupplierApi alone.
  • The same flights often come back from several sellers — Kitionz returns every offer and never removes a copy. Group them by journeyKey: equal keys mean the sellers state the same flights at the same start and end times (same airline and flight number, same airports including stops, each leg leaving and arriving at the same local time). Price, seats, baggage and rules differ per offer: never add seats across a group, and book one specific offer with its own supplierOfferRef. Each leg has a legKey (same rule, one direction) — equal leg keys never let you split a package or join two one-ways. When journeyKeyComparable is false (reasons in legs[].legKeyGaps) the key is unique to that offer: show it on its own. The key changes when an airline retimes a flight or Kitionz learns a fact a seller left out. The recipe (version jk1) is published so you can key your own inventory the same way.

Example — request (only origin / destination / departureDate / adults are required):

{ "origin": "DEL", "destination": "BOM", "departureDate": "2027-01-15", "adults": 1 }

Response (trimmed) — take each offer’s supplierOfferRef into /fare-quote:

{
"data": {
"searchId": "srch_x6xpERXqk",
"offers": [ {
"supplierOfferRef": "floffer_9x2k7q",
"tripType": "ONE_WAY",
"departureDate": "2027-01-15",
"journeyKey": "jk1_59da15eff41394c5648af3caaab489ca",
"journeyKeyComparable": true,
"pricing": { "totalAmount": 5480.00, "currency": "INR" },
"legs": [ {
"legType": "OUTBOUND",
"departureTime": "2027-01-15T06:00:00+05:30", "arrivalTime": "2027-01-15T08:10:00+05:30",
"segments": [ { "marketingCarrier": { "code": "6E", "flightNumber": "2134" }, "originCode": "DEL", "destCode": "BOM" } ],
"legKey": "lk1_59da15eff41394c5648af3caaab489ca", "legKeyComparable": true, "legKeyGaps": []
} ],
"capabilities": { "seatSelection": false, "hold": false, "cancellation": "OFFLINE" },
"booking": { "bookable": true, "viaSupplierApi": true, "validatingCarrier": "6E" }
}, {
"supplierOfferRef": "floffer_4h8n2r",
"tripType": "ROUND_TRIP",
"departureDate": "2027-01-15",
"returnDate": "2027-01-19",
"pricing": { "totalAmount": 9940.00, "currency": "INR" },
"legs": [ { "legType": "OUTBOUND" }, { "legType": "RETURN" } ],
"booking": { "bookable": true, "viaSupplierApi": true, "validatingCarrier": "6E" }
} ],
"meta": { "tripTypes": ["ONE_WAY", "ROUND_TRIP"], "suppliersFailed": [], "otherReturnDates": [] }
}
}

Example — a return journey (one-way offers and round trips back on 19 Jan):

{ "origin": "DEL", "destination": "BOM", "departureDate": "2027-01-15", "returnDate": "2027-01-19", "adults": 1 }

Response (trimmed) — one round-trip offer comes back on 19 Jan; two others come back on 20 Jan and are only counted:

{ "data": { "offers": [ { "tripType": "ONE_WAY", "departureDate": "2027-01-15" }, { "tripType": "ROUND_TRIP", "departureDate": "2027-01-15", "returnDate": "2027-01-19" } ], "meta": { "tripTypes": ["ONE_WAY", "ROUND_TRIP"], "otherReturnDates": [ { "returnDate": "2027-01-20", "offerCount": 2 } ] } } }

Authentication

AuthorizationBearer

Your Kitionz API key, sent as Authorization: Bearer keyId:secret. Create it in your Kitionz console under API → API keys.

Request

This endpoint expects an object.
originstringRequiredformat: "^[A-Za-z0-9]+$"2-10 characters
destinationstringRequiredformat: "^[A-Za-z0-9]+$"2-10 characters
departureDatestringRequired
returnDatestringOptional

The day your traveller flies back. Every round-trip offer in the answer has this returnDate (the local date its return leg leaves). Round-trip offers that return on other days are counted in meta.otherReturnDates. With tripType left out you get one-way offers and round trips back on this day: read each one-way offer’s route, never assume it flies out. Not allowed with tripType ONE_WAY, nor with slices (the date of your second slice is your return date).

tripTypeenumOptional

Optional. Left out: every trip kind — one-way fares and round trips. ROUND_TRIP: round trips only. ONE_WAY: one-way fares, plus any round-trip packages a supplier’s one-way answer carries; each says tripType ROUND_TRIP with its returnDate. Read tripType on every offer and book it by its own labels: send fare-quote and book the offer’s tripType, never the search’s. To get every package, send ROUND_TRIP or leave tripType out.

Allowed values:
adultsintegerOptional1-9Defaults to 1
childrenintegerOptional0-9Defaults to 0
infantsintegerOptional0-9Defaults to 0
cabinenumOptional
Allowed values:
sourceslist of stringsOptional

Optional. Leave it out to use every supplier your account has switched on. Send a list of sourceCodes only to narrow this call to some of them; a code you cannot use is refused (403), and blank entries are ignored.

sliceslist of objectsOptional
filtersobjectOptional

Response

Default Response
successboolean
statusCodedouble
dataobject

Flight-search result envelope: searchId + offers + per-supplier meta (partial supplier failures are surfaced in meta.suppliersFailed, never as a top-level error).

metaobject