---
title: "Read ranked flight results"
method: GET
path: "/v1/flights/searches/{searchId}/results"
tags: ["Flights"]
---

# Read ranked flight results

`GET /v1/flights/searches/{searchId}/results`

Ranked trips as lean list cards (default 10, max 50 per page; out-of-range rejected 400), filters + sort applied. No completion flag: re-read (300ms→3s) until snapshotFareCount holds steady across two reads AND snapshotTripCount > 0. No fares[] on a card – read the trip for fares.

## Path parameters

- `searchId` string, required

## Query parameters

- `page` integer
- `pageSize` integer
- `sort` 'score_desc' | 'price_asc' | 'duration_asc' | 'leg1_departure_time_asc' | 'leg1_departure_time_desc' | 'leg2_departure_time_asc' | 'leg2_departure_time_desc'
- `airlines` string[]
- `airlines-match` 'any' | 'all'
- `same-airline` '0' | '1' | 'true' | 'false'
- `alliances` string[]
- `stops` integer[]
- `min-price` number
- `max-price` number
- `max-duration` integer
- `min-stopover-duration` string
- `max-stopover-duration` string
- `outbound-departure-blocks` string[]
- `outbound-departure-range` string
- `booking-types` string[]
- `booking-sites` string[]
- `stopover-airports` string[]
- `aircraft` string[]
- `currency` string
- `locale` string
- `view` 'card'

## Response `200`

The current ranked-trip snapshot, as list cards.

