---
title: "Search flights"
method: POST
path: "/api/v1/flights/search"
tags: ["Flights"]
---

# Search flights

`POST /api/v1/flights/search`

Search hundreds of airlines for flights. Free and unlimited.
Results include price, airlines, duration, stopovers, and booking conditions.
City codes (LON, NYC, PAR) automatically expand to all airports in that city.

## Request body

- FlightSearchRequest
  - `origin` string, required — IATA airport or city code (e.g. LHR, LON, JFK)
  - `destination` string, required — IATA airport or city code
  - `date_from` string, date, required — Departure date (YYYY-MM-DD)
  - `date_to` string, date — Return date for round-trip (YYYY-MM-DD). Omit for one-way.
  - `adults` integer — Number of adult passengers
  - `children` integer — Number of children (2-11 years)
  - `cabin` 'M' | 'W' | 'C' | 'F' — Cabin class: M=economy, W=premium economy, C=business, F=first
  - `max_stops` integer — Maximum stopovers per direction
  - `currency` string — 3-letter currency code
  - `limit` integer — Maximum number of results
  - `sort` 'price' | 'duration'

## Response `200`

Search results

- FlightSearchResponse
  - `search_id` string — Unique search identifier
  - `passenger_ids` string[] — Passenger IDs to use when booking (e.g. pas_0, pas_1)
  - `total_results` integer — Total number of matching offers
  - `offers` FlightOffer[]
    - `id` string — Offer ID (use for unlock/book)
    - `price` number, float — Total price for all passengers
    - `currency` string
    - `airlines` string[] — Airlines operating the flights
    - `owner_airline` string — Primary operating airline
    - `route` string — Route summary (e.g. STN → BCN)
    - `duration_seconds` integer — Total journey duration in seconds
    - `stopovers` integer — Number of stops
    - `outbound` FlightRoute
      - `segments` FlightSegment[]
        - `airline` string
        - `flight_no` string
        - `origin` string
        - `destination` string
        - `departure` string, date-time
        - `arrival` string, date-time
        - `duration_seconds` integer
        - `cabin` string
        - `aircraft` string — Aircraft type as reported by the source, when known (e.g. 'Boeing 737MAX 8')
        - `starlink` 'confirmed' | 'likely', nullable — Starlink in-flight Wi-Fi on this leg. 'confirmed' = the carrier has fitted every aircraft of this type. 'likely' = installation on this type is underway but incomplete, so this airframe may not have it. Omitted/null means no information — NOT an absence of Wi-Fi.
      - `total_duration_seconds` integer
      - `stopovers` integer
      - `route_str` string — Human-readable route (e.g. LHR → BCN)
    - `inbound` FlightRoute
      - `segments` FlightSegment[]
        - `airline` string
        - `flight_no` string
        - `origin` string
        - `destination` string
        - `departure` string, date-time
        - `arrival` string, date-time
        - `duration_seconds` integer
        - `cabin` string
        - `aircraft` string — Aircraft type as reported by the source, when known (e.g. 'Boeing 737MAX 8')
        - `starlink` 'confirmed' | 'likely', nullable — Starlink in-flight Wi-Fi on this leg. 'confirmed' = the carrier has fitted every aircraft of this type. 'likely' = installation on this type is underway but incomplete, so this airframe may not have it. Omitted/null means no information — NOT an absence of Wi-Fi.
      - `total_duration_seconds` integer
      - `stopovers` integer
      - `route_str` string — Human-readable route (e.g. LHR → BCN)
    - `conditions` object
      - `refund_before_departure` 'allowed' | 'allowed_with_fee' | 'not_allowed'
      - `change_before_departure` 'allowed' | 'allowed_with_fee' | 'not_allowed'
    - `starlink` 'confirmed_all' | 'confirmed_some' | 'likely_all' | 'likely_some', nullable — Starlink in-flight Wi-Fi across the whole itinerary. 'confirmed_all' = every leg is on a subfleet the carrier has fully fitted; 'confirmed_some' = at least one leg confirmed and at least one leg with none; 'likely_all' / 'likely_some' = same, but for subfleets where installation is underway and incomplete. Per-leg detail is on each segment's `starlink`. Only present 'confirmed_*' to an end user as a fact. Omitted/null means no information for any leg.
    - `is_locked` boolean — Whether this offer has been unlocked
    - `source` string — Data source (e.g. ryanair, amadeus, duffel)

## Other responses

- `401` — Invalid or missing API key
- `422` — Invalid request (bad IATA code, date in past, etc.)

---

[API](https://skmtc.dev/letsfg/apis/letsfg-api.md) · [All operations](https://skmtc.dev/letsfg/apis/letsfg-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/letsfg/letsfg-api/revisions/89a6a1405650/schema)
