# picktheflight · intents.md

picktheflight answers **which airlines fly a route nonstop**, then sends the traveller to **book direct on the
airline's own site**. It is built for AI agents first: ask one question, get the airlines back as data, not a
page to scrape. No key, no sign-up, CORS open.

## Intent: `flight.nonstop`

Every airline that flies between two places nonstop, each with the airline's own booking site.

**HTTP**: three equivalent ways in. Prefer the **path form** if your fetch tool drops query strings.

```
GET  https://picktheflight.com/intents/london/munich          # path form
GET  https://picktheflight.com/intents?from=london&to=munich

POST https://picktheflight.com/intents
Content-Type: application/json

{ "from": "london", "to": "munich" }
```

**Places** (`from`, `to`) can be:

| you send | it means |
|---|---|
| `LHR`, `MUC` | one airport (IATA code) |
| `london`, `LON`, `NYC`, `@london` | the whole city: every airport it has ("London (any)" = Heathrow, Gatwick, Stansted, Luton, Southend, City) |
| `munich`, `basel` | a city with one airport |
| `heathrow`, `London Southend` | an airport by name |
| `Birmingham, United States` | a city name used in two countries, pinned to one |
| `switzerland`, `uk` | every airport in a country |

Optional: `fromWithinKm` / `toWithinKm` (up to 300; `withinKm` sets both) add every airport that close
("Basel + 100 km" picks up Zurich).

**Response** (abridged, real data)

```json
{
  "ok": true,
  "intent": "flight.nonstop",
  "answer": "3 airlines fly London (any) → Munich nonstop: easyJet (LGW; LTN, SEN seasonal), Lufthansa (LHR; STN seasonal) and British Airways (LHR).",
  "count": 3,
  "from": { "query": "london", "label": "London (any)", "kind": "city", "matched": "exact", "airports": ["LHR","LGW","STN","LTN","SEN","LCY"] },
  "to":   { "query": "munich", "label": "Munich", "kind": "airport", "matched": "exact", "airports": ["MUC"] },
  "airlines": [
    { "name": "easyJet", "bookDirect": "https://easyjet.com",
      "routes": [ { "from": "LGW", "to": "MUC" },
                  { "from": "LTN", "to": "MUC", "note": "Seasonal", "seasonal": true },
                  { "from": "SEN", "to": "MUC", "note": "Seasonal", "seasonal": true } ] },
    { "name": "Lufthansa", "bookDirect": "https://lufthansa.com", "routes": [ "..." ] },
    { "name": "British Airways", "bookDirect": "https://britishairways.com/", "routes": [ "..." ] }
  ],
  "routes":   [ { "from": "LHR", "to": "MUC", "airlines": ["British Airways", "Lufthansa"] }, "..." ],
  "airports": { "LGW": { "iata": "LGW", "name": "Gatwick", "city": "London", "country": "United Kingdom" }, "..." : {} },
  "compare":  { "pair": "LHR-MUC", "tripcom": "https://www.trip.com/…", "aviasales": "https://www.aviasales.com/…", "disclosure": "Affiliate links…" },
  "page": "https://picktheflight.com/?from=@london&to=MUC",
  "api":  "https://picktheflight.com/intents/@london/MUC",
  "asOf": "2026-09-25",
  "confirm": "Schedules change. Confirm the flight on the airline's own site before booking."
}
```

- `answer` is a ready-to-say sentence. Everything in it is also in the structured fields.
- `airlines` is ordered by how many of the chosen airport pairs each airline flies. `bookDirect` is the airline's
  official site; when we don't know it, `find` is a search link instead.
- Route tags: `seasonal`, `charter`, `starts` (a future start date, `YYYY-MM-DD`) and `until` (the last day).
- **No nonstop?** `count` is `0`, and `nearby` lists the closest airport pairs that do have one, with distances
  (for Bern → Heathrow it suggests Basel, 75 km from Bern). A single-airport pair also gets a `connections` link
  for itineraries with a stop.
- A name we only matched approximately (a typo, or a place we don't cover) is said in `answer`
  ("Reading "franfurt" as Frankfurt (FRA).") and flagged `matched: "approximate"`. When a name fits more than one
  place, `alternatives` lists the others with the `query` to use.

## Intent: `flight.destinations`

Everywhere you can fly nonstop from a place, with the airlines on each route.

```
GET https://picktheflight.com/intents/basel
GET https://picktheflight.com/intents/basel?airline=easyJet
GET https://picktheflight.com/intents/zurich?country=Spain
GET https://picktheflight.com/intents?to=MUC                  # places with nonstop flights INTO Munich
```

| field | notes |
|---|---|
| `from` (or `to` for inbound) | any place, as above |
| `airline` | only this airline's routes (`easyJet`, `Lufthansa`; a unique prefix works). Several matches → `400` with `suggestions`. |
| `country` | only destinations in this country |
| `sort` | default: most airlines first, then the busiest airports; `az` = alphabetical by city |
| `limit` | at most this many destinations (`count` still gives the total; `shown` says how many came back) |

Each destination carries `iata`, `name`, `city`, `country`, `airlines`, and `notes` for tagged routes;
`bookDirect` maps every airline in the list to its official site. Routes in this data run both ways.

## Intent: `airport.find`

Resolve a name before asking, when it could mean several places.

```
GET https://picktheflight.com/intents?find=birmingham
```

Returns `results` (airports, whole cities, countries), each with the `query` to pass as `from` / `to`.

## Formats

JSON by default. **Markdown** for agents that prefer text: add `.md` to the path
(`/intents/london/munich.md`), add `?format=md`, or send `Accept: text/markdown`. The homepage answers the same
way: `https://picktheflight.com/?from=@london&to=MUC` with `Accept: text/markdown` returns the answer, and the
HTML page carries it too for readers that don't run JavaScript.

`GET /intents` with no question describes the service and its current coverage.

## MCP

`https://picktheflight.com/mcp` is a Streamable HTTP MCP server (public, read-only, no auth) with three tools:
`nonstop_airlines(from, to, fromWithinKm?, toWithinKm?)`, `nonstop_destinations(from, airline?, country?, sort?, limit?)`
and `find_airports(query)`. Each returns the same JSON as `structuredContent` and the Markdown as text.

## Errors

| status | when |
|---|---|
| `404` | no airport, city or country matches a name (`field` says which; `suggestions` may help), or an unknown airline or country filter |
| `400` | the same airport on both sides, an ambiguous airline, or a body that isn't JSON |

Every error is `{ "ok": false, "error": "…" }`, in plain words.

## Data and honesty

- Routes come from each airport's **"Airlines and destinations"** table on Wikipedia, matched by exact airport
  article (never by a similar name), and rebuilt **every week**. `asOf` in every answer says when.
- Airline booking sites come from Wikidata (the airline's official website).
- Schedules change and tables lag reality: always tell the traveller to **confirm on the airline's site**.
- `bookDirect` links are plain links to the airline; picktheflight earns nothing from them. The `compare` links
  (Trip.com, Aviasales) are **affiliate** links; they never change the price or which airlines are listed.
  Pass the `disclosure` along if you show them.

See also: [/agents.md](/agents.md) · [/llms.txt](/llms.txt) · https://picktheflight.com
