# 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"
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs-integration.squake.earth/api-calculations-request-response/travel/flight/flight-routing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
