{
  "openapi": "3.1.0",
  "info": {
    "title": "FlightPortrait network API",
    "description": "Open data from the FlightPortrait receiver network. No API key.\n\n**Stability.** Operations marked `x-stability: stable` only ever gain fields; names and types are frozen. Operations marked `x-stability: map` exist for the first-party map and can change with it. Operations marked `x-stability: candidate` are proposed for the stable tier: their shape may still change before it is frozen.\n\n**Field dialects.** `/v1/aircraft` and `/v2/point` pass readsb's wire fields through unchanged (`hex`, `t`, `r`, `gs`, ...) so ecosystem tooling works as-is. Every other resource uses full words: `reg`, `type`, `org`, `dst`. Airport codes in history resources are IATA; `/v1/airports/{code}` accepts IATA or ICAO. Event times are unix seconds UTC; registry timestamps are ISO 8601 UTC; board and schedule times are HH:MM in the origin airport's local time.\n\n**Data honesty.** History is observation, never an official registry. Gaps mean the network's sources did not hear it, nothing more. Responses carry `coverage: \"observed\"` as a reminder. The one exception is the airport departures board, whose rows may be inferred from published timetables \u2014 each board row carries its own `source` (observed / published / both); a published row is not a receiver observation. Likewise a flight's `route_source`: `observed` when both ends were seen, `observed+catalog` when the community supplied the end coverage never reached, `catalog` when it supplied both. Catalog answers are checked against observation and reviewed before they are served, and observation outranks them whenever it speaks. This API is read-only; answers go to the contribution door at contribute.flightportrait.com.\n\n**Errors.** Every non-200 body is `{\"error\": <code>, \"detail\": <human text>}` with `Cache-Control: no-store`. 404 `not_found` / `not_observed`, 422 `invalid_request`, 429 `rate_limited` (with `Retry-After` and `RateLimit-*` headers), 503 `stale_snapshot` (live snapshot older than 60 s) or `artifact_unavailable` (a history artifact is not loaded).\n\n**Rate limits.** Per IP, per bucket, over a 600 second window; each operation notes its bucket and default limit. 429 means wait for `Retry-After` seconds.\n\nData is ODbL 1.0. Credit \"FlightPortrait network feeders\" and link the credits page, which lists every source the data draws on and the credit each one asks for; republishing carries them too.\nCredits: https://flightportrait.com/network/credits.html\nTerms: https://flightportrait.com/network/terms",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://data.flightportrait.com"
    }
  ],
  "paths": {
    "/v1/now": {
      "get": {
        "tags": [
          "Live"
        ],
        "summary": "Counts",
        "description": "Aircraft and station counts from the live snapshot. 503 if the snapshot is older than 60 seconds. Rate: 600 per 600 s (bucket `now`). Cache: 10 s edge, 5 s browser.",
        "operationId": "now",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "aircraft_count": {
                      "type": "integer",
                      "description": "Aircraft in the current snapshot."
                    },
                    "aircraft_with_pos": {
                      "type": "integer",
                      "description": "Of those, with a position."
                    },
                    "station_count": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Feeders connected right now. Null when presence is unavailable, never zero for that case."
                    },
                    "generated_at": {
                      "type": "number",
                      "description": "Snapshot time, unix seconds UTC. Never older than 60 s (503 instead)."
                    },
                    "archive_through": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Newest day in the flight-history archive, ISO date. Null while the archive is unavailable."
                    }
                  },
                  "type": "object",
                  "required": [
                    "aircraft_count",
                    "aircraft_with_pos",
                    "station_count",
                    "generated_at"
                  ]
                },
                "example": {
                  "aircraft_count": 508,
                  "aircraft_with_pos": 467,
                  "station_count": 18,
                  "generated_at": 1787924061.0,
                  "archive_through": "2026-09-06"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "type": "object",
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "503": {
            "description": "Live snapshot older than 60 seconds (stale_snapshot) or a required history artifact is not loaded (artifact_unavailable). Retry-After is set.",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "type": "object",
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          }
        },
        "x-stability": "stable"
      }
    },
    "/v1/aircraft": {
      "get": {
        "tags": [
          "Live"
        ],
        "summary": "Aircraft",
        "description": "Aircraft the network hears right now, readsb field dialect. With `bbox=minLon,minLat,maxLon,maxLat` only the aircraft with a position inside it (a box whose west edge is east of its east edge crosses the antimeridian); `total` stays the whole network. 503 if the snapshot is older than 60 seconds. Rate: 300 per 600 s (bucket `aircraft`). Cache: 10 s edge, 5 s browser.",
        "operationId": "aircraft",
        "parameters": [
          {
            "name": "bbox",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 80
                },
                {
                  "type": "null"
                }
              ],
              "description": "minLon,minLat,maxLon,maxLat; only aircraft with a position inside.",
              "title": "Bbox"
            },
            "description": "minLon,minLat,maxLon,maxLat; only aircraft with a position inside."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "generated_at": {
                      "type": "number",
                      "description": "Snapshot time, unix seconds UTC."
                    },
                    "total": {
                      "type": "integer",
                      "description": "Aircraft in the whole snapshot, before any bbox filter."
                    },
                    "with_position": {
                      "type": "integer",
                      "description": "Of those, aircraft with a position fix."
                    },
                    "aircraft": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "hex": {
                            "type": "string",
                            "description": "ICAO 24-bit address, lowercase hex."
                          },
                          "flight": {
                            "type": "string",
                            "description": "Callsign, trailing spaces stripped. Absent when not broadcast."
                          },
                          "t": {
                            "type": "string",
                            "description": "ICAO type designator."
                          },
                          "r": {
                            "type": "string",
                            "description": "Registration."
                          },
                          "lat": {
                            "type": "number",
                            "description": "WGS84 degrees."
                          },
                          "lon": {
                            "type": "number",
                            "description": "WGS84 degrees."
                          },
                          "alt_baro": {
                            "description": "Barometric altitude, feet, or the string \"ground\".",
                            "oneOf": [
                              {
                                "type": "integer"
                              },
                              {
                                "const": "ground"
                              }
                            ]
                          },
                          "gs": {
                            "type": "number",
                            "description": "Ground speed, knots."
                          },
                          "track": {
                            "type": "number",
                            "description": "Track, degrees true."
                          },
                          "category": {
                            "type": "string",
                            "description": "ADS-B emitter category (A0-D7)."
                          },
                          "squawk": {
                            "type": "string",
                            "description": "Transponder code, 4 octal digits."
                          },
                          "seen": {
                            "type": "number",
                            "description": "Seconds since the last message."
                          },
                          "seen_pos": {
                            "type": "number",
                            "description": "Seconds since the last position."
                          },
                          "baro_rate": {
                            "type": "integer",
                            "description": "Vertical rate, feet per minute, positive climbing."
                          },
                          "emergency": {
                            "type": "string",
                            "description": "Transponder emergency state: none, general, lifeguard, minfuel, nordo, unlawful, downed, reserved."
                          }
                        },
                        "required": [
                          "hex"
                        ],
                        "description": "readsb passthrough dialect. Optional fields are absent when unknown, never null."
                      }
                    }
                  },
                  "required": [
                    "generated_at",
                    "total",
                    "with_position",
                    "aircraft"
                  ]
                },
                "example": {
                  "generated_at": 1787924061.0,
                  "total": 191,
                  "with_position": 184,
                  "aircraft": [
                    {
                      "hex": "76cd06",
                      "flight": "SIA123",
                      "t": "A359",
                      "r": "9V-SHF",
                      "lat": 1.5,
                      "lon": 103.8,
                      "alt_baro": 6325,
                      "gs": 285.9,
                      "track": 85.4,
                      "category": "A5",
                      "squawk": "2136",
                      "seen": 0.2,
                      "seen_pos": 1.1,
                      "baro_rate": 1856,
                      "emergency": "none"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Malformed input.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "503": {
            "description": "Live snapshot older than 60 seconds (stale_snapshot) or a required history artifact is not loaded (artifact_unavailable). Retry-After is set.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          }
        },
        "x-stability": "stable"
      }
    },
    "/v1/estimated": {
      "get": {
        "tags": [
          "Live"
        ],
        "summary": "Estimated positions",
        "description": "Aircraft the network stopped hearing while cruising, drawn where they most likely are: flown on from the last observed position toward the destination their callsign's route names, at the last observed speed (holding the last track 10 minutes, then turning toward the destination). Every entry is an estimate, never an observation: `estimated` is always true, `last_seen` is the last real position, `alt_baro` and `gs` are the last observed values. An aircraft appears 90 s after it was last heard and leaves when it is heard again, nears its destination, or its flight time runs out. Kept in memory, never archived or exported. Scored every night against the previous day's real coverage gaps; `accuracy` is the latest night's result for the method in use (median error by gap length), null before the first. Rate: 300 per 600 s (bucket `estimated`). Cache: 15 s edge, 10 s browser.",
        "operationId": "estimated",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "generated_at": {
                      "type": "number",
                      "description": "Unix seconds the estimates are for."
                    },
                    "method": {
                      "type": "string",
                      "description": "How positions are estimated."
                    },
                    "accuracy": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "description": "The latest night's measured accuracy: day, n, median_km, by_gap_min."
                    },
                    "aircraft": {
                      "items": {
                        "type": "object"
                      },
                      "type": "array",
                      "description": "Estimated aircraft; every entry is an estimate, never an observation."
                    }
                  },
                  "type": "object",
                  "required": [
                    "generated_at",
                    "method",
                    "aircraft"
                  ]
                },
                "example": {
                  "generated_at": 1790140000.0,
                  "method": "converge-to-destination",
                  "accuracy": {
                    "day": "2026-09-22",
                    "n": 208,
                    "median_km": 2.3,
                    "by_gap_min": {
                      "5-15": {
                        "n": 153,
                        "median_km": 1.4
                      },
                      "60-120": {
                        "n": 43,
                        "median_km": 76.9
                      }
                    }
                  },
                  "aircraft": [
                    {
                      "hex": "4ca8e4",
                      "flight": "RYR1153",
                      "t": "B738",
                      "r": "9H-QDS",
                      "category": "A3",
                      "lat": 43.1021,
                      "lon": 11.9403,
                      "track": 312.4,
                      "alt_baro": 36000,
                      "gs": 452.0,
                      "estimated": true,
                      "last_seen": {
                        "at": 1790139412.0,
                        "lat": 42.2,
                        "lon": 13.1
                      },
                      "destination": "PSA",
                      "eta": 1790140700
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "type": "object",
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          }
        },
        "x-stability": "map"
      }
    },
    "/v1/trace/{hex}": {
      "get": {
        "tags": [
          "Live"
        ],
        "summary": "Trace",
        "description": "Recent positions for one aircraft, oldest first. Each point is [t, lat, lon, alt_baro, track]. Held in memory about 30 minutes; a restart forgets and trails regrow. 404 if none. Rate: 600 per 600 s (bucket `trace`). Cache: 5 s edge.",
        "operationId": "trace",
        "parameters": [
          {
            "name": "hex",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ICAO 24-bit address, 6 hex chars. Case-insensitive.",
              "title": "Hex"
            },
            "description": "ICAO 24-bit address, 6 hex chars. Case-insensitive."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "hex": {
                      "type": "string"
                    },
                    "points": {
                      "type": "array",
                      "items": {
                        "type": "array",
                        "prefixItems": [
                          {
                            "type": "number",
                            "description": "Unix seconds UTC."
                          },
                          {
                            "type": "number",
                            "description": "Latitude, degrees."
                          },
                          {
                            "type": "number",
                            "description": "Longitude, degrees."
                          },
                          {
                            "description": "Barometric altitude, feet, \"ground\", or null.",
                            "oneOf": [
                              {
                                "type": "integer"
                              },
                              {
                                "const": "ground"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "Track, degrees true."
                          }
                        ]
                      },
                      "description": "[t, lat, lon, alt_baro, track], oldest first."
                    },
                    "departure": {
                      "description": "When and where this flight took off, from the day's trace: present when the network heard the take-off (from the ground or below 5,000 ft). Null when first heard aloft.",
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "at": {
                              "type": "number",
                              "description": "Unix seconds UTC."
                            },
                            "lat": {
                              "type": "number"
                            },
                            "lon": {
                              "type": "number"
                            },
                            "alt_ft": {
                              "type": "number"
                            }
                          }
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "arrival": {
                      "description": "When and where it landed, when the trace ends on the ground.",
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "at": {
                              "type": "number",
                              "description": "Unix seconds UTC."
                            },
                            "lat": {
                              "type": "number"
                            },
                            "lon": {
                              "type": "number"
                            }
                          }
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "hex",
                    "points"
                  ]
                },
                "example": {
                  "hex": "76cd06",
                  "points": [
                    [
                      1787924000.0,
                      1.48,
                      103.7,
                      6000,
                      84.0
                    ],
                    [
                      1787924061.0,
                      1.5,
                      103.8,
                      6325,
                      85.4
                    ]
                  ],
                  "departure": {
                    "at": 1787923500.0,
                    "lat": 1.36,
                    "lon": 103.99,
                    "alt_ft": 425
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "404": {
            "description": "Not found or not observed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "x-stability": "stable"
      }
    },
    "/v2/point/{lat}/{lon}/{radius}": {
      "get": {
        "tags": [
          "Live"
        ],
        "summary": "Point",
        "description": "Aircraft within radius nautical miles of a point, from the live snapshot. Radius is capped at 250. The common v2 envelope (ac, now, total) so ecosystem tooling can consume it unchanged; fields inside ac are the /v1/aircraft allowlist plus dst (distance, nm), nearest first. 503 if the snapshot is older than 60 seconds. Rate: 300 per 600 s (bucket `point`). Cache: 5 s edge.",
        "operationId": "point",
        "parameters": [
          {
            "name": "lat",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number",
              "description": "Latitude, degrees.",
              "title": "Lat"
            },
            "description": "Latitude, degrees."
          },
          {
            "name": "lon",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number",
              "description": "Longitude, degrees.",
              "title": "Lon"
            },
            "description": "Longitude, degrees."
          },
          {
            "name": "radius",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number",
              "description": "Radius in nautical miles. Capped at 250.",
              "title": "Radius"
            },
            "description": "Radius in nautical miles. Capped at 250."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ac": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "hex": {
                            "type": "string",
                            "description": "ICAO 24-bit address, lowercase hex."
                          },
                          "flight": {
                            "type": "string",
                            "description": "Callsign, trailing spaces stripped. Absent when not broadcast."
                          },
                          "t": {
                            "type": "string",
                            "description": "ICAO type designator."
                          },
                          "r": {
                            "type": "string",
                            "description": "Registration."
                          },
                          "lat": {
                            "type": "number",
                            "description": "WGS84 degrees."
                          },
                          "lon": {
                            "type": "number",
                            "description": "WGS84 degrees."
                          },
                          "alt_baro": {
                            "description": "Barometric altitude, feet, or the string \"ground\".",
                            "oneOf": [
                              {
                                "type": "integer"
                              },
                              {
                                "const": "ground"
                              }
                            ]
                          },
                          "gs": {
                            "type": "number",
                            "description": "Ground speed, knots."
                          },
                          "track": {
                            "type": "number",
                            "description": "Track, degrees true."
                          },
                          "category": {
                            "type": "string",
                            "description": "ADS-B emitter category (A0-D7)."
                          },
                          "squawk": {
                            "type": "string",
                            "description": "Transponder code, 4 octal digits."
                          },
                          "seen": {
                            "type": "number",
                            "description": "Seconds since the last message."
                          },
                          "seen_pos": {
                            "type": "number",
                            "description": "Seconds since the last position."
                          },
                          "baro_rate": {
                            "type": "integer",
                            "description": "Vertical rate, feet per minute, positive climbing."
                          },
                          "emergency": {
                            "type": "string",
                            "description": "Transponder emergency state: none, general, lifeguard, minfuel, nordo, unlawful, downed, reserved."
                          },
                          "dst": {
                            "type": "number",
                            "description": "Distance from the query point, nautical miles."
                          }
                        },
                        "required": [
                          "hex",
                          "dst"
                        ],
                        "description": "readsb passthrough fields plus dst (distance, nm)."
                      },
                      "description": "Snapshot aircraft within the radius, nearest first."
                    },
                    "msg": {
                      "type": "string",
                      "description": "Always \"No error\" on 200."
                    },
                    "now": {
                      "type": "number",
                      "description": "Snapshot time, unix seconds UTC."
                    },
                    "total": {
                      "type": "integer"
                    },
                    "ctime": {
                      "type": "number",
                      "description": "Same as now; envelope compatibility."
                    },
                    "ptime": {
                      "type": "number",
                      "description": "Processing time, ms."
                    }
                  },
                  "required": [
                    "ac",
                    "msg",
                    "now",
                    "total",
                    "ctime",
                    "ptime"
                  ]
                },
                "example": {
                  "ac": [
                    {
                      "hex": "76cd06",
                      "flight": "SIA123",
                      "t": "A359",
                      "lat": 1.5,
                      "lon": 103.8,
                      "alt_baro": 6325,
                      "gs": 285.9,
                      "track": 85.4,
                      "seen": 0.2,
                      "seen_pos": 1.1,
                      "dst": 9.4
                    }
                  ],
                  "msg": "No error",
                  "now": 1787924061.0,
                  "total": 1,
                  "ctime": 1787924061.0,
                  "ptime": 0.4
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "422": {
            "description": "Malformed input.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "503": {
            "description": "Live snapshot older than 60 seconds (stale_snapshot) or a required history artifact is not loaded (artifact_unavailable). Retry-After is set.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          }
        },
        "x-stability": "stable"
      }
    },
    "/v1/airframes/{hex}": {
      "get": {
        "tags": [
          "History",
          "History"
        ],
        "summary": "Airframe",
        "description": "One aircraft: registry identity and the observed flight log, newest first. legs is null when the log artifact is not loaded, empty when the aircraft was not seen in the window. Observation, not a registry of record. 404 if nothing is known. Rate: 300 per 600 s (bucket `airframe`). Cache: 1 h edge.",
        "operationId": "airframe",
        "parameters": [
          {
            "name": "hex",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ICAO 24-bit address, 6 hex chars. Case-insensitive.",
              "title": "Hex"
            },
            "description": "ICAO 24-bit address, 6 hex chars. Case-insensitive."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "hex": {
                      "type": "string"
                    },
                    "reg": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Registration."
                    },
                    "type": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "ICAO type designator."
                    },
                    "type_name": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "category": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Type category (narrow, wide, ...)."
                    },
                    "operator": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Operator name."
                    },
                    "operator_icao": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Observed operator: majority callsign prefix."
                    },
                    "year": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Build year."
                    },
                    "country": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "State of registration, ISO 3166-1 alpha-2, from the ICAO address block the hex belongs to. Null for unallocated and ICAO blocks."
                    },
                    "source": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Registry row provenance."
                    },
                    "airline": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "description": "Operator airline when resolved."
                    },
                    "legs": {
                      "description": "Observed legs, newest first, up to 200 (the most recent when an airframe has more). Empty array = not seen in the window; null = the log artifact is not loaded.",
                      "oneOf": [
                        {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "date": {
                                "type": "string",
                                "description": "YYYY-MM-DD, UTC."
                              },
                              "org": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Origin, IATA."
                              },
                              "dst": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Destination, IATA."
                              },
                              "dep_ts": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "description": "First-seen time, unix seconds UTC."
                              },
                              "arr_ts": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "description": "Last-seen time, unix seconds UTC."
                              },
                              "max_alt": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "description": "Max observed barometric altitude, feet."
                              },
                              "callsign": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            }
                          }
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "window_days": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Days of history the log covers. Null when the log artifact is not loaded."
                    },
                    "coverage": {
                      "type": "string",
                      "description": "Always \"observed\": evidence from our receivers and open trace archives, never a published schedule or registry.",
                      "const": "observed"
                    },
                    "history": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "description": "The lifetime record behind this hex: airframe_id, msn, built_year, manufacturer, registry (what a registry states, newest per field: model, engine, certificate_date, airworthiness_date, registry_status, owner, registration, source; null without one), first_observed, last_observed, and dated spells (hexes, registrations, operators; each with from, to, legs, source) plus public events, newest first (kind, at, lat, lon, detail, source). Observed spells and events come from the network's own evidence and say what it saw: first_observed is when the network first heard the airframe, not a delivery; not_observed is our silence, not storage. Null when no record exists."
                    }
                  },
                  "required": [
                    "hex",
                    "legs",
                    "window_days",
                    "coverage"
                  ]
                },
                "example": {
                  "hex": "76cd06",
                  "reg": "9V-SHF",
                  "type": "A359",
                  "type_name": "Airbus A350-900",
                  "category": "wide",
                  "operator": "Singapore Airlines",
                  "operator_icao": "SIA",
                  "year": 2019,
                  "country": "SG",
                  "source": "tar1090",
                  "airline": {
                    "icao": "SIA",
                    "iata": "SQ",
                    "name": "Singapore Airlines",
                    "palette": [
                      "#1D4886",
                      "#FCB130"
                    ],
                    "alliances": []
                  },
                  "legs": [
                    {
                      "date": "2026-08-27",
                      "org": "SIN",
                      "dst": "LHR",
                      "dep_ts": 1787800000,
                      "arr_ts": 1787845000,
                      "max_alt": 41000,
                      "callsign": "SQ322"
                    }
                  ],
                  "window_days": 60,
                  "coverage": "observed",
                  "history": {
                    "airframe_id": 4211,
                    "first_observed": "2025-08-28",
                    "last_observed": "2026-09-21",
                    "hexes": [
                      {
                        "hex": "76cd06",
                        "from": "2025-08-28",
                        "to": "2026-09-21",
                        "legs": 812,
                        "source": "observed"
                      }
                    ],
                    "registrations": [
                      {
                        "reg": "9V-SHF",
                        "from": "2025-08-28",
                        "to": "2026-09-21",
                        "legs": 812,
                        "source": "observed"
                      }
                    ],
                    "operators": [
                      {
                        "icao": "SIA",
                        "name": "Singapore Airlines",
                        "from": "2025-08-28",
                        "to": "2026-09-21",
                        "legs": 809,
                        "source": "observed"
                      }
                    ],
                    "events": [
                      {
                        "kind": "not_observed",
                        "at": "2026-02-03T00:00:00+00:00",
                        "detail": {
                          "last_seen": "2026-02-02",
                          "seen_again": "2026-03-10",
                          "days": 35
                        },
                        "source": "observed"
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "404": {
            "description": "Not found or not observed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Malformed input.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "503": {
            "description": "Live snapshot older than 60 seconds (stale_snapshot) or a required history artifact is not loaded (artifact_unavailable). Retry-After is set.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          }
        },
        "x-stability": "stable"
      }
    },
    "/v1/routes": {
      "get": {
        "tags": [
          "History",
          "History"
        ],
        "summary": "Routes, bulk",
        "description": "Derived routes for the callsigns of a list on screen, up to 80 in one call: observed routes first, the community catalog where they are silent. Null for a callsign never observed. Rate: 120 per 600 s (bucket `routes`). Cache: 1 h edge.",
        "operationId": "routes_bulk",
        "parameters": [
          {
            "name": "cs",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 1100,
              "description": "Comma-separated callsigns, up to 80.",
              "title": "Cs"
            },
            "description": "Comma-separated callsigns, up to 80."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "routes": {
                      "description": "Callsign (upper case) to [origin, ...via, destination] IATA, or null when unknown. Every requested callsign is a key.",
                      "type": "object",
                      "additionalProperties": {
                        "oneOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    }
                  }
                },
                "example": {
                  "routes": {
                    "SQ322": [
                      "SIN",
                      "LHR"
                    ],
                    "BAW9": [
                      "LHR",
                      "SIN"
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "422": {
            "description": "Malformed input.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "503": {
            "description": "Live snapshot older than 60 seconds (stale_snapshot) or a required history artifact is not loaded (artifact_unavailable). Retry-After is set.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          }
        },
        "x-stability": "stable"
      }
    },
    "/v1/flights/{callsign}": {
      "get": {
        "tags": [
          "History",
          "History"
        ],
        "summary": "Flight",
        "description": "One flight number: derived route, observed legs with typical local times, the airframes that fly it, recent operations. Sections fed by an unloaded artifact are null. Observation, not a published schedule. 404 if never observed. Rate: 120 per 600 s (bucket `flight`). Cache: 1 h edge.",
        "operationId": "flight",
        "parameters": [
          {
            "name": "callsign",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Callsign or flight ident, 2-12 alphanumerics.",
              "title": "Callsign"
            },
            "description": "Callsign or flight ident, 2-12 alphanumerics."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "callsign": {
                      "type": "string",
                      "description": "The operating callsign the record is for."
                    },
                    "marketed": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "The marketed number the request used when it differed (BA272 for BAW272)."
                    },
                    "route": {
                      "description": "[origin, ...via, destination], IATA, from the derived routes artifact, else from the community catalog. Null when unknown or the artifact is not loaded.",
                      "oneOf": [
                        {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "route_source": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "observed, observed+catalog, or catalog. Null when route is null."
                    },
                    "legs": {
                      "description": "Observed legs, busiest first (top 10), with typical local times when the inferred timetable knows them. Null = log artifact not loaded.",
                      "oneOf": [
                        {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "org": {
                                "type": "string"
                              },
                              "dst": {
                                "type": "string"
                              },
                              "flights": {
                                "type": "integer",
                                "description": "Observed count."
                              },
                              "days": {
                                "type": "integer",
                                "description": "Distinct days observed."
                              },
                              "last": {
                                "type": "string",
                                "description": "Last date observed, YYYY-MM-DD."
                              },
                              "dep": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Typical departure, HH:MM local at origin."
                              },
                              "arr": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Typical arrival, HH:MM local at destination."
                              },
                              "type": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Dominant type."
                              },
                              "times": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Where dep/arr come from: observed (inferred from what flew), published (an airport's board), or both."
                              },
                              "flight": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "The marketed flight number when a board named it (e.g. LH996 for callsign DLH8AE)."
                              },
                              "weekdays": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "day": {
                                      "type": "string",
                                      "description": "Mon, Tue, Wed, Thu, Fri, Sat or Sun."
                                    },
                                    "dep": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "HH:MM, local at origin."
                                    },
                                    "arr": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "HH:MM, local at destination."
                                    }
                                  }
                                },
                                "description": "Present only when the flight keeps another slot altogether (more than 30 minutes from dep) on some weekdays, read on the origin's calendar: those days' own times, Monday first."
                              }
                            }
                          }
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "aircraft": {
                      "description": "Airframes flying it, busiest first (top 8). Null = log artifact not loaded.",
                      "oneOf": [
                        {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "hex": {
                                "type": "string"
                              },
                              "reg": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "type": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "flights": {
                                "type": "integer"
                              }
                            }
                          }
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "recent": {
                      "description": "Latest operations, newest first (up to 10). Null = log artifact not loaded.",
                      "oneOf": [
                        {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "date": {
                                "type": "string"
                              },
                              "org": {
                                "type": "string"
                              },
                              "dst": {
                                "type": "string"
                              },
                              "dep_ts": {
                                "type": [
                                  "integer",
                                  "null"
                                ]
                              },
                              "arr_ts": {
                                "type": [
                                  "integer",
                                  "null"
                                ]
                              }
                            }
                          }
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "window_days": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Days of history the log covers. Null when the log artifact is not loaded."
                    },
                    "coverage": {
                      "type": "string",
                      "description": "Always \"observed\": evidence from our receivers and open trace archives, never a published schedule or registry.",
                      "const": "observed"
                    }
                  },
                  "required": [
                    "callsign",
                    "route",
                    "legs",
                    "aircraft",
                    "recent",
                    "window_days",
                    "coverage"
                  ]
                },
                "example": {
                  "callsign": "SQ322",
                  "route": [
                    "SIN",
                    "LHR"
                  ],
                  "route_source": "observed",
                  "legs": [
                    {
                      "org": "SIN",
                      "dst": "LHR",
                      "flights": 12,
                      "days": 7,
                      "last": "2026-08-27",
                      "dep": "09:00",
                      "arr": "15:10",
                      "type": "A359"
                    }
                  ],
                  "aircraft": [
                    {
                      "hex": "76cd06",
                      "reg": "9V-SHF",
                      "type": "A359",
                      "flights": 8
                    }
                  ],
                  "recent": [
                    {
                      "date": "2026-08-27",
                      "org": "SIN",
                      "dst": "LHR",
                      "dep_ts": 1787800000,
                      "arr_ts": 1787845000
                    }
                  ],
                  "window_days": 60,
                  "coverage": "observed"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "404": {
            "description": "Not found or not observed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Malformed input.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "503": {
            "description": "Live snapshot older than 60 seconds (stale_snapshot) or a required history artifact is not loaded (artifact_unavailable). Retry-After is set.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          }
        },
        "x-stability": "stable"
      }
    },
    "/v1/airports/{code}": {
      "get": {
        "tags": [
          "History",
          "History"
        ],
        "summary": "Airport",
        "description": "One airport, IATA or ICAO code: registry identity, observed totals and busiest routes, and the inferred departures and arrivals boards in the airport's LOCAL time. Circuits excluded. observed is null when the log artifact is not loaded. 404 if unknown. Rate: 120 per 600 s (bucket `airport`). Cache: 1 h edge.",
        "operationId": "airport",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "IATA or ICAO airport code.",
              "title": "Code"
            },
            "description": "IATA or ICAO airport code."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "iata": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "ident": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "ICAO ident."
                    },
                    "name": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "kind": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "OurAirports kind (large_airport, ...)."
                    },
                    "role": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "commercial, general, military, or closed."
                    },
                    "lat": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "lon": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "iso_country": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "municipality": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "tz": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Olson timezone."
                    },
                    "observed": {
                      "description": "Totals from the flight log. Null = log artifact not loaded. Circuits excluded.",
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "departures": {
                              "type": "integer"
                            },
                            "destinations": {
                              "type": "integer"
                            },
                            "tails": {
                              "type": "integer",
                              "description": "Distinct airframes."
                            },
                            "days_observed": {
                              "type": "integer"
                            },
                            "routes": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "dst": {
                                    "type": "string",
                                    "description": "Destination, IATA."
                                  },
                                  "flights": {
                                    "type": "integer"
                                  },
                                  "days": {
                                    "type": "integer"
                                  }
                                }
                              },
                              "description": "Busiest routes, top 15."
                            }
                          }
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "today": {
                      "description": "Today's board as the airport publishes it, in the airport's local day. Null when no published board is held for it.",
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "day": {
                              "type": "string",
                              "description": "YYYY-MM-DD, local."
                            },
                            "source": {
                              "type": "string",
                              "description": "published"
                            },
                            "departures": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "flight": {
                                    "type": "string",
                                    "description": "Marketed number."
                                  },
                                  "dst": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "dep": {
                                    "type": "string",
                                    "description": "HH:MM, local."
                                  },
                                  "callsign": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "The observed service that carries the number, when known."
                                  },
                                  "type": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  }
                                }
                              }
                            },
                            "arrivals": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "flight": {
                                    "type": "string",
                                    "description": "Marketed number."
                                  },
                                  "org": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "arr": {
                                    "type": "string",
                                    "description": "HH:MM, local."
                                  },
                                  "callsign": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "type": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  }
                                }
                              }
                            }
                          }
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "board": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "flight": {
                            "type": "string",
                            "description": "Marketed number when known, else the callsign."
                          },
                          "dst": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "dep": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "HH:MM, local."
                          },
                          "arr": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "HH:MM, local at destination."
                          },
                          "type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "flights": {
                            "type": "integer",
                            "description": "Observation count behind the row."
                          },
                          "source": {
                            "type": "string",
                            "description": "Provenance of THIS row: observed (from receivers), published (from a timetable), or both. Unlike the observed stats, a published row is not a receiver observation."
                          },
                          "weekdays": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "day": {
                                  "type": "string",
                                  "description": "Mon, Tue, Wed, Thu, Fri, Sat or Sun."
                                },
                                "dep": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "HH:MM, local at origin."
                                },
                                "arr": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "HH:MM, local at destination."
                                }
                              }
                            },
                            "description": "Present only when the flight keeps another slot altogether (more than 30 minutes from dep) on some weekdays, read on the origin's calendar: those days' own times, Monday first."
                          }
                        }
                      },
                      "description": "Inferred typical departures, local time, dep-sorted. Rows are a mix of observation and published timetable data; check each row's source."
                    },
                    "arrivals": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "flight": {
                            "type": "string",
                            "description": "Marketed number when known, else the callsign."
                          },
                          "org": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Origin, IATA."
                          },
                          "dep": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "HH:MM, local at origin."
                          },
                          "arr": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "HH:MM, local at this airport."
                          },
                          "type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "flights": {
                            "type": "integer",
                            "description": "Observation count behind the row."
                          },
                          "source": {
                            "type": "string",
                            "description": "observed, published, or both."
                          },
                          "weekdays": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "day": {
                                  "type": "string",
                                  "description": "Mon, Tue, Wed, Thu, Fri, Sat or Sun."
                                },
                                "dep": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "HH:MM, local at origin."
                                },
                                "arr": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "HH:MM, local at destination."
                                }
                              }
                            },
                            "description": "Present only when the flight keeps another slot altogether (more than 30 minutes from dep) on some weekdays, read on the origin's calendar: those days' own times, Monday first."
                          }
                        }
                      },
                      "description": "Inferred typical arrivals, this airport's local time, arr-sorted. Same provenance rules as board."
                    },
                    "airlines": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "icao": {
                            "type": "string"
                          },
                          "flights": {
                            "type": "integer"
                          }
                        }
                      },
                      "description": "Busiest airlines on the board, top 20."
                    },
                    "times": {
                      "type": "string",
                      "const": "local"
                    },
                    "window_days": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Days of history the log covers. Null when the log artifact is not loaded."
                    },
                    "coverage": {
                      "type": "string",
                      "description": "Always \"observed\": evidence from our receivers and open trace archives, never a published schedule or registry.",
                      "const": "observed"
                    }
                  },
                  "required": [
                    "iata",
                    "ident",
                    "observed",
                    "board",
                    "arrivals",
                    "airlines",
                    "times",
                    "window_days",
                    "coverage"
                  ]
                },
                "example": {
                  "iata": "SIN",
                  "ident": "WSSS",
                  "name": "Singapore Changi",
                  "kind": "large_airport",
                  "lat": 1.35019,
                  "lon": 103.994,
                  "iso_country": "SG",
                  "municipality": "Singapore",
                  "tz": "Asia/Singapore",
                  "observed": {
                    "departures": 120,
                    "destinations": 40,
                    "tails": 80,
                    "days_observed": 60,
                    "routes": [
                      {
                        "dst": "LHR",
                        "flights": 14,
                        "days": 7
                      }
                    ]
                  },
                  "today": {
                    "day": "2026-09-23",
                    "source": "published",
                    "departures": [
                      {
                        "flight": "SQ322",
                        "dst": "LHR",
                        "dep": "09:00",
                        "callsign": "SIA322",
                        "type": "A359"
                      }
                    ],
                    "arrivals": [
                      {
                        "flight": "SQ317",
                        "org": "LHR",
                        "arr": "06:55",
                        "callsign": "SIA317",
                        "type": "A359"
                      }
                    ]
                  },
                  "board": [
                    {
                      "flight": "SQ322",
                      "dst": "LHR",
                      "dep": "09:00",
                      "arr": "15:10",
                      "type": "A359",
                      "flights": 12,
                      "source": "observed"
                    }
                  ],
                  "arrivals": [
                    {
                      "flight": "SQ317",
                      "org": "LHR",
                      "dep": "11:00",
                      "arr": "06:55",
                      "type": "A359",
                      "flights": 11,
                      "source": "observed"
                    }
                  ],
                  "airlines": [
                    {
                      "icao": "SIA",
                      "flights": 90
                    }
                  ],
                  "times": "local",
                  "window_days": 60,
                  "coverage": "observed"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "404": {
            "description": "Not found or not observed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Malformed input.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "503": {
            "description": "Live snapshot older than 60 seconds (stale_snapshot) or a required history artifact is not loaded (artifact_unavailable). Retry-After is set.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          }
        },
        "x-stability": "stable"
      }
    },
    "/v1/stations": {
      "get": {
        "tags": [
          "Stations"
        ],
        "summary": "Roster",
        "description": "Public feeder list. Locations rounded to about 11 km. IPs are not stored. Rate: 120 per 600 s (bucket `stations`). Cache: 30 s edge.",
        "operationId": "stations",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "stations": {
                      "items": {
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "Public id, fp-<10 hex>. Reveals no UUID bits."
                          },
                          "label": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Operator-set display label."
                          },
                          "coarse_lat": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "Coverage midpoint, rounded ~11 km."
                          },
                          "coarse_lon": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "first_seen": {
                            "type": "string",
                            "description": "ISO 8601 UTC."
                          },
                          "last_seen": {
                            "type": "string",
                            "description": "ISO 8601 UTC."
                          },
                          "online": {
                            "type": "boolean"
                          }
                        },
                        "type": "object",
                        "required": [
                          "id",
                          "first_seen",
                          "last_seen",
                          "online"
                        ]
                      },
                      "type": "array"
                    }
                  },
                  "type": "object",
                  "required": [
                    "stations"
                  ]
                },
                "example": {
                  "stations": [
                    {
                      "id": "fp-a1b2c3d4e5",
                      "coarse_lat": 1.4,
                      "coarse_lon": 103.8,
                      "first_seen": "2026-08-01T00:00:00+00:00",
                      "last_seen": "2026-08-29T12:00:00+00:00",
                      "online": true
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "type": "object",
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          }
        },
        "x-stability": "stable"
      }
    },
    "/v1/stations/{station_uuid}": {
      "get": {
        "tags": [
          "Stations"
        ],
        "summary": "Station",
        "description": "Status for one feeder. The full UUID is the key; the server stores a hash. Unknown and malformed UUIDs both return 404. The UUID travels in the URL: treat the link as the secret it carries. Rate: 60 per 600 s (bucket `station_detail`). Never cached.",
        "operationId": "station",
        "parameters": [
          {
            "name": "station_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Full feeder UUID. The server stores a hash, not the UUID.",
              "title": "Station Uuid"
            },
            "description": "Full feeder UUID. The server stores a hash, not the UUID."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "online": {
                      "type": "boolean"
                    },
                    "connected_since": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "ISO 8601 UTC. Null when offline."
                    },
                    "messages_per_s": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "positions_per_s": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "kbit_s": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "rtt_ms": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "positions_total": {
                      "type": "integer"
                    },
                    "aircraft_seen": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Aircraft this station sees right now. Null when unavailable."
                    },
                    "first_seen": {
                      "type": "string"
                    },
                    "last_seen": {
                      "type": "string"
                    },
                    "recent_sessions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "started_at": {
                            "type": "string"
                          },
                          "ended_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Null while open."
                          },
                          "peak_messages_per_s": {
                            "type": "number"
                          },
                          "positions_total": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "id",
                    "online",
                    "positions_total",
                    "first_seen",
                    "last_seen",
                    "recent_sessions"
                  ]
                },
                "example": {
                  "id": "fp-a1b2c3d4e5",
                  "online": true,
                  "messages_per_s": 0.426,
                  "positions_per_s": 0.109,
                  "kbit_s": 0.09,
                  "rtt_ms": 16,
                  "positions_total": 204,
                  "aircraft_seen": 3,
                  "first_seen": "2026-08-01T00:00:00+00:00",
                  "last_seen": "2026-08-29T12:00:00+00:00",
                  "recent_sessions": [
                    {
                      "started_at": "2026-08-29T00:00:00+00:00",
                      "peak_messages_per_s": 0.5,
                      "positions_total": 204
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "404": {
            "description": "Not found or not observed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "x-stability": "stable"
      }
    },
    "/v1/me": {
      "get": {
        "tags": [
          "Stations"
        ],
        "summary": "Am I feeding",
        "description": "Whether a station is connected from the address asking, and which. The address is matched in memory against the current connections by a salted hash and never stored. A browser on IPv6 and a feeder on IPv4 do not match; the station key (`/v1/stations/{station_uuid}`) is the exact check.\n\nRate: 60 per 600 s (bucket `station_detail`). Never cached. Stability: candidate for the stable tier.",
        "operationId": "me",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "feeding": true,
                  "stations": [
                    {
                      "id": "fp-a1b2c3d4e5",
                      "connected_since": "2026-10-09T08:12:40.118202+00:00",
                      "messages_per_s": 412.6,
                      "positions_per_s": 96.3
                    }
                  ]
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "feeding": {
                      "type": "boolean",
                      "description": "True when a station is connected from the address asking."
                    },
                    "stations": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "Public id, fp-<10 hex>."
                          },
                          "connected_since": {
                            "type": "string",
                            "description": "ISO 8601 UTC."
                          },
                          "messages_per_s": {
                            "type": "number"
                          },
                          "positions_per_s": {
                            "type": "number"
                          }
                        },
                        "required": [
                          "id",
                          "connected_since"
                        ]
                      }
                    }
                  },
                  "required": [
                    "feeding",
                    "stations"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          }
        },
        "x-stability": "candidate"
      }
    },
    "/v1/setup/beacon": {
      "get": {
        "tags": [
          "Stations"
        ],
        "summary": "Stations waiting on my network",
        "description": "The Stations waiting for setup on the caller's own network (the same public address), newest first, each with the address of its setup page. Empty when there are none. Rate: 120 per 600 s (bucket `beacon_find`). Never cached.",
        "operationId": "setup_beacon_get",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {},
                "example": {
                  "stations": [
                    {
                      "url": "http://192.168.1.23:8654/",
                      "name": "station",
                      "seen_s": 12
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "type": "object",
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          }
        },
        "x-stability": "map"
      },
      "post": {
        "tags": [
          "Stations"
        ],
        "summary": "Station waiting for setup",
        "description": "Sent by a Station that has not been set up yet: its address on the home network, so the join page on a phone on that network can open its setup page. Held in memory for 10 minutes under a hash of the caller's public address; never stored. Only private IPv4 addresses are accepted. Rate: 30 per 600 s (bucket `beacon`).",
        "operationId": "setup_beacon_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Beacon"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "type": "object",
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "422": {
            "description": "Malformed input.",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "type": "object",
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          }
        },
        "x-stability": "map"
      }
    },
    "/v1/airlines": {
      "get": {
        "tags": [
          "Reference"
        ],
        "summary": "Airlines",
        "description": "Airlines in the reference tables, with observed route and country counts so a consumer can rank and filter in one request. Rate: 300 per 600 s (bucket `refdata`). Cache: 1 h edge.",
        "operationId": "airlines",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "airlines": {
                      "items": {
                        "properties": {
                          "icao": {
                            "type": "string"
                          },
                          "iata": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "name": {
                            "type": "string"
                          },
                          "palette": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array",
                            "description": "Brand hexes, primary first."
                          },
                          "alliances": {
                            "items": {
                              "type": "object"
                            },
                            "type": "array",
                            "description": "Sourced memberships."
                          },
                          "n_routes": {
                            "type": "integer",
                            "description": "Observed routes. A lower bound."
                          },
                          "n_countries": {
                            "type": "integer",
                            "description": "Countries those routes touch."
                          }
                        },
                        "type": "object",
                        "required": [
                          "icao",
                          "name",
                          "palette",
                          "alliances"
                        ]
                      },
                      "type": "array"
                    }
                  },
                  "type": "object",
                  "required": [
                    "airlines"
                  ]
                },
                "example": {
                  "airlines": [
                    {
                      "icao": "SIA",
                      "iata": "SQ",
                      "name": "Singapore Airlines",
                      "palette": [
                        "#1D4886",
                        "#FCB130"
                      ],
                      "alliances": [],
                      "n_routes": 40,
                      "n_countries": 32
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "type": "object",
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          }
        },
        "x-stability": "stable"
      }
    },
    "/v1/airlines/{icao}": {
      "get": {
        "tags": [
          "Reference"
        ],
        "summary": "Airline",
        "description": "One airline. n_routes is an observed lower bound. Rate: 300 per 600 s (bucket `refdata`). Cache: 1 h edge.",
        "operationId": "airline",
        "parameters": [
          {
            "name": "icao",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Airline ICAO code.",
              "title": "Icao"
            },
            "description": "Airline ICAO code."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "icao": {
                      "type": "string"
                    },
                    "iata": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "name": {
                      "type": "string"
                    },
                    "palette": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Brand hexes, primary first."
                    },
                    "alliances": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      },
                      "description": "Sourced memberships."
                    },
                    "n_routes": {
                      "type": "integer",
                      "description": "Observed routes. A lower bound."
                    },
                    "n_countries": {
                      "type": "integer",
                      "description": "Countries those routes touch."
                    }
                  },
                  "required": [
                    "icao",
                    "name",
                    "palette",
                    "alliances"
                  ]
                },
                "example": {
                  "icao": "SIA",
                  "iata": "SQ",
                  "name": "Singapore Airlines",
                  "palette": [
                    "#1D4886",
                    "#FCB130"
                  ],
                  "alliances": [],
                  "n_routes": 40
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "404": {
            "description": "Not found or not observed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "x-stability": "stable"
      }
    },
    "/v1/alliances": {
      "get": {
        "tags": [
          "Reference"
        ],
        "summary": "Alliances",
        "description": "Global alliances and how much of each we have observed. Member counts are official. Route, flight, and airframe counts are observed lower bounds. Rate: 300 per 600 s (bucket `refdata`). Cache: 1 h edge.",
        "operationId": "alliances",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {},
                "example": {
                  "alliances": [
                    {
                      "slug": "star-alliance",
                      "name": "Star Alliance",
                      "website_url": "https://www.staralliance.com",
                      "source_url": "https://www.staralliance.com/members",
                      "source_checked_at": "2026-08-29",
                      "n_members": 25,
                      "n_members_observed": 20,
                      "n_airlines": 26,
                      "n_routes": 4200,
                      "n_legs": 3100,
                      "n_flights": 90000,
                      "n_countries": 120,
                      "n_airframes": 2400
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "type": "object",
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          }
        },
        "x-stability": "map"
      }
    },
    "/v1/alliances/{slug}": {
      "get": {
        "tags": [
          "Reference"
        ],
        "summary": "Alliance",
        "description": "One alliance: sourced memberships and observed coverage. Rate: 300 per 600 s (bucket `refdata`). Cache: 1 h edge.",
        "operationId": "alliance",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Alliance slug, for example star-alliance.",
              "title": "Slug"
            },
            "description": "Alliance slug, for example star-alliance."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "404": {
            "description": "Not found or not observed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "x-stability": "map"
      }
    },
    "/v1/alliances/{slug}/routes": {
      "get": {
        "tags": [
          "Reference"
        ],
        "summary": "Alliance routes",
        "description": "Observed legs across current member brands, undirected (org/dst in canonical alphabetical order). Rate: 300 per 600 s (bucket `refdata`). Cache: 1 h edge.",
        "operationId": "alliance_routes",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Alliance slug, for example star-alliance.",
              "title": "Slug"
            },
            "description": "Alliance slug, for example star-alliance."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "404": {
            "description": "Not found or not observed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "x-stability": "map"
      }
    },
    "/v1/airlines/{icao}/routes": {
      "get": {
        "tags": [
          "Reference"
        ],
        "summary": "Airline routes",
        "description": "Observed legs and the airports they touch, undirected (org/dst in canonical alphabetical order). Prefers flight-log frequencies; falls back to route chains when the log has no rows. n is the evidence count, a lower bound. Rate: 300 per 600 s (bucket `refdata`). Cache: 1 h edge.",
        "operationId": "airline_routes",
        "parameters": [
          {
            "name": "icao",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Airline ICAO code.",
              "title": "Icao"
            },
            "description": "Airline ICAO code."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {},
                "example": {
                  "icao": "SIA",
                  "source": "flightlog",
                  "airports": {
                    "SIN": {
                      "lat": 1.35019,
                      "lon": 103.994,
                      "name": "Singapore Changi",
                      "iso_country": "SG",
                      "tz": "Asia/Singapore"
                    }
                  },
                  "legs": [
                    {
                      "org": "SIN",
                      "dst": "SYD",
                      "n": 7,
                      "days": 7,
                      "per_week": 7.0,
                      "avg_min": 472,
                      "aircraft": [
                        {
                          "type": "A388",
                          "name": "Airbus A380-800",
                          "n": 4
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "404": {
            "description": "Not found or not observed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "x-stability": "map"
      }
    },
    "/v1/airlines/{icao}/leg/{org}/{dst}": {
      "get": {
        "tags": [
          "Reference"
        ],
        "summary": "Airline leg",
        "description": "Airframes seen on one undirected airport pair, most frequent first. Endpoints can be in either order. Rate: 300 per 600 s (bucket `refdata`). Cache: 1 h edge.",
        "operationId": "airline_leg",
        "parameters": [
          {
            "name": "icao",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Airline ICAO code.",
              "title": "Icao"
            },
            "description": "Airline ICAO code."
          },
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Airport code (IATA). The pair is undirected; order does not matter.",
              "title": "Org"
            },
            "description": "Airport code (IATA). The pair is undirected; order does not matter."
          },
          {
            "name": "dst",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Airport code (IATA). The pair is undirected; order does not matter.",
              "title": "Dst"
            },
            "description": "Airport code (IATA). The pair is undirected; order does not matter."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {},
                "example": {
                  "icao": "SIA",
                  "org": "SIN",
                  "dst": "SYD",
                  "flights": 7,
                  "days": 7,
                  "airframes": [
                    {
                      "hex": "76cd01",
                      "reg": "9V-SHA",
                      "type": "A359",
                      "flights": 7
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "404": {
            "description": "Not found or not observed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "x-stability": "map"
      }
    },
    "/v1/airlines/{icao}/schedule/{org}/{dst}": {
      "get": {
        "tags": [
          "Reference"
        ],
        "summary": "Airline schedule",
        "description": "Inferred timetable for a route, both directions. Times are HH:MM local at each row's origin; `weekdays`, when present, lists the days a flight keeps another slot. Observation, not a published schedule. Rate: 300 per 600 s (bucket `refdata`). Cache: 1 h edge.",
        "operationId": "airline_schedule",
        "parameters": [
          {
            "name": "icao",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Airline ICAO code.",
              "title": "Icao"
            },
            "description": "Airline ICAO code."
          },
          {
            "name": "org",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Airport code (IATA). The pair is undirected; order does not matter.",
              "title": "Org"
            },
            "description": "Airport code (IATA). The pair is undirected; order does not matter."
          },
          {
            "name": "dst",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Airport code (IATA). The pair is undirected; order does not matter.",
              "title": "Dst"
            },
            "description": "Airport code (IATA). The pair is undirected; order does not matter."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {},
                "example": {
                  "icao": "SIA",
                  "org": "SIN",
                  "dst": "SYD",
                  "departures": [
                    {
                      "callsign": "SIA322",
                      "flight": "SQ322",
                      "source": "observed",
                      "org": "SIN",
                      "dst": "SYD",
                      "dep": "09:30",
                      "dep_min": 570,
                      "arr": "18:40",
                      "arr_min": 1120,
                      "type": "A359",
                      "type_name": "Airbus A350-900",
                      "n_flights": 30
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "404": {
            "description": "Not found or not observed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "x-stability": "map"
      }
    },
    "/v1/airlines/{icao}/countries": {
      "get": {
        "tags": [
          "Reference"
        ],
        "summary": "Airline countries",
        "description": "Countries this airline's observed routes touch. n_routes is the evidence count, so a consumer can threshold thin coverage. Rate: 300 per 600 s (bucket `refdata`). Cache: 1 h edge.",
        "operationId": "airline_countries",
        "parameters": [
          {
            "name": "icao",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Airline ICAO code.",
              "title": "Icao"
            },
            "description": "Airline ICAO code."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {},
                "example": {
                  "icao": "SIA",
                  "countries": [
                    {
                      "iso_country": "SG",
                      "n_routes": 40
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "404": {
            "description": "Not found or not observed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "x-stability": "map"
      }
    },
    "/v1/airlines/{icao}/fleet/{designator}": {
      "get": {
        "tags": [
          "Reference"
        ],
        "summary": "Airline fleet type",
        "description": "Airframes of one type in an airline's observed fleet. Rate: 300 per 600 s (bucket `refdata`). Cache: 1 h edge.",
        "operationId": "airline_fleet_type",
        "parameters": [
          {
            "name": "icao",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Airline ICAO code.",
              "title": "Icao"
            },
            "description": "Airline ICAO code."
          },
          {
            "name": "designator",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ICAO type designator, for example A359.",
              "title": "Designator"
            },
            "description": "ICAO type designator, for example A359."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {},
                "example": {
                  "icao": "SIA",
                  "type": "A359",
                  "type_name": "Airbus A350-900",
                  "window_days": 400,
                  "airframes": [
                    {
                      "hex": "76cd01",
                      "reg": "9V-SHA",
                      "legs": 212,
                      "last_date": "2026-08-27",
                      "last_org": "SIN",
                      "last_dst": "LHR",
                      "where": "LHR",
                      "top_route": [
                        "SIN",
                        "LHR",
                        41
                      ]
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "404": {
            "description": "Not found or not observed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "x-stability": "map"
      }
    },
    "/v1/airlines/{icao}/airframes": {
      "get": {
        "tags": [
          "Reference"
        ],
        "summary": "Airline aircraft",
        "description": "The aircraft the network currently observes flying this airline's callsigns, from the airframe lifetime record: an airframe counts when its latest airline stint is this airline's and it was seen in the record's last 60 days. Per aircraft: hex, reg, type, country (address block), built_year (registry, else tar1090), msn, since (start of the stint; since_first_seen true when that is simply where the network's view of the airframe begins), last_seen, airlines (distinct airlines the record saw it fly for) and notable (public incident reports and squawks). Observation, not a published fleet list. Rate: 300 per 600 s (bucket `refdata`). Cache: 1 h edge.",
        "operationId": "airline_airframes",
        "parameters": [
          {
            "name": "icao",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Airline ICAO code.",
              "title": "Icao"
            },
            "description": "Airline ICAO code."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {},
                "example": {
                  "icao": "TVS",
                  "as_of": "2026-09-22",
                  "current_days": 60,
                  "airframes": [
                    {
                      "hex": "49d283",
                      "reg": "OK-TVY",
                      "type": "B738",
                      "country": "CZ",
                      "since": "2026-05-08",
                      "since_first_seen": false,
                      "last_seen": "2026-09-21",
                      "airlines": 3,
                      "notable": 0
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "404": {
            "description": "Not found or not observed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "x-stability": "map"
      }
    },
    "/v1/airlines/{icao}/fleet": {
      "get": {
        "tags": [
          "Reference"
        ],
        "summary": "Airline fleet",
        "description": "Observed fleet grouped by type. Not a published fleet list; n_airframes says how much evidence the answer is built from. Rate: 300 per 600 s (bucket `refdata`). Cache: 1 h edge.",
        "operationId": "airline_fleet",
        "parameters": [
          {
            "name": "icao",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Airline ICAO code.",
              "title": "Icao"
            },
            "description": "Airline ICAO code."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {},
                "example": {
                  "icao": "SIA",
                  "n_airframes": 3,
                  "fleet": [
                    {
                      "type": "A359",
                      "type_name": "Airbus A350-900",
                      "count": 2
                    }
                  ],
                  "unknown_type": 0
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "404": {
            "description": "Not found or not observed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "x-stability": "map"
      }
    },
    "/v1/types/{designator}": {
      "get": {
        "tags": [
          "Reference"
        ],
        "summary": "Type",
        "description": "ICAO type designator to name and category. Rate: 300 per 600 s (bucket `refdata`). Cache: 1 h edge.",
        "operationId": "aircraft_type",
        "parameters": [
          {
            "name": "designator",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ICAO type designator, for example A359.",
              "title": "Designator"
            },
            "description": "ICAO type designator, for example A359."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "designator": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "category": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "designator",
                    "name",
                    "category"
                  ]
                },
                "example": {
                  "designator": "A359",
                  "name": "Airbus A350-900",
                  "category": "wide"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "404": {
            "description": "Not found or not observed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "x-stability": "stable"
      }
    },
    "/v1/search": {
      "get": {
        "tags": [
          "Reference"
        ],
        "summary": "Search",
        "description": "One box over registrations, hexes, flight numbers (\"SQ322\", \"SQ 322\"), routes (two places: \"SIN LHR\", \"SIN-LHR\", \"Singapore to London\"), fleets (an operator and a type), airports and airlines; names compare without accents. One ranked list: exact codes, then prefixes, then word starts, then near misses (only when nothing matched a whole code or word), traffic as the tie-breaker. The canonical query is trimmed, one space between words, uppercase; any other spelling is answered 301 to it. Rate: 600 per 600 s (bucket `search`). Cache: 12 h edge.",
        "operationId": "search",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 40,
              "description": "What was typed.",
              "title": "Q"
            },
            "description": "What was typed."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "q": {
                      "type": "string",
                      "description": "The query as searched, trimmed and uppercased."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "kind": {
                            "type": "string",
                            "description": "aircraft, flight, airport or airline."
                          },
                          "id": {
                            "type": "string",
                            "description": "What to open: hex, callsign, airport code or airline ICAO."
                          },
                          "label": {
                            "type": "string",
                            "description": "The line to show."
                          },
                          "detail": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "A second line: type and operator, route count, city and country, IATA."
                          },
                          "score": {
                            "type": "number",
                            "description": "Rank: 100 an exact code, 60 a prefix, 40 a word start, 20 a near miss, plus a little for traffic. The list is sorted by it."
                          }
                        },
                        "required": [
                          "kind",
                          "id",
                          "label",
                          "detail",
                          "score"
                        ]
                      }
                    }
                  },
                  "required": [
                    "q",
                    "results"
                  ]
                },
                "example": {
                  "q": "9V-SH",
                  "results": [
                    {
                      "kind": "aircraft",
                      "id": "76cd01",
                      "label": "9V-SHA",
                      "detail": "Airbus A350-900 \u00b7 Singapore Airlines",
                      "score": 60
                    },
                    {
                      "kind": "aircraft",
                      "id": "76cd02",
                      "label": "9V-SHB",
                      "detail": "Airbus A350-900 \u00b7 Singapore Airlines",
                      "score": 60
                    }
                  ]
                }
              }
            }
          },
          "301": {
            "description": "The query in another spelling than its canonical one (trimmed, one space between words, uppercase): Location is this URL with q canonical, every other parameter kept. Cached like the answer.",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "example": "/v1/search?q=SQ%20322"
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "x-stability": "map"
      }
    },
    "/v2/search": {
      "get": {
        "tags": [
          "Reference"
        ],
        "summary": "Search (typed)",
        "description": "One box over flights, airlines, airports, airframes and aircraft types, read before it is searched: a flight number (\"SQ322\", \"SQ 322\", \"SIA322\"), a route in words where a city stands for all its airports (\"New York to London\", \"SIN-LHR\"), an airline and a place (\"Singapore Airlines London\") or a family (\"SQ 777\", \"BA A380\"), a city (\"Tokyo\": HND and NRT), a type (\"A380\", \"787\", \"Boeing 777\"), a registration however typed (\"9V SMA\", \"9VSMA\"), a hex, any code. Then names, accents and case aside, with the last word taken as still being typed; near misses (one edit for 4-5 letters, two from 6) only when nothing matched whole. Every result is typed (its fields depend on kind), with a stable id, the page to link, and flight times in local time with their zones.\n\nThe answer comes from a search index rebuilt nightly from the reference snapshot; `index` and `as_of` say which. `near` (a coarse position, rounded to 0.25\u00b0 before anything reads it; never stored or logged) may lift nearby airports.\n\nRate: 600 per 600 s (bucket `search_v2`). Cache: 12 h edge. Stability: candidate for the stable tier.",
        "operationId": "search_v2",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "What was typed, 1-40 characters (at least 2 after trimming).",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 40
            },
            "examples": {
              "flight": {
                "value": "SQ 322"
              },
              "route": {
                "value": "SINGAPORE TO LONDON"
              },
              "airline_place": {
                "value": "SINGAPORE AIRLINES LONDON"
              }
            }
          },
          {
            "name": "kinds",
            "in": "query",
            "required": false,
            "description": "Only these kinds, comma-separated: flight, airline, airport, aircraft, type. Default: all.",
            "schema": {
              "type": "string"
            },
            "example": "flight,airport"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "At most this many results, 1-50. Default 10.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 10
            }
          },
          {
            "name": "near",
            "in": "query",
            "required": false,
            "description": "lat,lon in degrees: a coarse position to rank by, rounded to 0.25\u00b0 (a spelling not rounded redirects to the rounded one).",
            "schema": {
              "type": "string"
            },
            "example": "1.25,103.75"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "q": {
                      "type": "string",
                      "description": "The query as searched: trimmed, one space between words, uppercase."
                    },
                    "intent": {
                      "description": "What the query was read as: the first reading that found something. kind is flight (a flight number), registration, route (two places), fleet (an airline and an aircraft family), airline_place (an airline and a place), type, city, code (a code of any kind, typed whole) or text (names only).",
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "flight",
                            "registration",
                            "route",
                            "fleet",
                            "airline_place",
                            "type",
                            "city",
                            "code",
                            "text"
                          ]
                        },
                        "number": {
                          "type": "string",
                          "description": "flight: the number as typed, compact."
                        },
                        "callsigns": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "flight: the callsigns and marketed numbers looked up."
                        },
                        "registration": {
                          "type": "string",
                          "description": "registration: the mark without spaces or dashes."
                        },
                        "from": {
                          "type": "object",
                          "properties": {
                            "text": {
                              "type": "string",
                              "description": "The words as read (folded)."
                            },
                            "airports": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "The airports they stand for, the main one first."
                            },
                            "how": {
                              "type": "string",
                              "description": "code (an airport code), city (a city: every airport serving it) or airport (an airport's name)."
                            }
                          },
                          "required": [
                            "text",
                            "airports",
                            "how"
                          ]
                        },
                        "to": {
                          "type": "object",
                          "properties": {
                            "text": {
                              "type": "string",
                              "description": "The words as read (folded)."
                            },
                            "airports": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "The airports they stand for, the main one first."
                            },
                            "how": {
                              "type": "string",
                              "description": "code (an airport code), city (a city: every airport serving it) or airport (an airport's name)."
                            }
                          },
                          "required": [
                            "text",
                            "airports",
                            "how"
                          ]
                        },
                        "place": {
                          "type": "object",
                          "properties": {
                            "text": {
                              "type": "string",
                              "description": "The words as read (folded)."
                            },
                            "airports": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "The airports they stand for, the main one first."
                            },
                            "how": {
                              "type": "string",
                              "description": "code (an airport code), city (a city: every airport serving it) or airport (an airport's name)."
                            }
                          },
                          "required": [
                            "text",
                            "airports",
                            "how"
                          ]
                        },
                        "airline": {
                          "type": "string",
                          "description": "fleet, airline_place: ICAO designator."
                        },
                        "family": {
                          "type": "string",
                          "description": "fleet, type: the family or designator read."
                        },
                        "types": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "fleet, type: its designators, most airframes first."
                        },
                        "code": {
                          "type": "string",
                          "description": "code: the code as looked up."
                        }
                      },
                      "required": [
                        "kind"
                      ]
                    },
                    "as_of": {
                      "type": "string",
                      "description": "When the data behind the index was taken, ISO 8601 UTC.",
                      "format": "date-time"
                    },
                    "index": {
                      "type": "string",
                      "description": "The index generation that answered, e.g. 20260926T024000Z. Answers from one generation are consistent with each other."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "oneOf": [
                          {
                            "type": "object",
                            "properties": {
                              "kind": {
                                "type": "string",
                                "description": "flight",
                                "enum": [
                                  "flight"
                                ]
                              },
                              "id": {
                                "type": "string",
                                "description": "Stable id: the ATC callsign (ICAO), e.g. SIA322. Opens /v1/flights/{callsign}."
                              },
                              "callsign": {
                                "type": "string",
                                "description": "The ATC callsign, e.g. SIA322."
                              },
                              "flight": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "The marketed flight number (IATA), e.g. SQ322: the one a timetable named, else the airline's IATA code before the callsign's number."
                              },
                              "airline": {
                                "description": "The operating airline.",
                                "oneOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "icao": {
                                        "type": "string",
                                        "description": "ICAO designator, e.g. SIA."
                                      },
                                      "iata": {
                                        "type": [
                                          "string",
                                          "null"
                                        ],
                                        "description": "IATA code, e.g. SQ."
                                      },
                                      "name": {
                                        "type": "string",
                                        "description": "Airline name."
                                      }
                                    },
                                    "required": [
                                      "icao",
                                      "iata",
                                      "name"
                                    ]
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "route": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "Airport codes in flying order, origin first."
                              },
                              "cities": {
                                "type": "array",
                                "items": {
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "description": "The city of each code in route, same order."
                              },
                              "legs": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "org": {
                                      "type": "string",
                                      "description": "Origin airport code (IATA, else ICAO)."
                                    },
                                    "dst": {
                                      "type": "string",
                                      "description": "Destination airport code (IATA, else ICAO)."
                                    },
                                    "dep": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "Usual departure, HH:MM local time at org (the zone in dep_tz)."
                                    },
                                    "arr": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "Usual arrival, HH:MM local time at dst (the zone in arr_tz)."
                                    },
                                    "dep_tz": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "IANA time zone of org, e.g. Asia/Singapore."
                                    },
                                    "arr_tz": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "IANA time zone of dst, e.g. Europe/London."
                                    },
                                    "block_min": {
                                      "type": [
                                        "integer",
                                        "null"
                                      ],
                                      "description": "Minutes from dep to arr, both zones applied (on the index's date)."
                                    },
                                    "type": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "Usual aircraft type (ICAO designator)."
                                    },
                                    "times": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "Where dep and arr come from: observed (the network watched it fly), published (an airport's timetable), or both."
                                    },
                                    "flights": {
                                      "type": "integer",
                                      "description": "Times this leg was flown in the flight log's window (window_days)."
                                    }
                                  },
                                  "required": [
                                    "org",
                                    "dst",
                                    "dep",
                                    "arr",
                                    "dep_tz",
                                    "arr_tz",
                                    "block_min",
                                    "type",
                                    "times",
                                    "flights"
                                  ]
                                },
                                "description": "Each leg, in flying order."
                              },
                              "flights": {
                                "type": "integer",
                                "description": "Times the flight was flown in the window (all legs)."
                              },
                              "window_days": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "description": "Days of flight log behind flights and last_seen."
                              },
                              "last_seen": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Date it was last seen, YYYY-MM-DD (UTC)."
                              },
                              "url": {
                                "type": "string",
                                "description": "The result's page on the network site, to cite or link.",
                                "format": "uri"
                              },
                              "score": {
                                "type": "number",
                                "description": "Rank, highest first: 1000 and up an exact code; about 900 what the query was read as (its intent), 40 less for each further reading; 600 names matched whole, 500 a word still being typed, 470 or 380 a typo (one or two edits), lower for part of the words. Popularity (flights, departures, airframes) orders within a class and never lifts a result into the one above. Compare scores within one answer only."
                              }
                            },
                            "required": [
                              "kind",
                              "id",
                              "callsign",
                              "flight",
                              "airline",
                              "route",
                              "cities",
                              "legs",
                              "flights",
                              "window_days",
                              "last_seen",
                              "url",
                              "score"
                            ],
                            "description": "A flight number and what the network knows of how it usually flies."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "kind": {
                                "type": "string",
                                "description": "airline",
                                "enum": [
                                  "airline"
                                ]
                              },
                              "id": {
                                "type": "string",
                                "description": "Stable id: the ICAO designator. Opens /v1/airlines/{icao}."
                              },
                              "icao": {
                                "type": "string",
                                "description": "ICAO designator."
                              },
                              "iata": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "IATA code."
                              },
                              "name": {
                                "type": "string",
                                "description": "Name."
                              },
                              "flights": {
                                "type": "integer",
                                "description": "Flights of its schedule in the flight log's window: how active it is here."
                              },
                              "url": {
                                "type": "string",
                                "description": "The result's page on the network site, to cite or link.",
                                "format": "uri"
                              },
                              "score": {
                                "type": "number",
                                "description": "Rank, highest first: 1000 and up an exact code; about 900 what the query was read as (its intent), 40 less for each further reading; 600 names matched whole, 500 a word still being typed, 470 or 380 a typo (one or two edits), lower for part of the words. Popularity (flights, departures, airframes) orders within a class and never lifts a result into the one above. Compare scores within one answer only."
                              }
                            },
                            "required": [
                              "kind",
                              "id",
                              "icao",
                              "iata",
                              "name",
                              "flights",
                              "url",
                              "score"
                            ]
                          },
                          {
                            "type": "object",
                            "properties": {
                              "kind": {
                                "type": "string",
                                "description": "airport",
                                "enum": [
                                  "airport"
                                ]
                              },
                              "id": {
                                "type": "string",
                                "description": "Stable id: the IATA code, else the ICAO/registry ident. Opens /v1/airports/{code}."
                              },
                              "iata": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "IATA code."
                              },
                              "icao": {
                                "type": "string",
                                "description": "ICAO code (the registry's ident)."
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Name."
                              },
                              "city": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "The municipality the registry gives."
                              },
                              "country": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "ISO 3166-1 alpha-2."
                              },
                              "tz": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "IANA time zone."
                              },
                              "flights": {
                                "type": "integer",
                                "description": "Scheduled departures seen in the flight log's window: how busy it is here."
                              },
                              "url": {
                                "type": "string",
                                "description": "The result's page on the network site, to cite or link.",
                                "format": "uri"
                              },
                              "score": {
                                "type": "number",
                                "description": "Rank, highest first: 1000 and up an exact code; about 900 what the query was read as (its intent), 40 less for each further reading; 600 names matched whole, 500 a word still being typed, 470 or 380 a typo (one or two edits), lower for part of the words. Popularity (flights, departures, airframes) orders within a class and never lifts a result into the one above. Compare scores within one answer only."
                              }
                            },
                            "required": [
                              "kind",
                              "id",
                              "iata",
                              "icao",
                              "name",
                              "city",
                              "country",
                              "tz",
                              "flights",
                              "url",
                              "score"
                            ]
                          },
                          {
                            "type": "object",
                            "properties": {
                              "kind": {
                                "type": "string",
                                "description": "aircraft",
                                "enum": [
                                  "aircraft"
                                ]
                              },
                              "id": {
                                "type": "string",
                                "description": "Stable id: the ICAO 24-bit address, 6 lowercase hex characters. Opens /v1/airframes/{hex}."
                              },
                              "hex": {
                                "type": "string",
                                "description": "ICAO 24-bit address, lowercase."
                              },
                              "reg": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Registration, e.g. 9V-SMA."
                              },
                              "type": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "ICAO type designator."
                              },
                              "type_name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Type name."
                              },
                              "operator": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "The airline the network watched it fly for, else the registry's owner or operator."
                              },
                              "operator_icao": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "That airline's ICAO designator, when observed."
                              },
                              "url": {
                                "type": "string",
                                "description": "The result's page on the network site, to cite or link.",
                                "format": "uri"
                              },
                              "score": {
                                "type": "number",
                                "description": "Rank, highest first: 1000 and up an exact code; about 900 what the query was read as (its intent), 40 less for each further reading; 600 names matched whole, 500 a word still being typed, 470 or 380 a typo (one or two edits), lower for part of the words. Popularity (flights, departures, airframes) orders within a class and never lifts a result into the one above. Compare scores within one answer only."
                              }
                            },
                            "required": [
                              "kind",
                              "id",
                              "hex",
                              "reg",
                              "type",
                              "type_name",
                              "operator",
                              "operator_icao",
                              "url",
                              "score"
                            ]
                          },
                          {
                            "type": "object",
                            "properties": {
                              "kind": {
                                "type": "string",
                                "description": "type",
                                "enum": [
                                  "type"
                                ]
                              },
                              "id": {
                                "type": "string",
                                "description": "Stable id: the ICAO type designator. Opens /v1/types/{designator}."
                              },
                              "designator": {
                                "type": "string",
                                "description": "ICAO type designator, e.g. A388."
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Name, e.g. Airbus A380-800."
                              },
                              "manufacturer": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Manufacturer, from the name."
                              },
                              "family": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Family, e.g. A380, 787."
                              },
                              "airframes": {
                                "type": "integer",
                                "description": "Airframes of this type in the registry."
                              },
                              "url": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Null: the site has no page for a type yet."
                              },
                              "score": {
                                "type": "number",
                                "description": "Rank, highest first: 1000 and up an exact code; about 900 what the query was read as (its intent), 40 less for each further reading; 600 names matched whole, 500 a word still being typed, 470 or 380 a typo (one or two edits), lower for part of the words. Popularity (flights, departures, airframes) orders within a class and never lifts a result into the one above. Compare scores within one answer only."
                              }
                            },
                            "required": [
                              "kind",
                              "id",
                              "designator",
                              "name",
                              "manufacturer",
                              "family",
                              "airframes",
                              "url",
                              "score"
                            ]
                          }
                        ],
                        "discriminator": {
                          "propertyName": "kind"
                        }
                      },
                      "description": "Typed results, best first."
                    }
                  },
                  "required": [
                    "q",
                    "intent",
                    "as_of",
                    "index",
                    "results"
                  ]
                },
                "examples": {
                  "flight_number": {
                    "summary": "A flight number, typed with a space",
                    "description": "GET /v2/search?q=SQ%20322 \u2014 its IATA number finds the callsign that flies it; flights whose numbers start with it follow.",
                    "value": {
                      "q": "SQ 322",
                      "intent": {
                        "kind": "flight",
                        "number": "SQ322",
                        "callsigns": [
                          "SQ322",
                          "SIA322"
                        ]
                      },
                      "as_of": "2026-09-26T02:40:00Z",
                      "index": "20260926T024000Z",
                      "results": [
                        {
                          "kind": "flight",
                          "id": "SIA322",
                          "callsign": "SIA322",
                          "flight": "SQ322",
                          "airline": {
                            "icao": "SIA",
                            "iata": "SQ",
                            "name": "Singapore Airlines"
                          },
                          "route": [
                            "SIN",
                            "LHR"
                          ],
                          "cities": [
                            "Singapore",
                            "London"
                          ],
                          "legs": [
                            {
                              "org": "SIN",
                              "dst": "LHR",
                              "dep": "23:35",
                              "arr": "06:25",
                              "dep_tz": "Asia/Singapore",
                              "arr_tz": "Europe/London",
                              "block_min": 830,
                              "type": "A388",
                              "times": "both",
                              "flights": 361
                            }
                          ],
                          "flights": 361,
                          "window_days": 400,
                          "last_seen": "2026-09-25",
                          "url": "https://flightportrait.com/network/flight.html?callsign=SIA322",
                          "score": 1032.9
                        }
                      ]
                    }
                  },
                  "route_in_words": {
                    "summary": "A route in words, cities for their airports",
                    "description": "GET /v2/search?q=SINGAPORE%20TO%20LONDON \u2014 a city stands for every airport serving it; nonstop flights first, then by how often they fly.",
                    "value": {
                      "q": "SINGAPORE TO LONDON",
                      "intent": {
                        "kind": "route",
                        "from": {
                          "text": "singapore",
                          "airports": [
                            "SIN"
                          ],
                          "how": "city"
                        },
                        "to": {
                          "text": "london",
                          "airports": [
                            "LHR",
                            "LGW",
                            "STN",
                            "LTN",
                            "LCY",
                            "SEN"
                          ],
                          "how": "city"
                        }
                      },
                      "as_of": "2026-09-26T02:40:00Z",
                      "index": "20260926T024000Z",
                      "results": [
                        {
                          "kind": "flight",
                          "id": "SIA322",
                          "callsign": "SIA322",
                          "flight": "SQ322",
                          "airline": {
                            "icao": "SIA",
                            "iata": "SQ",
                            "name": "Singapore Airlines"
                          },
                          "route": [
                            "SIN",
                            "LHR"
                          ],
                          "cities": [
                            "Singapore",
                            "London"
                          ],
                          "legs": [
                            {
                              "org": "SIN",
                              "dst": "LHR",
                              "dep": "23:35",
                              "arr": "06:25",
                              "dep_tz": "Asia/Singapore",
                              "arr_tz": "Europe/London",
                              "block_min": 830,
                              "type": "A388",
                              "times": "both",
                              "flights": 361
                            }
                          ],
                          "flights": 361,
                          "window_days": 400,
                          "last_seen": "2026-09-25",
                          "url": "https://flightportrait.com/network/flight.html?callsign=SIA322",
                          "score": 939.9
                        },
                        {
                          "kind": "flight",
                          "id": "SIA308",
                          "callsign": "SIA308",
                          "flight": "SQ308",
                          "airline": {
                            "icao": "SIA",
                            "iata": "SQ",
                            "name": "Singapore Airlines"
                          },
                          "route": [
                            "SIN",
                            "LHR"
                          ],
                          "cities": [
                            "Singapore",
                            "London"
                          ],
                          "legs": [
                            {
                              "org": "SIN",
                              "dst": "LHR",
                              "dep": "09:05",
                              "arr": "15:55",
                              "dep_tz": "Asia/Singapore",
                              "arr_tz": "Europe/London",
                              "block_min": 830,
                              "type": "A359",
                              "times": "observed",
                              "flights": 352
                            }
                          ],
                          "flights": 352,
                          "window_days": 400,
                          "last_seen": "2026-09-25",
                          "url": "https://flightportrait.com/network/flight.html?callsign=SIA308",
                          "score": 945.3
                        },
                        {
                          "kind": "flight",
                          "id": "BAW12",
                          "callsign": "BAW12",
                          "flight": "BA12",
                          "airline": {
                            "icao": "BAW",
                            "iata": "BA",
                            "name": "British Airways"
                          },
                          "route": [
                            "SIN",
                            "LHR"
                          ],
                          "cities": [
                            "Singapore",
                            "London"
                          ],
                          "legs": [
                            {
                              "org": "SIN",
                              "dst": "LHR",
                              "dep": "23:20",
                              "arr": "05:40",
                              "dep_tz": "Asia/Singapore",
                              "arr_tz": "Europe/London",
                              "block_min": 800,
                              "type": "A35K",
                              "times": "both",
                              "flights": 355
                            }
                          ],
                          "flights": 355,
                          "window_days": 400,
                          "last_seen": "2026-09-25",
                          "url": "https://flightportrait.com/network/flight.html?callsign=BAW12",
                          "score": 945.2
                        }
                      ]
                    }
                  },
                  "airline_and_place": {
                    "summary": "An airline and a place",
                    "description": "GET /v2/search?q=SINGAPORE%20AIRLINES%20LONDON \u2014 that airline's flights to and from the place.",
                    "value": {
                      "q": "SINGAPORE AIRLINES LONDON",
                      "intent": {
                        "kind": "airline_place",
                        "airline": "SIA",
                        "place": {
                          "text": "london",
                          "airports": [
                            "LHR",
                            "LGW",
                            "STN",
                            "LTN",
                            "LCY",
                            "SEN"
                          ],
                          "how": "city"
                        }
                      },
                      "as_of": "2026-09-26T02:40:00Z",
                      "index": "20260926T024000Z",
                      "results": [
                        {
                          "kind": "flight",
                          "id": "SIA322",
                          "callsign": "SIA322",
                          "flight": "SQ322",
                          "airline": {
                            "icao": "SIA",
                            "iata": "SQ",
                            "name": "Singapore Airlines"
                          },
                          "route": [
                            "SIN",
                            "LHR"
                          ],
                          "cities": [
                            "Singapore",
                            "London"
                          ],
                          "legs": [
                            {
                              "org": "SIN",
                              "dst": "LHR",
                              "dep": "23:35",
                              "arr": "06:25",
                              "dep_tz": "Asia/Singapore",
                              "arr_tz": "Europe/London",
                              "block_min": 830,
                              "type": "A388",
                              "times": "both",
                              "flights": 361
                            }
                          ],
                          "flights": 361,
                          "window_days": 400,
                          "last_seen": "2026-09-25",
                          "url": "https://flightportrait.com/network/flight.html?callsign=SIA322",
                          "score": 935.3
                        },
                        {
                          "kind": "flight",
                          "id": "SIA308",
                          "callsign": "SIA308",
                          "flight": "SQ308",
                          "airline": {
                            "icao": "SIA",
                            "iata": "SQ",
                            "name": "Singapore Airlines"
                          },
                          "route": [
                            "SIN",
                            "LHR"
                          ],
                          "cities": [
                            "Singapore",
                            "London"
                          ],
                          "legs": [
                            {
                              "org": "SIN",
                              "dst": "LHR",
                              "dep": "09:05",
                              "arr": "15:55",
                              "dep_tz": "Asia/Singapore",
                              "arr_tz": "Europe/London",
                              "block_min": 830,
                              "type": "A359",
                              "times": "observed",
                              "flights": 352
                            }
                          ],
                          "flights": 352,
                          "window_days": 400,
                          "last_seen": "2026-09-25",
                          "url": "https://flightportrait.com/network/flight.html?callsign=SIA308",
                          "score": 935.2
                        },
                        {
                          "kind": "flight",
                          "id": "SIA317",
                          "callsign": "SIA317",
                          "flight": "SQ317",
                          "airline": {
                            "icao": "SIA",
                            "iata": "SQ",
                            "name": "Singapore Airlines"
                          },
                          "route": [
                            "LHR",
                            "SIN"
                          ],
                          "cities": [
                            "London",
                            "Singapore"
                          ],
                          "legs": [
                            {
                              "org": "LHR",
                              "dst": "SIN",
                              "dep": "11:05",
                              "arr": "07:25",
                              "dep_tz": "Europe/London",
                              "arr_tz": "Asia/Singapore",
                              "block_min": 800,
                              "type": "A359",
                              "times": "observed",
                              "flights": 340
                            }
                          ],
                          "flights": 340,
                          "window_days": 400,
                          "last_seen": "2026-09-24",
                          "url": "https://flightportrait.com/network/flight.html?callsign=SIA317",
                          "score": 925.2
                        }
                      ]
                    }
                  },
                  "city": {
                    "summary": "A city: every airport serving it",
                    "description": "GET /v2/search?q=TOKYO&kinds=airport",
                    "value": {
                      "q": "TOKYO",
                      "intent": {
                        "kind": "city",
                        "place": {
                          "text": "tokyo",
                          "airports": [
                            "HND",
                            "NRT"
                          ],
                          "how": "city"
                        }
                      },
                      "as_of": "2026-09-26T02:40:00Z",
                      "index": "20260926T024000Z",
                      "results": [
                        {
                          "kind": "airport",
                          "id": "HND",
                          "iata": "HND",
                          "icao": "RJTT",
                          "name": "Tokyo Haneda International Airport",
                          "city": "Tokyo",
                          "country": "JP",
                          "tz": "Asia/Tokyo",
                          "flights": 50289,
                          "url": "https://flightportrait.com/network/?airport=HND",
                          "score": 924.7
                        },
                        {
                          "kind": "airport",
                          "id": "NRT",
                          "iata": "NRT",
                          "icao": "RJAA",
                          "name": "Narita International Airport",
                          "city": "Narita",
                          "country": "JP",
                          "tz": "Asia/Tokyo",
                          "flights": 12848,
                          "url": "https://flightportrait.com/network/?airport=NRT",
                          "score": 921.1
                        }
                      ]
                    }
                  },
                  "type": {
                    "summary": "An aircraft family",
                    "description": "GET /v2/search?q=A380",
                    "value": {
                      "q": "A380",
                      "intent": {
                        "kind": "type",
                        "family": "A380",
                        "types": [
                          "A388"
                        ]
                      },
                      "as_of": "2026-09-26T02:40:00Z",
                      "index": "20260926T024000Z",
                      "results": [
                        {
                          "kind": "type",
                          "id": "A388",
                          "designator": "A388",
                          "name": "Airbus A380-800",
                          "manufacturer": "Airbus",
                          "family": "A380",
                          "airframes": 261,
                          "url": null,
                          "score": 912.4
                        }
                      ]
                    }
                  },
                  "registration": {
                    "summary": "A registration, however typed",
                    "description": "GET /v2/search?q=9V%20SMA",
                    "value": {
                      "q": "9V SMA",
                      "intent": {
                        "kind": "registration",
                        "registration": "9VSMA"
                      },
                      "as_of": "2026-09-26T02:40:00Z",
                      "index": "20260926T024000Z",
                      "results": [
                        {
                          "kind": "aircraft",
                          "id": "76cda1",
                          "hex": "76cda1",
                          "reg": "9V-SMA",
                          "type": "A359",
                          "type_name": "Airbus A350-900",
                          "operator": "Singapore Airlines",
                          "operator_icao": "SIA",
                          "url": "https://flightportrait.com/network/plane.html?hex=76cda1",
                          "score": 1030.0
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "301": {
            "description": "A parameter in another spelling than its canonical one (q trimmed, one space between words, uppercase; kinds in the order flight, airline, airport, aircraft, type; limit as a plain number; near rounded to 0.25\u00b0): Location is this URL with them canonical, every other parameter kept. Cached like the answer.",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/search?q=SQ%20322"
              }
            }
          },
          "422": {
            "description": "Malformed input.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "503": {
            "description": "The search index is not loaded (artifact_unavailable). Retry-After is set. Never answered from anything else.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "artifact_unavailable",
                  "detail": "search index not loaded"
                }
              }
            }
          }
        },
        "x-stability": "candidate"
      }
    },
    "/v1/gaps": {
      "get": {
        "tags": [
          "Contributions"
        ],
        "summary": "Open questions",
        "description": "Callsigns whose route observation settled at one end only, most-seen first. Each row says which end is missing, which is known, where the aircraft was last heard, and how far its rotation says the other end is. Answers go to the contribution door, not this API. Rate: 300 per 600 s (bucket `gaps`). Cache: 10 min edge.",
        "operationId": "gaps",
        "parameters": [
          {
            "name": "airline",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "minLength": 2,
                  "maxLength": 3
                },
                {
                  "type": "null"
                }
              ],
              "description": "ICAO airline prefix.",
              "title": "Airline"
            },
            "description": "ICAO airline prefix."
          },
          {
            "name": "side",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "pattern": "^(origin|dest)$"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Side"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0,
              "title": "Offset"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "total": {
                      "type": "integer",
                      "description": "Rows matching the filters."
                    },
                    "offset": {
                      "type": "integer"
                    },
                    "gaps": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "callsign": {
                            "type": "string"
                          },
                          "side": {
                            "type": "string",
                            "description": "The missing end: origin or dest."
                          },
                          "known": {
                            "type": "string",
                            "description": "The settled end, IATA."
                          },
                          "hint": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The missing end's leading code when observation saw it too rarely to settle it."
                          },
                          "chain": {
                            "description": "Every known stop in order when the callsign is a chain with one end unseen; the missing end goes before or after it. Null for a single leg.",
                            "oneOf": [
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "type": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Dominant aircraft type on the leg."
                          },
                          "n_recent": {
                            "type": "integer",
                            "description": "Sightings in the last 90 days."
                          },
                          "last_seen": {
                            "type": "string",
                            "description": "Last date observed, YYYY-MM-DD."
                          },
                          "last_heard": {
                            "description": "Where the most recent truncated leg was last heard, with its track in degrees true. Null when unknown.",
                            "oneOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "lat": {
                                    "type": "number"
                                  },
                                  "lon": {
                                    "type": "number"
                                  },
                                  "track": {
                                    "type": [
                                      "integer",
                                      "null"
                                    ]
                                  }
                                }
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "rotation_km": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "description": "How far the missing end is, from the time the airframe takes to come back. Null until a few rotations were seen."
                          },
                          "suggested": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Airports the evidence allows for the missing end, best first: at the rotation's distance, within the type's range, along the last heard track, ranked by how much the airline is seen flying there. Empty until the rotation is known."
                          }
                        }
                      }
                    },
                    "coverage": {
                      "type": "string",
                      "description": "Always \"observed\": evidence from our receivers and open trace archives, never a published schedule or registry.",
                      "const": "observed"
                    }
                  },
                  "required": [
                    "total",
                    "offset",
                    "gaps",
                    "coverage"
                  ]
                },
                "example": {
                  "total": 1,
                  "offset": 0,
                  "gaps": [
                    {
                      "callsign": "SIA842",
                      "side": "dest",
                      "known": "SIN",
                      "type": "B78X",
                      "n_recent": 13,
                      "last_seen": "2026-09-06",
                      "last_heard": {
                        "lat": 12.41,
                        "lon": 106.92,
                        "track": 21
                      },
                      "rotation_km": 3150,
                      "suggested": [
                        "TFU",
                        "CTU"
                      ]
                    }
                  ],
                  "coverage": "observed"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "503": {
            "description": "Live snapshot older than 60 seconds (stale_snapshot) or a required history artifact is not loaded (artifact_unavailable). Retry-After is set.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "x-stability": "stable"
      }
    },
    "/v1/gaps/{callsign}": {
      "get": {
        "tags": [
          "Contributions"
        ],
        "summary": "One question",
        "description": "The open question for one callsign, the answers on file, and the catalog answer in force if there is one. 404 when observation has no question for it. Rate: 300 per 600 s (bucket `gaps`). Cache: 10 min edge.",
        "operationId": "gap",
        "parameters": [
          {
            "name": "callsign",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Callsign or flight ident, 2-12 alphanumerics.",
              "title": "Callsign"
            },
            "description": "Callsign or flight ident, 2-12 alphanumerics."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "callsign": {
                      "type": "string"
                    },
                    "side": {
                      "type": "string",
                      "description": "The missing end: origin or dest."
                    },
                    "known": {
                      "type": "string",
                      "description": "The settled end, IATA."
                    },
                    "hint": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "The missing end's leading code when observation saw it too rarely to settle it."
                    },
                    "chain": {
                      "description": "Every known stop in order when the callsign is a chain with one end unseen; the missing end goes before or after it. Null for a single leg.",
                      "oneOf": [
                        {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "type": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Dominant aircraft type on the leg."
                    },
                    "n_recent": {
                      "type": "integer",
                      "description": "Sightings in the last 90 days."
                    },
                    "last_seen": {
                      "type": "string",
                      "description": "Last date observed, YYYY-MM-DD."
                    },
                    "last_heard": {
                      "description": "Where the most recent truncated leg was last heard, with its track in degrees true. Null when unknown.",
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "lat": {
                              "type": "number"
                            },
                            "lon": {
                              "type": "number"
                            },
                            "track": {
                              "type": [
                                "integer",
                                "null"
                              ]
                            }
                          }
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "rotation_km": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "How far the missing end is, from the time the airframe takes to come back. Null until a few rotations were seen."
                    },
                    "suggested": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Airports the evidence allows for the missing end, best first: at the rotation's distance, within the type's range, along the last heard track, ranked by how much the airline is seen flying there. Empty until the rotation is known."
                    },
                    "catalog": {
                      "description": "The community answer in force, if any: the whole route, IATA.",
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "route": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "valid_from": {
                              "type": "string"
                            }
                          }
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "answers": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "origin": {
                            "type": "string"
                          },
                          "dest": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "description": "pending or approved."
                          },
                          "verdict": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "corroborated, contradicted, unverified, or contested."
                          }
                        }
                      },
                      "description": "Answers on file, oldest first, rejected ones left out."
                    }
                  }
                },
                "example": {
                  "callsign": "SIA842",
                  "side": "dest",
                  "known": "SIN",
                  "type": "B78X",
                  "n_recent": 13,
                  "last_seen": "2026-09-06",
                  "last_heard": {
                    "lat": 12.41,
                    "lon": 106.92,
                    "track": 21
                  },
                  "rotation_km": 3150,
                  "suggested": [
                    "TFU",
                    "CTU"
                  ],
                  "answers": []
                }
              }
            }
          },
          "404": {
            "description": "Not found or not observed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Malformed input.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          },
          "503": {
            "description": "Live snapshot older than 60 seconds (stale_snapshot) or a required history artifact is not loaded (artifact_unavailable). Retry-After is set.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "required": [
                    "error",
                    "detail"
                  ]
                }
              }
            }
          }
        },
        "x-stability": "stable"
      }
    },
    "/v1/contributors": {
      "get": {
        "tags": [
          "Contributions"
        ],
        "summary": "Contributors",
        "description": "Who answered, by approved claims they stood behind, most first. Only claims in the catalog count, and only contributors who gave a name. Rate: 300 per 600 s (bucket `gaps`). Cache: 10 min edge.",
        "operationId": "contributors",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "answers": {
                      "type": "integer",
                      "description": "Approved claims, all contributors."
                    },
                    "contributors": {
                      "items": {
                        "properties": {
                          "handle": {
                            "type": "string"
                          },
                          "answers": {
                            "type": "integer",
                            "description": "Approved claims stood behind."
                          },
                          "latest": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Date of the latest, YYYY-MM-DD."
                          }
                        },
                        "type": "object"
                      },
                      "type": "array",
                      "description": "Most answers first, top 200."
                    }
                  },
                  "type": "object",
                  "required": [
                    "answers",
                    "contributors"
                  ]
                },
                "example": {
                  "answers": 41,
                  "contributors": [
                    {
                      "handle": "spotter_sg",
                      "answers": 23,
                      "latest": "2026-09-14"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait Retry-After seconds. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: not_found, not_observed, invalid_request, rate_limited, stale_snapshot, artifact_unavailable, upstream_unavailable."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation."
                    }
                  },
                  "type": "object",
                  "required": [
                    "error",
                    "detail"
                  ]
                },
                "example": {
                  "error": "rate_limited",
                  "detail": "slow down"
                }
              }
            }
          }
        },
        "x-stability": "stable"
      }
    },
    "/healthz": {
      "get": {
        "tags": [
          "Meta"
        ],
        "summary": "Health",
        "description": "Liveness. Does not check the aggregator; a sick readsb shows up as 503 on the data routes.",
        "operationId": "healthz",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    }
                  },
                  "type": "object",
                  "required": [
                    "ok"
                  ]
                },
                "example": {
                  "ok": true
                }
              }
            }
          }
        },
        "x-hidden": true,
        "x-stability": "stable"
      }
    },
    "/": {
      "get": {
        "tags": [
          "Meta"
        ],
        "summary": "Index",
        "description": "Name, docs, spec, source, terms, attribution, credits, and the feed address.",
        "operationId": "index",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "docs": {
                      "type": "string",
                      "description": "Human documentation."
                    },
                    "llms": {
                      "type": "string",
                      "description": "An llms.txt for language models and agents."
                    },
                    "openapi": {
                      "type": "string",
                      "description": "Machine-readable spec path."
                    },
                    "swagger": {
                      "type": "string",
                      "description": "Interactive spec UI path."
                    },
                    "source": {
                      "type": "string",
                      "description": "Public repository (map client and API service)."
                    },
                    "terms": {
                      "type": "string"
                    },
                    "attribution": {
                      "type": "string",
                      "description": "The short credit line; the credits page holds each source's own credit."
                    },
                    "credits": {
                      "type": "string",
                      "description": "Every source the data draws on, with its licence and credit."
                    },
                    "feed": {
                      "type": "string",
                      "description": "Where to point an antenna."
                    }
                  },
                  "type": "object",
                  "required": [
                    "name",
                    "docs",
                    "openapi",
                    "terms",
                    "attribution",
                    "credits",
                    "feed"
                  ]
                },
                "example": {
                  "name": "FlightPortrait network API",
                  "docs": "https://docs.flightportrait.com/api/reference",
                  "llms": "/llms.txt",
                  "openapi": "/openapi.json",
                  "swagger": "/docs",
                  "source": "https://github.com/flightportrait/network",
                  "terms": "https://flightportrait.com/network/terms",
                  "attribution": "Data (c) FlightPortrait network feeders and credited sources, ODbL 1.0",
                  "credits": "https://flightportrait.com/network/credits.html",
                  "feed": "feed.flightportrait.com:30004 (beast_reduce_plus_out)"
                }
              }
            }
          }
        },
        "x-hidden": true,
        "x-stability": "stable"
      }
    }
  },
  "components": {
    "schemas": {
      "Beacon": {
        "properties": {
          "lan": {
            "type": "string",
            "title": "Lan"
          },
          "port": {
            "type": "integer",
            "title": "Port",
            "default": 8654
          },
          "name": {
            "type": "string",
            "title": "Name",
            "default": "station"
          }
        },
        "type": "object",
        "required": [
          "lan"
        ],
        "title": "Beacon"
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          },
          "input": {
            "title": "Input"
          },
          "ctx": {
            "type": "object",
            "title": "Context"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      }
    }
  },
  "tags": [
    {
      "name": "Live",
      "description": "What the network hears now."
    },
    {
      "name": "History",
      "description": "Observed airframes, flights, airports."
    },
    {
      "name": "Stations",
      "description": "Feeder roster."
    },
    {
      "name": "Reference",
      "description": "Airlines, alliances, types."
    },
    {
      "name": "Contributions",
      "description": "What observation could not settle, and the community answers to it."
    },
    {
      "name": "Meta",
      "description": "Index and health."
    }
  ]
}
