---
title: "Get live flight pricing — search by route, or re-price a known offer"
method: POST
path: "/v1/flight_search"
tags: ["Pricing & booking"]
---

# Get live flight pricing — search by route, or re-price a known offer

`POST /v1/flight_search`

## Request

- Base URL: `https://api.gojinko.com`
- URL: `https://api.gojinko.com/v1/flight_search`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

Two modes: **search** — provide `origin` + `destination` + `departure_date` to price a route; or **price-check** — provide only `offer_token` to re-price a specific offer from a discovery endpoint. Exactly one mode per request.

## Request body

- FlightSearchRequest
  - `origin` string: 3-letter IATA city or airport code. See `origin_type` for how an untyped code is read. `origin` and `destination` must differ. A 3-letter code the platform’s location catalog does not recognise is not refused: it is searched as an airport, and if no provider sells it the search answers `result: no_matches`.
  - `destination` string: 3-letter IATA city or airport code. See `destination_type` for how an untyped code is read: LAX alone is the Los Angeles CITY; send `destination_type: "airport"` for the airport only. `origin` and `destination` must differ. A 3-letter code the platform’s location catalog does not recognise is not refused: it is searched as an airport, and if no provider sells it the search answers `result: no_matches`.
  - `origin_type` 'city' | 'airport': How to read the code: `city` searches every airport of the city, `airport` only that one airport. Omit it and the platform applies one rule: a code that names a multi-airport city is searched as the city; every other code is searched as the airport. Untyped NYC, LON or PAR is the city; untyped JFK, LHR or CDG is the airport; and untyped LAX, MIA or LAS — codes a city shares with its main airport — is the CITY, so results can land at any airport of that city. If the user named the airport, send `airport`; if they named the city, omit the field. The provider decides which airports a city holds, so a city search can return airports the catalog does not list under that code: searched as a city, LAX returns Ontario (ONT) fares, often as the cheapest offers. Each offer’s legs carry the airports flown; the offer-level `origin` / `destination` carry the city.
  - `destination_type` 'city' | 'airport': How to read the code: `city` searches every airport of the city, `airport` only that one airport. Omit it and the platform applies one rule: a code that names a multi-airport city is searched as the city; every other code is searched as the airport. Untyped NYC, LON or PAR is the city; untyped JFK, LHR or CDG is the airport; and untyped LAX, MIA or LAS — codes a city shares with its main airport — is the CITY, so results can land at any airport of that city. If the user named the airport, send `airport`; if they named the city, omit the field. The provider decides which airports a city holds, so a city search can return airports the catalog does not list under that code: searched as a city, LAX returns Ontario (ONT) fares, often as the cheapest offers. Each offer’s legs carry the airports flown; the offer-level `origin` / `destination` carry the city.
  - `departure_date` string: Departure date, `YYYY-MM-DD`: the local date at `origin`. Required in search mode, with `origin` and `destination`; not allowed beside `offer_token`. A date that does not exist on the calendar (`2026-02-30`) is refused with 422 naming the field.
  - `return_date` string: Return date, `YYYY-MM-DD`, on or after `departure_date` (a same-day return is valid). Sending it makes the search a round trip; see `trip_type`.
  - `trip_type` 'oneway' | 'roundtrip': `oneway` or `roundtrip`. Omit it and `return_date` decides: present is a round trip, absent a one-way trip. `roundtrip` requires `return_date`, and `oneway` refuses it (422 naming `return_date`).
  - `cabin_class` 'economy' | 'premium_economy' | 'business' | 'first', nullable: Omit this field or send `null` to let the provider default the search to economy without applying a cabin filter. Send an explicit enum value to require each fare’s representative cabin to equal it. The representative cabin is the cabin on the longest flight segment; shorter connecting segments may use another cabin. An omitted or `null` cabin applies no cabin filter.
  - `direct_only` boolean: DEPRECATED — send `max_stops: 0` instead. Still accepted: `direct_only` is folded into `max_stops` (`true` becomes `max_stops: 0`) before the search runs, so only `max_stops` reaches the platform. Setting it beside a non-zero `max_stops` is rejected.
  - `max_stops` integer: Maximum stops per leg: `0` non-stop (the way to ask for direct flights), `1` one connection, `2` two. Applies to every leg of the trip.
  - `multi_fare` boolean: Branded fare ladder: several fares per itinerary (upsell options). Defaults to `true` when omitted; send `false` for a single fare per itinerary and a smaller response. An offer carries at most 10 fares, the cheapest fare of each cabin kept first; a provider that sells no fare ladder returns a single fare either way.
  - `max_total` number: Drop fares whose total price (all passengers) exceeds this cap, in `currency`, major units. A fare priced in another currency is usually converted to `currency` with the platform’s FX rate before the comparison, but not always: a provider whose first priced offer is already in `currency` drops its offers in other currencies as unverifiable instead of converting them. A fare whose currency cannot be converted is not returned.
  - `include_carriers` string[]: Keep only itineraries marketed by these IATA carriers. Matching means every segment is marketed by a listed carrier (codeshares count by marketing carrier). When nothing matches, the search returns no offers with `result: no_matches`; the platform never widens to other carriers.
  - `exclude_carriers` string[]: Drop itineraries marketed by these IATA carriers. Must not overlap `include_carriers`.
  - `departure_time_range` object: Filter the OUTBOUND leg by local departure time-of-day.
    - `earliest` string
    - `latest` string
  - `arrival_time_range` object: Filter the OUTBOUND leg by local arrival time-of-day.
    - `earliest` string
    - `latest` string
  - `return_departure_time_range` object: Filter the RETURN leg by local departure time-of-day (round-trip only).
    - `earliest` string
    - `latest` string
  - `return_arrival_time_range` object: Filter the RETURN leg by local arrival time-of-day (round-trip only).
    - `earliest` string
    - `latest` string
  - `connection_time_min_minutes` integer: Shortest acceptable layover, in minutes, applied to every connection of every leg. Must not exceed `connection_time_max_minutes`. Conservative, like `refundable_only`: an itinerary with a connection whose times are unknown cannot be checked and is dropped.
  - `connection_time_max_minutes` integer: Longest acceptable layover, in minutes, applied to every connection of every leg. Conservative in the same way as `connection_time_min_minutes`: a connection whose times are unknown drops the itinerary.
  - `max_total_duration_minutes` integer: Cap each leg’s door-to-door elapsed travel time, in minutes.
  - `refundable_only` boolean: Keep only fares that can be cancelled before departure (with or without a fee). Conservative: a fare whose rules the platform cannot verify is DROPPED, so carriers that publish no rule data disappear under this filter. The filter reads the before-departure cancellation rules only; `is_refundable` on a returned fare is a wider reading of the same rules (it is `true` on a fare whose only decided rule allows cancellation after departure), so the flag is not this filter.
  - `changeable_only` boolean: Keep only fares that allow a voluntary change. Conservative in the same way as `refundable_only`: unverifiable fares are dropped. The filter reads the before-departure change rules only; `is_changeable` on a returned fare is the wider reading `refundable_only` describes.
  - `checked_bag_included` boolean: Keep only fares whose price already includes a checked bag on EVERY segment. Conservative, like `refundable_only`: a segment that states no allowance makes the fare unverifiable and it is dropped. The response flag of the same name is read from the first segment that states an allowance, not from every segment, so without this filter a fare flagged `checked_bag_included: true` can still lack a free bag on a later segment.
  - `single_carrier_only` boolean: Keep only itineraries marketed end-to-end by one carrier.
  - `via_airports` string[]: Restrict connections to these airports: an itinerary qualifies only when EVERY connection is one of them. Non-stop itineraries have no connection to check and are kept. Some providers are asked for at most the first 9 listed airports per leg; the whole list is still applied to what they return.
  - `exclude_via_airports` string[]: Ban connections at these airports. Must not overlap `via_airports`.
  - `aircraft_types` string[]: Keep only itineraries whose every segment flies one of these IATA equipment codes. Conservative, like `refundable_only`: a segment whose equipment is unknown makes the itinerary unverifiable and it is dropped, so a provider that reports no equipment (see `aircraft` on the segment) disappears under this filter entirely.
  - `origin_alternate_airports` string[]: ADDITIONAL departure airports searched alongside `origin`. Widening only — the anchor in `origin` is always searched, so this can add results but never remove any. THE ANCHOR DECIDES RANKING AND TRUNCATION, which makes the two airports NOT interchangeable: measured on one route, anchor `JFK` with alternate `EWR` returned 15 JFK / 35 EWR, while anchor `EWR` with alternate `JFK` returned 2 JFK / 48 EWR — 13 itineraries differed between the two. Put the airport that matters most in `origin`. Works with an airport or a city anchor: `origin` NYC with `["BOS"]` searches New York's airports and Boston; an alternate inside the city is redundant and harmless. On a round trip the platform mirrors the list onto the return leg, so it also covers where the return lands. Some providers search only the anchor.
  - `destination_alternate_airports` string[]: ADDITIONAL arrival airports searched alongside `destination`. Widening only — the anchor in `destination` is always searched, so this can add results but never remove any. THE ANCHOR DECIDES RANKING AND TRUNCATION, which makes the two airports NOT interchangeable the same way `origin_alternate_airports` describes: put the airport that matters most in `destination`. Works with an airport or a city anchor, as `origin_alternate_airports` describes. On a round trip the platform mirrors the list onto the return leg, so it also covers where the return departs from. Some providers search only the anchor.
  - `nearby_airports` boolean: Also search the alternate airports around each leg’s origin and destination. Widening: more results, not fewer.
  - `same_connection_airport_only` boolean: Keep only itineraries whose connections leave from the same airport they arrived at (no cross-town transfer).
  - `same_origin_airport_only` boolean: Keep only round trips that return to the airport the trip departed from. Round trip only: on a one-way search it is accepted and has no effect.
  - `same_turnaround_airport_only` boolean: Keep only round trips whose return departs from the airport the outbound arrived at. Round trip only: on a one-way search it is accepted and has no effect.
  - `limit` integer: TOTAL number of flights to return (1–300), not a per-page size: `limit: 5` returns at most five flights. Search mode only. Omit to let the platform choose: the cheapest flight plus up to 100 alternatives, so up to 101 flights. Applied after the cross-provider merge and sort, so it only trims the returned set — the providers still bound the real count.
  - `adults` integer: Adult travelers (12+). At most 9 travellers who need a seat: `adults + children` ≤ 9. Lap infants are not counted.
  - `children` integer: Child travelers (2–11). At most 9 travellers who need a seat: `adults + children` ≤ 9. Lap infants are not counted.
  - `infants` integer: Infant travelers (under 2), traveling on an adult’s lap. Seated infants (own seat) are not supported.
  - `currency` string: ISO 4217 currency code, case-insensitive (`eur` is `EUR`): prices come back with the upper-case code and a `display`. Defaults to USD. A currency the platform cannot price in is refused with 400.
  - `locale` string
  - `offer_token` string: Price-check mode: re-price one known offer instead of searching a route. Route and filter fields are not allowed beside it (422); the passenger counts and `currency` are. Two kinds of token behave differently. A cached-itinerary `offer_token` from `flight_calendar`, `find_dates`, `lowest_fare`, `find_destination` or a price monitor is re-shopped LIVE on its route and dates with no cabin, stop or carrier constraint: `offers[0]` is the cheapest live offer with the same flights and cabin when one exists, `exact_match_found` says whether it did, and up to 100 alternatives follow. An `offer_id` from an earlier `flight_search` is answered from the cache of that search without re-pricing (`exact_match_found: true`), unless the passenger counts or `currency` differ, in which case it is re-shopped; once every fare of the cached offer has passed its `expires_at` it answers `410 OFFER_EXPIRED`: search again.
  - `intent` IntentInput
    - `user_intent` string, nullable: The user's natural-language intent: the Alpic PII-stripped paraphrase when available, else a best-effort fallback to the client-provided NL query.

