> For the complete documentation index, see [llms.txt](https://docs-integration.squake.earth/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs-integration.squake.earth/api-calculations-request-response/travel/flight/flight-routing.md).

# Flight: Routing (multi-leg)

Flight routing lets API clients send a **single** flight item with an ICAO-style **hyphen-separated airport chain** (for example `BER-FRA-JFK`) instead of `origin` and `destination`. The backend expands that string into consecutive legs (BER→FRA, FRA→JFK), runs the same methodology **once per leg**, and **aggregates** carbon and distance on the parent item.

***

## Mutual exclusion with `origin` / `destination`

`routing` **cannot** be combined with `origin` or `destination`. Supplying both yields `invalid_params` with a detail such as:

`'routing' cannot be used together with 'origin' or 'destination'.`

***

## Parsing rules

The routing string is parsed as follows:

* Split on `-`, segments are converted to uppercase and trimmed.
* There must be **at least two** non-empty segments.
* **Consecutive segments must not be identical** (for example `BER-BER` is invalid).

Invalid or empty routing fails validation with a clear error, for example:

`'routing' must be a hyphen-separated list of at least two distinct airport codes (e.g. BER-FRA-JFK).`

***

## Per-leg parameters (pipe lists and defaults)

Certain attributes can vary **per leg**. Validated attributes include:

`booking_class`, `fare_class`, `airline`, `aircraft_type`, `aircraft_size`, `plane_type`, `biofuel`, `flight_number`, `departure_date`.

### How values are applied

* **Single value** — repeated for every leg.
* **Pipe-separated (`|`)** — must have **exactly as many parts as legs**. Leg count is the number of **consecutive airport pairs** in the routing (for `BER-FRA-JFK` there are **two** legs).
* **Hyphen split** — if the number of hyphen-separated segments **equals** the leg count, values map leg-by-leg. If that count does **not** match and the string is not a **single** segment, validation fails with an ambiguous multi-segment string.
* **`departure_date` is pipe-only** — it is never hyphen-split, because ISO dates contain hyphens. Use a single value (broadcast to all legs) or a pipe list with one entry per leg.

A **count mismatch** returns `invalid_params` with detail like:

`'booking_class' list has 2 value(s) but routing has 1 leg(s).`

Validation failures and leg-count mismatches also emit internal metrics for monitoring.

***

## `distance_in_km` when routing is present

`distance_in_km` is **not** used as a substitute for computed distance when routing is present: routing drives **per-leg** distance, and the parent item’s distance aggregates those legs. Submitting `distance_in_km` does **not** define the total for routed items.

***

## Response and `expand`

* Include **`"legs"`** in the request **`expand`** array (together with **`"items"`** when you need per-item totals) to receive a **per-leg** breakdown on the flight item.
* When `legs` is expanded, the item typically includes **`routing`** (echoing the submitted chain) and a **`legs`** array. Parent **`carbon_quantity`** and **`distance`** aggregate the legs (for example, parent `distance` matches the sum of leg distances).
* If **`expand`** includes only **`items`** (and omits **`legs`**), the item payload **may omit** `routing` and `legs` even when the request used routing.

With **audit mode** enabled, per-leg objects can include **`audit`** and **`emission_factors`** when `legs` is expanded.

***

## Example request

Multi-leg DEFRA flight with expanded items and legs:

```json
{
  "expand": ["items", "legs"],
  "carbon_unit": "tonne",
  "distance_unit": "kilometer",
  "items": [
    {
      "type": "flight",
      "methodology": "DEFRA",
      "routing": "BER-FRA-JFK",
      "booking_class": "economy",
      "number_of_travelers": 1,
      "radiative_forcing_index": true,
      "external_reference": "multi_leg_1"
    }
  ]
}
```

Per-leg attributes example (two legs, different booking classes):

```json
{
  "routing": "BER-FRA-JFK",
  "booking_class": "economy|business"
}
```