- object — A paginated snapshot of ranked trips as lean list cards.
  - `searchId` string, required — The id of the search this snapshot belongs to.
  - `currencyCode` string, required — The currency the prices in this snapshot actually came back in, read off the fares themselves – so this, not metadata.currencyCode, is what a displayed number is denominated in. metadata.currencyCode reports what the read asked for and carries currencyCodeSource beside it; the two agree unless upstream declined to reprice into the requested currency.
  - `metadata` object, required — Pagination, the snapshot's filter vocabulary, the settle counters for this read, and what it resolved currency and locale to.
    - `page` integer, required — 1-based page number of this snapshot.
    - `pageSize` integer, required — Trips requested per page.
    - `resultCount` integer, required — Trips on this page. The page only – judge a filter on totalCandidates, not this.
    - `totalCandidates` integer, required — Trips matching this read's filters across the whole snapshot – the count that judges a filter, never the page (results). Flights have no completion flag: settle on snapshotFareCount steady across two reads with snapshotTripCount above 0.
    - `hasMore` boolean, required — Another page of trips follows.
    - `filterOptions` object, required — The filter values this snapshot actually carries, ordered by count, over the same trips as snapshotTripCount. Codes are what the matching query param accepts, so pick from here rather than guessing: sending one listed code with no other filter makes metadata.totalCandidates equal that count exactly. It does NOT bound results, which stays the requested page, so compare against totalCandidates and not resultCount. Counts assume the default matching, so airlines-match=all or same-airline=true can keep fewer trips than the airlines count promises. count is trips, not legs or fares, and a trip is counted once however many of its legs or fares carry the value, including when only its return leg does. name is the display label: always present on bookingSites, where the provider code is its own fallback, present on airlines and stopoverAirports only when the snapshot dictionary resolves the code, and never present on alliances, which upstream gives no label. Still growing while the search aggregates, so judge an ABSENT code only once snapshotFareCount holds steady across two reads.
      - `alliances` object[], required — Alliance codes present in this snapshot, by descending count.
        - `code` string, required — The code the matching filter query param accepts.
        - `name` string — Display label for the code, when the snapshot dictionary resolves one.
        - `count` integer, required — Trips carrying this value, deduped per trip and matched on any leg.
      - `airlines` object[], required — Airline codes present in this snapshot, by descending count.
        - `code` string, required — The code the matching filter query param accepts.
        - `name` string — Display label for the code, when the snapshot dictionary resolves one.
        - `count` integer, required — Trips carrying this value, deduped per trip and matched on any leg.
      - `bookingSites` object[], required — Booking provider codes present in this snapshot, by descending count.
        - `code` string, required — The code the matching filter query param accepts.
        - `name` string — Display label for the code, when the snapshot dictionary resolves one.
        - `count` integer, required — Trips carrying this value, deduped per trip and matched on any leg.
      - `stopoverAirports` object[], required — Stopover airport codes present in this snapshot, by descending count.
        - `code` string, required — The code the matching filter query param accepts.
        - `name` string — Display label for the code, when the snapshot dictionary resolves one.
        - `count` integer, required — Trips carrying this value, deduped per trip and matched on any leg.
      - `aircraft` object[], required — Aircraft type codes present in this snapshot, by descending count. name is the display label the results card publishes (A380, A320 Neo), and is NOT unique: several codes can carry the same label, so filter on code. Includes any non-aircraft equipment upstream reports on a leg, such as BUS for a surface segment.
        - `code` string, required — The code the matching filter query param accepts.
        - `name` string — Display label for the code, when the snapshot dictionary resolves one.
        - `count` integer, required — Trips carrying this value, deduped per trip and matched on any leg.
      - `stopoverDurations` object — The layover span this snapshot carries, in minutes, measured the way min-stopover-duration and max-stopover-duration are judged: per trip, the LARGEST leg total across its legs. Use it to bound a slider. Both ends are reachable - sending the published min or max with no other filter keeps at least the trip that set it. min is 0 whenever the snapshot holds one direct trip, which is the usual case. A range, not a count list, so it has no name or count. Absent when nothing here is measurable: an empty snapshot, or one where every trip carries a connecting leg whose layover upstream never stated.
        - `min` number, required — Shortest layover any trip in this snapshot carries, in minutes. 0 whenever one trip is direct. Echoes the upstream figure, so it is a whole number of minutes wherever upstream states one.
        - `max` number, required — Longest layover any trip in this snapshot carries, in minutes.
    - `snapshotTripCount` integer, required — Renderable trips before filter/sort/page. 0 means upstream has produced none yet; above 0 beside an empty `results` means a filter or page range excluded everything. Settling needs `snapshotFareCount` steady across two reads AND this above 0.
    - `snapshotFareCount` integer, required — Upstream progress counter, for cross-read comparison only. Runs ahead of the fares returned and stays non-zero over an empty page, so read `resultCount`/`totalCandidates` for display. Settled = equal non-zero across two reads with `snapshotTripCount` above 0.
    - `createdAt` string — When the upstream search was created (ISO 8601) – the freshness anchor for these prices. Absent when upstream omits it.
    - `currencyCode` string, required — The currency this read ASKED upstream for, and the one every price on it is meant to be in. Read it beside currencyCodeSource before you show a number: a price computed in the wrong currency renders as a perfectly normal price, with no error and no odd shape to notice, so the response states which one rather than leaving it to be inferred. Where the operation also publishes a top-level currencyCode, that field reports the currency the prices actually came back in; the two agree unless upstream declined to reprice.
    - `currencyCodeSource` 'explicit' | 'default', required — How the API resolved currencyCode: explicit (the caller sent currency – including a value equal to the default) or default (USD, no currency sent). A default here is the one signal that the request never carried the currency you meant.
    - `locale` string, required — The language tag this read asked upstream for – what any localized text on it was resolved in (room and board names, airline and airport names, review prose).
    - `localeSource` 'explicit' | 'default', required — How the API resolved locale: explicit (the caller sent locale – including a value equal to the default) or default (en, no locale sent). A default here explains text that came back in a language the caller did not ask for.
  - `results` object[], required — The requested page of ranked trips, as list cards.
    - `tripId` string, required — Opaque trip id; read it back with GET /v1/flights/trips/{tripId}.
    - `badges` string[], required — Every featured label that fits this trip. best_value ranks on the score of the trip's CHEAPEST fare, the same statistic sort=score_desc orders by; cheapest and cheapest_direct break a price tie by that score, then by leg-1 departure – cheapest keeps the LATER departure, cheapest_direct the EARLIER one.
    - `stops` number, required — Trip-level stop count – the MAX across legs, the same value ?stops= filters on. Do not fold legs[] yourself.
    - `durationMinutes` number, required — Trip-level duration – the SUM across legs.
    - `price` object, required — Card price summary – the cheapest whole-party total, fee-inclusive; scope names the (party) figure.
      - `total` number, required — The cheapest fare's whole-party total (upstream totalAmount), including payment + booking fees.
      - `currency` string, required — ISO 4217 currency of total.
      - `scope` 'party', required — total covers the whole party (adults + children + infants), not per-person.
      - `websiteCount` integer, required — How many providers/fares sell this trip ("from 11 websites").
      - `hasWegoFare` boolean, required — Whether any of the trip's fares is a Book-on-Wego fare.
    - `legs` object[], required — Per-leg summary for this trip, outbound first then return.
      - `from` string, required — Departure airport IATA code.
      - `to` string, required — Arrival airport IATA code.
      - `departsAt` string, required — Leg departure, ISO 8601 with offset.
      - `arrivesAt` string, required — Leg arrival, ISO 8601 with offset.
      - `arrivalDayOffset` number, required — Calendar days the arrival lands after departure (the +1 badge).
      - `overnight` boolean, required — The leg spans a night.
      - `durationMinutes` number, required — Leg duration in minutes.
      - `stops` number, required — Stops on this leg (0 is nonstop).
      - `via` string[], required — Stopover airport codes ("via KUL"); empty for a direct leg.
      - `layoverMinutesByStop` number[] — Layover minutes per connection, index-aligned to via, so layoverMinutesByStop[i] is the wait at via[i]. Absent on a direct leg, and absent on a leg whose upstream segment list does not line up with via, where publishing it could pair a wait with the wrong airport. Named apart from the trip read's legs[].layoverMinutes, which is a single leg TOTAL rather than a per-connection list. Sums to the leg total that min-stopover-duration and max-stopover-duration are judged against; those params bound the LARGEST leg total across the trip's legs, not an individual connection, so a trip kept by max-stopover-duration can still carry one long wait among several short ones.
      - `airlines` object[], required — Marketing airlines on the leg, resolved to code, name and logo.
        - `code` string, required — IATA airline code.
        - `name` string, required — Airline display name.
        - `logoUrl` string, required — Airline logo URL; may 404, fall back to the name.
      - `operatingAirlines` object[] — Carriers that fly a segment of this leg they do not market. airlines names the MARKETING carriers only, so on a leg sold by one airline every code here is a carrier absent from the ticket; on an interline leg sold by two, one of these may also market a different segment. Read this before telling a traveller who they fly. This card carries no segments[], so read the trip for which flight each one operates. PRESENT ONLY WHEN A SEGMENT PROVES A CODESHARE: absent means none was proven on this leg, never a promise that the marketing carrier operates every segment.
        - `code` string, required — IATA airline code.
        - `name` string, required — Airline display name.
        - `logoUrl` string, required — Airline logo URL; may 404, fall back to the name.
      - `aircraft` string[], required — Distinct aircraft short names across the leg ("A330","B787"). Equipment only: a surface segment does show up here as its equipment label ("Bus"), but transportTypes is the field that states the mode.
      - `transportTypes` string[], required — Distinct transport modes across this leg's segments, in segment order. Always present and never empty: an all-flight leg reads ["FLIGHT"]. This card carries no segments[], so anything else here means read the trip to see which segment is not a plane before you quote the leg as a flight.

## Other responses

- `400` — Invalid request body/query/path parameters.
- `401` — Missing or invalid bearer token.
- `404` — Unknown or expired search.
- `429` — Rate limit exceeded; retry after the `Retry-After` seconds.
- `502` — The upstream flights service returned an invalid response.
- `503` — The flights service is temporarily unavailable (`upstream_unavailable`) or rate-limited upstream (`upstream_rate_limited`); retry after the `Retry-After` seconds.

---

[API](https://skmtc.net/wego/apis/wego-api.md) · [All operations](https://skmtc.net/wego/apis/wego-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/wego/wego-api/revisions/e5d7af502419/schema)