## Response `200`

Priced offers. Every filter that narrows the results (cabin, stops, price, carriers, times, connections, fare conditions, aircraft) is applied exactly as sent: no returned offer breaks one. Options that widen a search (alternate or nearby airports) are searched where available. A search that completes and matches nothing is also a 200: `offers` is empty, `result` is `no_matches` and the body carries a recovery `instruction`. A search that could not be completed answers an error (`UPSTREAM_REJECTED`, `UPSTREAM_ERROR`, `UPSTREAM_UNAVAILABLE` or `UPSTREAM_TIMEOUT`) rather than an empty list. Offers that were found are returned even when part of the search could not be completed.

- FlightSearchResponse
  - `offers` FlightOffer[], required
    - `offer_id` string, required: Identifier of this offer: `offer__` followed by 8 hex characters. Send it as `offer_token` to re-price the offer; it is also the prefix of each fare’s `trip_item_token`.
    - `origin` object, required
      - `code` string: City code of the requested origin: the code sent as `origin` when it was typed `city`, otherwise the city of that airport (`NYC` for JFK). Not the airport flown; read `outbound.origin` for that. An empty string when the platform cannot map the requested code to a city.
      - `name` string
    - `destination` object, required
      - `code` string: City code of the requested destination, resolved as `origin.code` is. Not the airport flown; read `outbound.destination` for that. An empty string when the platform cannot map the requested code to a city.
      - `name` string
    - `is_round_trip` boolean
    - `total_duration_minutes` number
    - `outbound` FlightLeg
      - `origin` string
      - `destination` string
      - `departure_datetime` string: Local time at the airport, RFC 3339 with that airport’s UTC offset (e.g. `2026-09-23T11:55:00-04:00`). Parse it as an instant; do not assume UTC and do not compare two of these as strings. The offset is a property of this leg/segment shape wherever it appears — a flight search, and an itinerary echoed back on a quote or trip read — not of the search response alone. On the rare airport whose timezone the platform does not know, the offset is omitted and the value is local wall-clock time. The `*_local` fields of a booked or exchanged itinerary are NOT this: those carry wall-clock time with no offset, by design.
      - `arrival_datetime` string: Local time at the airport, RFC 3339 with that airport’s UTC offset (e.g. `2026-09-23T11:55:00-04:00`). Parse it as an instant; do not assume UTC and do not compare two of these as strings. The offset is a property of this leg/segment shape wherever it appears — a flight search, and an itinerary echoed back on a quote or trip read — not of the search response alone. On the rare airport whose timezone the platform does not know, the offset is omitted and the value is local wall-clock time. The `*_local` fields of a booked or exchanged itinerary are NOT this: those carry wall-clock time with no offset, by design.
      - `duration_minutes` number
      - `airline` string
      - `airline_name` string
      - `stops` number
      - `stop_infos` StopInfo[]: Layover detail, one entry per stop, in travel order. Absent when the leg is non-stop (`stops: 0`) or when upstream detail is incomplete for any stop; `stops` still reports the connection count in that case.
        - `airport_code` string: IATA code of the airport where the leg stops.
        - `duration_minutes` number: Layover length in minutes (arrival of the inbound segment to departure of the next). Omitted when the upstream times cannot be resolved.
      - `segments` Segment[]: The flown segments of this leg, in travel order — one per aircraft. A non-stop leg has one. Read `operating_carrier` here to disclose codeshares. Absent when the provider returned no segment breakdown, in which case `stops` and `stop_infos` are all that is known about the leg.
        - `airline` string: IATA code of the MARKETING carrier — whose flight number you booked.
        - `airline_name` string
        - `flight_number` string: Marketing flight number as the provider sends it on a live offer: a bare number such as `460`, without the carrier code, which `airline` carries.
        - `aircraft` string: IATA aircraft type code for the equipment scheduled on this segment. Absent when the provider reports no equipment; some providers never do, so their itineraries carry no `aircraft` at all (and are dropped by the `aircraft_types` filter).
        - `departure_airport` string
        - `departure_city` string: IATA city code of the departure airport (`NYC` for JFK), from the platform’s airport catalog: a code, not a name. Absent when the airport is not in the catalog.
        - `departure_time` string: Local time at the airport, RFC 3339 with that airport’s UTC offset (e.g. `2026-09-23T11:55:00-04:00`). Parse it as an instant; do not assume UTC and do not compare two of these as strings. The offset is a property of this leg/segment shape wherever it appears — a flight search, and an itinerary echoed back on a quote or trip read — not of the search response alone. On the rare airport whose timezone the platform does not know, the offset is omitted and the value is local wall-clock time. The `*_local` fields of a booked or exchanged itinerary are NOT this: those carry wall-clock time with no offset, by design.
        - `arrival_airport` string
        - `arrival_city` string: IATA city code of the arrival airport (`CHI` for ORD), from the platform’s airport catalog: a code, not a name. Absent when the airport is not in the catalog.
        - `arrival_time` string: Local time at the airport, RFC 3339 with that airport’s UTC offset (e.g. `2026-09-23T11:55:00-04:00`). Parse it as an instant; do not assume UTC and do not compare two of these as strings. The offset is a property of this leg/segment shape wherever it appears — a flight search, and an itinerary echoed back on a quote or trip read — not of the search response alone. On the rare airport whose timezone the platform does not know, the offset is omitted and the value is local wall-clock time. The `*_local` fields of a booked or exchanged itinerary are NOT this: those carry wall-clock time with no offset, by design.
        - `duration_minutes` number
        - `layover_minutes` number: Wait between this segment’s arrival and the next departure. Absent on the last segment of a leg, and whenever the upstream times could not be resolved.
        - `operating_carrier` string: IATA code of the carrier that actually OPERATES the segment. A value differing from `airline` is a codeshare the passenger must be told about. Whether equality is stated depends on the provider: some always send it, including when it equals `airline`; others send it only when they disclose an operating carrier, so an absent value says nothing about who operates the flight.
    - `inbound` FlightLeg
      - `origin` string
      - `destination` string
      - `departure_datetime` string: Local time at the airport, RFC 3339 with that airport’s UTC offset (e.g. `2026-09-23T11:55:00-04:00`). Parse it as an instant; do not assume UTC and do not compare two of these as strings. The offset is a property of this leg/segment shape wherever it appears — a flight search, and an itinerary echoed back on a quote or trip read — not of the search response alone. On the rare airport whose timezone the platform does not know, the offset is omitted and the value is local wall-clock time. The `*_local` fields of a booked or exchanged itinerary are NOT this: those carry wall-clock time with no offset, by design.
      - `arrival_datetime` string: Local time at the airport, RFC 3339 with that airport’s UTC offset (e.g. `2026-09-23T11:55:00-04:00`). Parse it as an instant; do not assume UTC and do not compare two of these as strings. The offset is a property of this leg/segment shape wherever it appears — a flight search, and an itinerary echoed back on a quote or trip read — not of the search response alone. On the rare airport whose timezone the platform does not know, the offset is omitted and the value is local wall-clock time. The `*_local` fields of a booked or exchanged itinerary are NOT this: those carry wall-clock time with no offset, by design.
      - `duration_minutes` number
      - `airline` string
      - `airline_name` string
      - `stops` number
      - `stop_infos` StopInfo[]: Layover detail, one entry per stop, in travel order. Absent when the leg is non-stop (`stops: 0`) or when upstream detail is incomplete for any stop; `stops` still reports the connection count in that case.
        - `airport_code` string: IATA code of the airport where the leg stops.
        - `duration_minutes` number: Layover length in minutes (arrival of the inbound segment to departure of the next). Omitted when the upstream times cannot be resolved.
      - `segments` Segment[]: The flown segments of this leg, in travel order — one per aircraft. A non-stop leg has one. Read `operating_carrier` here to disclose codeshares. Absent when the provider returned no segment breakdown, in which case `stops` and `stop_infos` are all that is known about the leg.
        - `airline` string: IATA code of the MARKETING carrier — whose flight number you booked.
        - `airline_name` string
        - `flight_number` string: Marketing flight number as the provider sends it on a live offer: a bare number such as `460`, without the carrier code, which `airline` carries.
        - `aircraft` string: IATA aircraft type code for the equipment scheduled on this segment. Absent when the provider reports no equipment; some providers never do, so their itineraries carry no `aircraft` at all (and are dropped by the `aircraft_types` filter).
        - `departure_airport` string
        - `departure_city` string: IATA city code of the departure airport (`NYC` for JFK), from the platform’s airport catalog: a code, not a name. Absent when the airport is not in the catalog.
        - `departure_time` string: Local time at the airport, RFC 3339 with that airport’s UTC offset (e.g. `2026-09-23T11:55:00-04:00`). Parse it as an instant; do not assume UTC and do not compare two of these as strings. The offset is a property of this leg/segment shape wherever it appears — a flight search, and an itinerary echoed back on a quote or trip read — not of the search response alone. On the rare airport whose timezone the platform does not know, the offset is omitted and the value is local wall-clock time. The `*_local` fields of a booked or exchanged itinerary are NOT this: those carry wall-clock time with no offset, by design.
        - `arrival_airport` string
        - `arrival_city` string: IATA city code of the arrival airport (`CHI` for ORD), from the platform’s airport catalog: a code, not a name. Absent when the airport is not in the catalog.
        - `arrival_time` string: Local time at the airport, RFC 3339 with that airport’s UTC offset (e.g. `2026-09-23T11:55:00-04:00`). Parse it as an instant; do not assume UTC and do not compare two of these as strings. The offset is a property of this leg/segment shape wherever it appears — a flight search, and an itinerary echoed back on a quote or trip read — not of the search response alone. On the rare airport whose timezone the platform does not know, the offset is omitted and the value is local wall-clock time. The `*_local` fields of a booked or exchanged itinerary are NOT this: those carry wall-clock time with no offset, by design.
        - `duration_minutes` number
        - `layover_minutes` number: Wait between this segment’s arrival and the next departure. Absent on the last segment of a leg, and whenever the upstream times could not be resolved.
        - `operating_carrier` string: IATA code of the carrier that actually OPERATES the segment. A value differing from `airline` is a codeshare the passenger must be told about. Whether equality is stated depends on the provider: some always send it, including when it equals `airline`; others send it only when they disclose an operating carrier, so an absent value says nothing about who operates the flight.
    - `additional_legs` FlightLeg[], required: Third and later legs of a multi-city itinerary, in travel order. Empty for one-way and round-trip offers.
      - `origin` string
      - `destination` string
      - `departure_datetime` string: Local time at the airport, RFC 3339 with that airport’s UTC offset (e.g. `2026-09-23T11:55:00-04:00`). Parse it as an instant; do not assume UTC and do not compare two of these as strings. The offset is a property of this leg/segment shape wherever it appears — a flight search, and an itinerary echoed back on a quote or trip read — not of the search response alone. On the rare airport whose timezone the platform does not know, the offset is omitted and the value is local wall-clock time. The `*_local` fields of a booked or exchanged itinerary are NOT this: those carry wall-clock time with no offset, by design.
      - `arrival_datetime` string: Local time at the airport, RFC 3339 with that airport’s UTC offset (e.g. `2026-09-23T11:55:00-04:00`). Parse it as an instant; do not assume UTC and do not compare two of these as strings. The offset is a property of this leg/segment shape wherever it appears — a flight search, and an itinerary echoed back on a quote or trip read — not of the search response alone. On the rare airport whose timezone the platform does not know, the offset is omitted and the value is local wall-clock time. The `*_local` fields of a booked or exchanged itinerary are NOT this: those carry wall-clock time with no offset, by design.
      - `duration_minutes` number
      - `airline` string
      - `airline_name` string
      - `stops` number
      - `stop_infos` StopInfo[]: Layover detail, one entry per stop, in travel order. Absent when the leg is non-stop (`stops: 0`) or when upstream detail is incomplete for any stop; `stops` still reports the connection count in that case.
        - `airport_code` string: IATA code of the airport where the leg stops.
        - `duration_minutes` number: Layover length in minutes (arrival of the inbound segment to departure of the next). Omitted when the upstream times cannot be resolved.
      - `segments` Segment[]: The flown segments of this leg, in travel order — one per aircraft. A non-stop leg has one. Read `operating_carrier` here to disclose codeshares. Absent when the provider returned no segment breakdown, in which case `stops` and `stop_infos` are all that is known about the leg.
        - `airline` string: IATA code of the MARKETING carrier — whose flight number you booked.
        - `airline_name` string
        - `flight_number` string: Marketing flight number as the provider sends it on a live offer: a bare number such as `460`, without the carrier code, which `airline` carries.
        - `aircraft` string: IATA aircraft type code for the equipment scheduled on this segment. Absent when the provider reports no equipment; some providers never do, so their itineraries carry no `aircraft` at all (and are dropped by the `aircraft_types` filter).
        - `departure_airport` string
        - `departure_city` string: IATA city code of the departure airport (`NYC` for JFK), from the platform’s airport catalog: a code, not a name. Absent when the airport is not in the catalog.
        - `departure_time` string: Local time at the airport, RFC 3339 with that airport’s UTC offset (e.g. `2026-09-23T11:55:00-04:00`). Parse it as an instant; do not assume UTC and do not compare two of these as strings. The offset is a property of this leg/segment shape wherever it appears — a flight search, and an itinerary echoed back on a quote or trip read — not of the search response alone. On the rare airport whose timezone the platform does not know, the offset is omitted and the value is local wall-clock time. The `*_local` fields of a booked or exchanged itinerary are NOT this: those carry wall-clock time with no offset, by design.
        - `arrival_airport` string
        - `arrival_city` string: IATA city code of the arrival airport (`CHI` for ORD), from the platform’s airport catalog: a code, not a name. Absent when the airport is not in the catalog.
        - `arrival_time` string: Local time at the airport, RFC 3339 with that airport’s UTC offset (e.g. `2026-09-23T11:55:00-04:00`). Parse it as an instant; do not assume UTC and do not compare two of these as strings. The offset is a property of this leg/segment shape wherever it appears — a flight search, and an itinerary echoed back on a quote or trip read — not of the search response alone. On the rare airport whose timezone the platform does not know, the offset is omitted and the value is local wall-clock time. The `*_local` fields of a booked or exchanged itinerary are NOT this: those carry wall-clock time with no offset, by design.
        - `duration_minutes` number
        - `layover_minutes` number: Wait between this segment’s arrival and the next departure. Absent on the last segment of a leg, and whenever the upstream times could not be resolved.
        - `operating_carrier` string: IATA code of the carrier that actually OPERATES the segment. A value differing from `airline` is a codeshare the passenger must be told about. Whether equality is stated depends on the provider: some always send it, including when it equals `airline`; others send it only when they disclose an operating carrier, so an absent value says nothing about who operates the flight.
    - `fares` Fare[], required
      - `trip_item_token` string: The token that adds this fare to a trip: pass it to `POST /v1/trip` as `add_item.trip_item_token`. Opaque: the offer’s `offer_id`, a colon, then the provider’s reference for the fare. Usable until `expires_at`; after that, search again and use the fresh token.
      - `searched_at` string, date-time: When the supplier search for this fare began, in RFC 3339 format. Repeated searches can return the same trip_item_token; use this timestamp to assess freshness. Absent when the search time is unknown.
      - `expires_at` string, date-time: Latest known time to use this fare, in RFC 3339 format: the earlier of the supplier deadline, when supplied, and Jinko’s 75-minute token lifetime measured from searched_at. Without a supplier deadline this bounds token retention only. Availability and price can change sooner. Complete checkout promptly; after this time, search again and use the latest result. Absent means unknown, not unlimited validity. This is not a quote or payment deadline.
      - `cabin_class` string: The cabin this fare sells: `economy`, `premium_economy`, `business` or `first`. For a fare over several flight segments it is the cabin of the main segment — the longest flight — since a short connecting segment can sit in another cabin.
      - `brand_name` string: The fare brand as the airline names it, read from the first segment that carries a fare component; when the provider names no brand, the cabin name it sent instead. Absent when neither is known.
      - `total_price` Money: A money figure in one of two scales. New integrations read the `*_money` field beside it (a `MoneyValue`) where there is one, and `value` on objects that carry it; the rule below applies only to the deprecated forms. When `decimal_places` is present, `value` (or the deprecated `amount`) is an INTEGER in minor units: divide by 10 ** decimal_places. When it is absent, the deprecated `amount` is already in MAJOR units. Branch on whether decimal_places is present in the response you received, never on the currency code or the field name. `display` is the same figure as a string to show.
        - `amount` number: Deprecated: use `value` instead (the same integer) where this object carries decimal_places. Where it does not, the figure is in MAJOR units and the field holding this object is itself deprecated: read its `*_money` sibling. The two-scale rule applies only to deprecated fields. Alternative to `value` on some endpoints (the two never appear together); its scale depends on decimal_places. When this object carries decimal_places, amount is an INTEGER in minor units — divide by 10 ** decimal_places (e.g. select_ancillaries total_with_ancillaries). When there is no decimal_places field, amount is a decimal in MAJOR units, safe to display as-is (e.g. trip and checkout totals).
        - `value` integer: Integer amount in MINOR units, always paired with decimal_places — divide by 10 ** decimal_places to display. Example: value 15977 with decimal_places 2 is 159.77 USD. Rendering this field directly shows prices 100x too high for 2-decimal currencies.
        - `currency` string: ISO 4217 currency code.
        - `decimal_places` integer: Scale of the integer value/amount: display = integer / 10 ** decimal_places. Always sent alongside minor-unit amounts. Usually the ISO 4217 digits of the currency (2 for USD/EUR/GBP, 0 for JPY/KRW, 3 for BHD/JOD/KWD) but currency-converted prices can carry a different scale — ALWAYS use the decimal_places sent with the amount, never a hardcoded 2. Only if the field is genuinely absent on a value-shaped object, fall back to the ISO digits for the currency.
        - `display` string: The same figure as a string ready to show: the ISO 4217 code, a space, then the amount, e.g. "USD 159.77". With decimal_places it is written at exactly that scale (value 1561500, JPY, decimal_places 2 is "JPY 15615.00"); without, at the ISO digits of the currency. Show this; compute with the number. Absent when the figure is not money (a cancellation step expressed as a percent or a number of nights) or could not be read unambiguously.
      - `price_per_person` MoneyWithoutAmount: A money figure: `value` is an INTEGER in minor units (divide by 10 ** `decimal_places` to get the amount), `currency` is its ISO 4217 code and `display` is the same figure as a string ready to show. The `Money` shape without its deprecated `amount` member, for a figure that never carried one.
        - `value` integer: Integer amount in MINOR units, always paired with decimal_places — divide by 10 ** decimal_places to display. Example: value 15977 with decimal_places 2 is 159.77 USD. Rendering this field directly shows prices 100x too high for 2-decimal currencies.
        - `currency` string: ISO 4217 currency code.
        - `decimal_places` integer: Scale of the integer value/amount: display = integer / 10 ** decimal_places. Always sent alongside minor-unit amounts. Usually the ISO 4217 digits of the currency (2 for USD/EUR/GBP, 0 for JPY/KRW, 3 for BHD/JOD/KWD) but currency-converted prices can carry a different scale — ALWAYS use the decimal_places sent with the amount, never a hardcoded 2. Only if the field is genuinely absent on a value-shaped object, fall back to the ISO digits for the currency.
        - `display` string: The same figure as a string ready to show: the ISO 4217 code, a space, then the amount, e.g. "USD 159.77". With decimal_places it is written at exactly that scale (value 1561500, JPY, decimal_places 2 is "JPY 15615.00"); without, at the ISO digits of the currency. Show this; compute with the number. Absent when the figure is not money (a cancellation step expressed as a percent or a number of nights) or could not be read unambiguously.
      - `included_baggage` object: Checked-bag allowance of this fare, read from the first segment that states one (it is not reported per leg). Absent when no segment states a checked-bag allowance; a stated zero is sent as `pieces: 0`.
        - `pieces` integer: Number of bags included at this allowance.
        - `weight` number: Weight allowance per bag, in `weight_unit`.
        - `weight_unit` string: `KG` or `LB`. Absent when the provider states no recognised unit.
        - `dimensions` string: Size limit as the carrier states it. Free text, not a parseable measurement.
        - `description` string: Text the platform writes from the allowance, not the carrier’s own prose: for checked bags `1 bag, 23KG each`, `2 checked bags included` or `No checked bags included`; for cabin bags `1 carry-on bag` or `2 cabin bags`, with ` and 1 personal item` when one is included. Present on fares with NO free allowance too (`No checked bags included`), so its presence is not evidence a bag is included.
      - `carry_on_baggage` object: Cabin-bag allowance of this fare, read from the first segment that states a carry-on bag or a personal item (it is not reported per leg). Absent when no segment states one.
        - `pieces` integer: Number of bags included at this allowance.
        - `weight` number: Weight allowance per bag, in `weight_unit`.
        - `weight_unit` string: `KG` or `LB`. Absent when the provider states no recognised unit.
        - `dimensions` string: Size limit as the carrier states it. Free text, not a parseable measurement.
        - `description` string: Text the platform writes from the allowance, not the carrier’s own prose: for checked bags `1 bag, 23KG each`, `2 checked bags included` or `No checked bags included`; for cabin bags `1 carry-on bag` or `2 cabin bags`, with ` and 1 personal item` when one is included. Present on fares with NO free allowance too (`No checked bags included`), so its presence is not evidence a bag is included.
      - `is_changeable` boolean: Whether the fare allows a voluntary change, folded from every change rule of the itinerary (the most restrictive wins). Not the same reading as the `changeable_only` filter: the filter checks the before-departure rules only, while this flag is `true` on a fare whose only decided rule allows a change after departure (`change_policy` then ends in `after departure`). `false` is an answer: the fare rules did not confirm a change is allowed.
      - `is_refundable` boolean: Whether the fare can be cancelled, with or without a fee, folded from every cancellation rule of the itinerary (the most restrictive wins). Not the same reading as the `refundable_only` filter: the filter checks the before-departure rules only, while this flag is `true` on a fare whose only decided rule allows cancellation after departure (`refund_policy` then ends in `after departure`). `false` is an answer: the fare rules did not confirm a refund is allowed.
      - `refund_policy` string: The refund terms in words, before booking: `Free cancellation`, `Refundable` (fee not stated), `Refundable with fee` or `Non-refundable`; when the only decided rule applies after departure, the same four with ` after departure` appended, e.g. `Refundable with fee after departure`. A cancellation rule with an unspecified penalty reads `Non-refundable`. Absent when the fare carries no cancellation rule. Read it beside `is_refundable`, which says only whether a refund is possible at all.
      - `change_policy` string: The change terms in words, before booking: `Free changes`, `Changes allowed` (fee not stated), `Changes allowed with fee` or `No changes allowed`; when the only decided rule applies after departure, the same four with ` after departure` appended, e.g. `Changes allowed with fee after departure`. Absent when the fare carries no change rule, or only one with an unspecified penalty. Read it beside `is_changeable`, which says only whether a change is possible at all.
      - `checked_bag_included` boolean: Whether the price already includes at least one free checked bag, read from `included_baggage`: `pieces` is 1 or more. `included_baggage` comes from the first segment that states an allowance, so this is not the same reading as the `checked_bag_included` filter, which needs a free bag on every segment. `weight` is the per-bag limit that applies when a bag IS included, so it carries no allowance on its own; prose in `included_baggage` does not count either.
  - `exact_match_found` boolean: Price-check mode only (request carried `offer_token`): true when the live offer has the same flights as the cached one. Absent in search mode.
  - `result` 'no_matches': Search mode only. `no_matches` means the search completed and no offer matched: relay `instruction`, which asks which filter to relax only when the request sent a filter that narrows the results. `offers` is empty. Absent when offers were found. A search that could not be completed at all answers an error instead (`UPSTREAM_REJECTED`, `UPSTREAM_ERROR`, `UPSTREAM_UNAVAILABLE` or `UPSTREAM_TIMEOUT`), never an empty list.
  - `instruction` string: Present with `result: no_matches`: what to tell the user or do next. It attributes the empty result to the filters only when the request sent a filter that narrows the results; otherwise it reads "Search completed successfully, but no flights were found for this route and dates. Ask the user whether to try other dates or airports before searching again."

## Other responses

- `400`: The request was malformed or failed validation (search and price check alike). When a supplier declined the request, `error.message` is “The request was declined for these inputs. Check the dates, places and travellers, then retry.” **`BAD_REQUEST`** — The request was malformed or failed validation. Fix the request as the message describes; retrying it unchanged cannot succeed.
- `401`: Authentication required
- `402`: Payment required — organization balance exhausted
- `404`: Resource not found
- `409`: The operation conflicts with the current state of the resource
- `410`: The resource this request names no longer exists
- `422`: Validation error
- `429`: Rate limit or quota exceeded
- `502`: The travel provider rejected the request, or an upstream call failed
- `503`: No travel provider can serve the request right now
- `504`: The travel provider did not answer in time

---

[API](https://skmtc.dev/gojinko/apis/jinko-public-api.md) - [All operations](https://skmtc.dev/gojinko/apis/jinko-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/gojinko/apis/jinko-public-api/revisions/ac5046767e4c?raw)
