{
  "openapi": "3.0.3",
  "info": {
    "title": "sondahub Flights API",
    "version": "0.6.1",
    "description": "Airports, airlines, two and a half thousand scheduled flights and their bookings — the live-board one.\n\nFifty real airports, six invented airlines, flights over a two-week window around the seed’s \"today\" (2026-09-01), and three and a half thousand bookings with passengers and seats. The live stream runs a departures board: flights boarding, departing, delayed and landing. POST a booking and the hub picks a seat.\n\nNo keys, no accounts. Writes (POST, PUT, PATCH, DELETE) are validated and answered exactly as a real server would answer them, then forgotten: sondahub stores nothing, and every such answer says so in _note and in the X-Sondahub-Write: simulated header. Every list takes page, limit, sort, q, fields and expand, plus one filter per field with the operators _ne _gt _gte _lt _lte _like _in.",
    "contact": {
      "name": "sondahub",
      "url": "https://api.sondahub.com"
    }
  },
  "servers": [
    {
      "url": "https://api.sondahub.com"
    }
  ],
  "tags": [
    {
      "name": "airports",
      "description": "Airports by IATA code."
    },
    {
      "name": "airlines",
      "description": "Carriers."
    },
    {
      "name": "flights",
      "description": "A scheduled flight. Times are ISO with the airport’s UTC offset applied, so a departure reads like the board. Filter by route with ?origin=MIA&destination=EZE, by day with ?departure_date=2026-09-02."
    },
    {
      "name": "bookings",
      "description": "A seat on a flight. POST {\"flight_id\",\"passenger\":{...},\"cabin\"} and the hub assigns a seat and a record locator. Cancel with PATCH {\"status\":\"cancelled\"}."
    }
  ],
  "paths": {
    "/v1/flights/airports": {
      "get": {
        "tags": [
          "airports"
        ],
        "summary": "List airports",
        "operationId": "list_airports",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Comma-separated fields; prefix with - for descending. Default: id.",
            "schema": {
              "type": "string",
              "example": "-id"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search over the string fields.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "description": "Comma-separated fields to return.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "query",
            "required": false,
            "description": "Filter: id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "description": "Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed.",
              "readOnly": true
            }
          },
          {
            "name": "created_at",
            "in": "query",
            "required": false,
            "description": "Filter: created_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true,
              "description": "When the record was created (ISO 8601, UTC).",
              "readOnly": true
            }
          },
          {
            "name": "updated_at",
            "in": "query",
            "required": false,
            "description": "Filter: updated_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true,
              "description": "When the record last changed.",
              "readOnly": true
            }
          },
          {
            "name": "iata",
            "in": "query",
            "required": false,
            "description": "Filter: iata equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "example": "MIA"
            }
          },
          {
            "name": "name",
            "in": "query",
            "required": false,
            "description": "Filter: name equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "city",
            "in": "query",
            "required": false,
            "description": "Filter: city equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "description": "Filter: country equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "nullable": true,
              "example": "US"
            }
          },
          {
            "name": "timezone",
            "in": "query",
            "required": false,
            "description": "Filter: timezone equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "lat",
            "in": "query",
            "required": false,
            "description": "Filter: lat equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "number",
              "nullable": true
            }
          },
          {
            "name": "lon",
            "in": "query",
            "required": false,
            "description": "Filter: lon equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "number",
              "nullable": true
            }
          },
          {
            "name": "terminals",
            "in": "query",
            "required": false,
            "description": "Filter: terminals equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AirportList"
                }
              }
            }
          },
          "400": {
            "description": "A parameter could not be read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "airports"
        ],
        "summary": "Create a airport",
        "operationId": "create_airport",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AirportInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created — simulated: the answer is what a real server would give, nothing is stored (see _note and the X-Sondahub-Write header).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Airport"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/flights/airports/{id}": {
      "get": {
        "tags": [
          "airports"
        ],
        "summary": "Get a airport",
        "operationId": "get_airport",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "The record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Airport"
                }
              }
            }
          },
          "304": {
            "description": "Unchanged since the ETag you sent."
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "airports"
        ],
        "summary": "Replace a airport",
        "operationId": "replace_airport",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AirportInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The record as it would have been saved — simulated, nothing is stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Airport"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "airports"
        ],
        "summary": "Update part of a airport",
        "operationId": "update_airport",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AirportInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The record as it would have been saved — simulated, nothing is stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Airport"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "airports"
        ],
        "summary": "Delete a airport",
        "description": "Simulated: answers 200 with the record that would have been removed and a note; nothing is stored.",
        "operationId": "delete_airport",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "What would have been deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "boolean"
                    },
                    "id": {
                      "type": "integer"
                    },
                    "_note": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/flights/airlines": {
      "get": {
        "tags": [
          "airlines"
        ],
        "summary": "List airlines",
        "operationId": "list_airlines",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Comma-separated fields; prefix with - for descending. Default: id.",
            "schema": {
              "type": "string",
              "example": "-id"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search over the string fields.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "description": "Comma-separated fields to return.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "expand",
            "in": "query",
            "description": "Comma-separated relations to embed: flights.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "query",
            "required": false,
            "description": "Filter: id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "description": "Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed.",
              "readOnly": true
            }
          },
          {
            "name": "created_at",
            "in": "query",
            "required": false,
            "description": "Filter: created_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true,
              "description": "When the record was created (ISO 8601, UTC).",
              "readOnly": true
            }
          },
          {
            "name": "updated_at",
            "in": "query",
            "required": false,
            "description": "Filter: updated_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true,
              "description": "When the record last changed.",
              "readOnly": true
            }
          },
          {
            "name": "code",
            "in": "query",
            "required": false,
            "description": "Filter: code equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "example": "SH"
            }
          },
          {
            "name": "name",
            "in": "query",
            "required": false,
            "description": "Filter: name equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "alliance",
            "in": "query",
            "required": false,
            "description": "Filter: alliance equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "fleet_size",
            "in": "query",
            "required": false,
            "description": "Filter: fleet_size equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AirlineList"
                }
              }
            }
          },
          "400": {
            "description": "A parameter could not be read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "airlines"
        ],
        "summary": "Create a airline",
        "operationId": "create_airline",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AirlineInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created — simulated: the answer is what a real server would give, nothing is stored (see _note and the X-Sondahub-Write header).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Airline"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/flights/airlines/{id}": {
      "get": {
        "tags": [
          "airlines"
        ],
        "summary": "Get a airline",
        "operationId": "get_airline",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "expand",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Airline"
                }
              }
            }
          },
          "304": {
            "description": "Unchanged since the ETag you sent."
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "airlines"
        ],
        "summary": "Replace a airline",
        "operationId": "replace_airline",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AirlineInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The record as it would have been saved — simulated, nothing is stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Airline"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "airlines"
        ],
        "summary": "Update part of a airline",
        "operationId": "update_airline",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AirlineInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The record as it would have been saved — simulated, nothing is stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Airline"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "airlines"
        ],
        "summary": "Delete a airline",
        "description": "Simulated: answers 200 with the record that would have been removed and a note; nothing is stored.",
        "operationId": "delete_airline",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "What would have been deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "boolean"
                    },
                    "id": {
                      "type": "integer"
                    },
                    "_note": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/flights/airlines/{id}/flights": {
      "get": {
        "tags": [
          "airlines"
        ],
        "summary": "The flights of a airline",
        "operationId": "airline_flights",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Comma-separated fields; prefix with - for descending. Default: id.",
            "schema": {
              "type": "string",
              "example": "-id"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search over the string fields.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "description": "Comma-separated fields to return.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of related records.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FlightList"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/flights/flights": {
      "get": {
        "tags": [
          "flights"
        ],
        "summary": "List flights",
        "operationId": "list_flights",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Comma-separated fields; prefix with - for descending. Default: scheduled_departure.",
            "schema": {
              "type": "string",
              "example": "scheduled_departure"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search over the string fields.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "description": "Comma-separated fields to return.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "expand",
            "in": "query",
            "description": "Comma-separated relations to embed: airline, origin_airport, destination_airport, bookings.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "query",
            "required": false,
            "description": "Filter: id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "description": "Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed.",
              "readOnly": true
            }
          },
          {
            "name": "created_at",
            "in": "query",
            "required": false,
            "description": "Filter: created_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true,
              "description": "When the record was created (ISO 8601, UTC).",
              "readOnly": true
            }
          },
          {
            "name": "updated_at",
            "in": "query",
            "required": false,
            "description": "Filter: updated_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true,
              "description": "When the record last changed.",
              "readOnly": true
            }
          },
          {
            "name": "number",
            "in": "query",
            "required": false,
            "description": "Filter: number equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "example": "SH 1042"
            }
          },
          {
            "name": "airline_id",
            "in": "query",
            "required": false,
            "description": "Filter: airline_id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "description": "The id of a airline."
            }
          },
          {
            "name": "origin",
            "in": "query",
            "required": false,
            "description": "Filter: origin equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "description": "IATA code.",
              "example": "MIA"
            }
          },
          {
            "name": "destination",
            "in": "query",
            "required": false,
            "description": "Filter: destination equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "example": "EZE"
            }
          },
          {
            "name": "origin_airport_id",
            "in": "query",
            "required": false,
            "description": "Filter: origin_airport_id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "description": "The id of a airport."
            }
          },
          {
            "name": "destination_airport_id",
            "in": "query",
            "required": false,
            "description": "Filter: destination_airport_id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "description": "The id of a airport."
            }
          },
          {
            "name": "departure_date",
            "in": "query",
            "required": false,
            "description": "Filter: departure_date equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date",
              "nullable": true,
              "description": "Local date at the origin."
            }
          },
          {
            "name": "scheduled_departure",
            "in": "query",
            "required": false,
            "description": "Filter: scheduled_departure equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "scheduled_arrival",
            "in": "query",
            "required": false,
            "description": "Filter: scheduled_arrival equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true
            }
          },
          {
            "name": "estimated_departure",
            "in": "query",
            "required": false,
            "description": "Filter: estimated_departure equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true
            }
          },
          {
            "name": "actual_departure",
            "in": "query",
            "required": false,
            "description": "Filter: actual_departure equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter: status equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "enum": [
                "scheduled",
                "boarding",
                "departed",
                "in_air",
                "landed",
                "delayed",
                "cancelled",
                "diverted"
              ],
              "nullable": true,
              "example": "scheduled"
            }
          },
          {
            "name": "delay_minutes",
            "in": "query",
            "required": false,
            "description": "Filter: delay_minutes equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "minimum": 0
            }
          },
          {
            "name": "gate",
            "in": "query",
            "required": false,
            "description": "Filter: gate equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "nullable": true,
              "example": "D14"
            }
          },
          {
            "name": "terminal",
            "in": "query",
            "required": false,
            "description": "Filter: terminal equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "aircraft",
            "in": "query",
            "required": false,
            "description": "Filter: aircraft equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "nullable": true,
              "example": "A321neo"
            }
          },
          {
            "name": "duration_minutes",
            "in": "query",
            "required": false,
            "description": "Filter: duration_minutes equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true
            }
          },
          {
            "name": "distance_km",
            "in": "query",
            "required": false,
            "description": "Filter: distance_km equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true
            }
          },
          {
            "name": "seats_total",
            "in": "query",
            "required": false,
            "description": "Filter: seats_total equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true
            }
          },
          {
            "name": "seats_available",
            "in": "query",
            "required": false,
            "description": "Filter: seats_available equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "readOnly": true
            }
          },
          {
            "name": "base_fare",
            "in": "query",
            "required": false,
            "description": "Filter: base_fare equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "number",
              "nullable": true,
              "description": "USD, economy."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FlightList"
                }
              }
            }
          },
          "400": {
            "description": "A parameter could not be read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "flights"
        ],
        "summary": "Create a flight",
        "operationId": "create_flight",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FlightInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created — simulated: the answer is what a real server would give, nothing is stored (see _note and the X-Sondahub-Write header).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Flight"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/flights/flights/{id}": {
      "get": {
        "tags": [
          "flights"
        ],
        "summary": "Get a flight",
        "operationId": "get_flight",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "expand",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Flight"
                }
              }
            }
          },
          "304": {
            "description": "Unchanged since the ETag you sent."
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "flights"
        ],
        "summary": "Replace a flight",
        "operationId": "replace_flight",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FlightInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The record as it would have been saved — simulated, nothing is stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Flight"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "flights"
        ],
        "summary": "Update part of a flight",
        "operationId": "update_flight",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FlightInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The record as it would have been saved — simulated, nothing is stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Flight"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "flights"
        ],
        "summary": "Delete a flight",
        "description": "Simulated: answers 200 with the record that would have been removed and a note; nothing is stored.",
        "operationId": "delete_flight",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "What would have been deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "boolean"
                    },
                    "id": {
                      "type": "integer"
                    },
                    "_note": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/flights/flights/{id}/airline": {
      "get": {
        "tags": [
          "flights"
        ],
        "summary": "The airline of a flight",
        "operationId": "flight_airline",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "The related record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Airline"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/flights/flights/{id}/origin_airport": {
      "get": {
        "tags": [
          "flights"
        ],
        "summary": "The origin_airport of a flight",
        "operationId": "flight_origin_airport",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "The related record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Airport"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/flights/flights/{id}/destination_airport": {
      "get": {
        "tags": [
          "flights"
        ],
        "summary": "The destination_airport of a flight",
        "operationId": "flight_destination_airport",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "The related record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Airport"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/flights/flights/{id}/bookings": {
      "get": {
        "tags": [
          "flights"
        ],
        "summary": "The bookings of a flight",
        "operationId": "flight_bookings",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Comma-separated fields; prefix with - for descending. Default: scheduled_departure.",
            "schema": {
              "type": "string",
              "example": "scheduled_departure"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search over the string fields.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "description": "Comma-separated fields to return.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of related records.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BookingList"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/flights/bookings": {
      "get": {
        "tags": [
          "bookings"
        ],
        "summary": "List bookings",
        "operationId": "list_bookings",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Comma-separated fields; prefix with - for descending. Default: -booked_at.",
            "schema": {
              "type": "string",
              "example": "-booked_at"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search over the string fields.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "description": "Comma-separated fields to return.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "expand",
            "in": "query",
            "description": "Comma-separated relations to embed: flight.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "query",
            "required": false,
            "description": "Filter: id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "description": "Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed.",
              "readOnly": true
            }
          },
          {
            "name": "created_at",
            "in": "query",
            "required": false,
            "description": "Filter: created_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true,
              "description": "When the record was created (ISO 8601, UTC).",
              "readOnly": true
            }
          },
          {
            "name": "updated_at",
            "in": "query",
            "required": false,
            "description": "Filter: updated_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true,
              "description": "When the record last changed.",
              "readOnly": true
            }
          },
          {
            "name": "locator",
            "in": "query",
            "required": false,
            "description": "Filter: locator equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "nullable": true,
              "description": "Six-character record locator, unique.",
              "example": "K7M2QX",
              "readOnly": true
            }
          },
          {
            "name": "flight_id",
            "in": "query",
            "required": false,
            "description": "Filter: flight_id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "description": "The id of a flight."
            }
          },
          {
            "name": "seat",
            "in": "query",
            "required": false,
            "description": "Filter: seat equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "nullable": true,
              "description": "Assigned by the hub on POST when omitted.",
              "example": "14C"
            }
          },
          {
            "name": "cabin",
            "in": "query",
            "required": false,
            "description": "Filter: cabin equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "enum": [
                "economy",
                "premium",
                "business",
                "first"
              ],
              "nullable": true,
              "example": "economy"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter: status equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "enum": [
                "confirmed",
                "checked_in",
                "boarded",
                "cancelled",
                "no_show"
              ],
              "nullable": true,
              "example": "confirmed"
            }
          },
          {
            "name": "fare",
            "in": "query",
            "required": false,
            "description": "Filter: fare equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "number",
              "nullable": true,
              "minimum": 0
            }
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "description": "Filter: currency equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "bags",
            "in": "query",
            "required": false,
            "description": "Filter: bags equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "minimum": 0,
              "maximum": 5
            }
          },
          {
            "name": "frequent_flyer",
            "in": "query",
            "required": false,
            "description": "Filter: frequent_flyer equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "booked_at",
            "in": "query",
            "required": false,
            "description": "Filter: booked_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true
            }
          },
          {
            "name": "checked_in_at",
            "in": "query",
            "required": false,
            "description": "Filter: checked_in_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BookingList"
                }
              }
            }
          },
          "400": {
            "description": "A parameter could not be read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "bookings"
        ],
        "summary": "Create a booking",
        "operationId": "create_booking",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BookingInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created — simulated: the answer is what a real server would give, nothing is stored (see _note and the X-Sondahub-Write header).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Booking"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/flights/bookings/{id}": {
      "get": {
        "tags": [
          "bookings"
        ],
        "summary": "Get a booking",
        "operationId": "get_booking",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "expand",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Booking"
                }
              }
            }
          },
          "304": {
            "description": "Unchanged since the ETag you sent."
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "bookings"
        ],
        "summary": "Replace a booking",
        "operationId": "replace_booking",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BookingInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The record as it would have been saved — simulated, nothing is stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Booking"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "bookings"
        ],
        "summary": "Update part of a booking",
        "operationId": "update_booking",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BookingInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The record as it would have been saved — simulated, nothing is stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Booking"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "bookings"
        ],
        "summary": "Delete a booking",
        "description": "Simulated: answers 200 with the record that would have been removed and a note; nothing is stored.",
        "operationId": "delete_booking",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "What would have been deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "boolean"
                    },
                    "id": {
                      "type": "integer"
                    },
                    "_note": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/flights/bookings/{id}/flight": {
      "get": {
        "tags": [
          "bookings"
        ],
        "summary": "The flight of a booking",
        "operationId": "booking_flight",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "The related record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Flight"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "example": "validation_failed"
              },
              "message": {
                "type": "string"
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        }
      },
      "ListMeta": {
        "type": "object",
        "properties": {
          "page": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "pages": {
            "type": "integer"
          }
        }
      },
      "Airport": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "nullable": true,
            "description": "Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed.",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the record was created (ISO 8601, UTC).",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the record last changed.",
            "readOnly": true
          },
          "iata": {
            "type": "string",
            "example": "MIA"
          },
          "name": {
            "type": "string"
          },
          "city": {
            "type": "string",
            "nullable": true
          },
          "country": {
            "type": "string",
            "nullable": true,
            "example": "US"
          },
          "timezone": {
            "type": "string",
            "nullable": true
          },
          "lat": {
            "type": "number",
            "nullable": true
          },
          "lon": {
            "type": "number",
            "nullable": true
          },
          "terminals": {
            "type": "integer",
            "nullable": true
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at",
          "iata",
          "name"
        ]
      },
      "AirportInput": {
        "type": "object",
        "properties": {
          "iata": {
            "type": "string",
            "example": "MIA"
          },
          "name": {
            "type": "string"
          },
          "city": {
            "type": "string",
            "nullable": true
          },
          "country": {
            "type": "string",
            "nullable": true,
            "example": "US"
          },
          "timezone": {
            "type": "string",
            "nullable": true
          },
          "lat": {
            "type": "number",
            "nullable": true
          },
          "lon": {
            "type": "number",
            "nullable": true
          },
          "terminals": {
            "type": "integer",
            "nullable": true
          }
        },
        "required": [
          "iata",
          "name"
        ],
        "example": {
          "iata": "MIA",
          "name": "A name",
          "country": "US"
        }
      },
      "AirportList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Airport"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ListMeta"
          }
        }
      },
      "Airline": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "nullable": true,
            "description": "Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed.",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the record was created (ISO 8601, UTC).",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the record last changed.",
            "readOnly": true
          },
          "code": {
            "type": "string",
            "example": "SH"
          },
          "name": {
            "type": "string"
          },
          "alliance": {
            "type": "string",
            "nullable": true
          },
          "fleet_size": {
            "type": "integer",
            "nullable": true
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at",
          "code",
          "name"
        ]
      },
      "AirlineInput": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "example": "SH"
          },
          "name": {
            "type": "string"
          },
          "alliance": {
            "type": "string",
            "nullable": true
          },
          "fleet_size": {
            "type": "integer",
            "nullable": true
          }
        },
        "required": [
          "code",
          "name"
        ],
        "example": {
          "code": "SH",
          "name": "A name"
        }
      },
      "AirlineList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Airline"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ListMeta"
          }
        }
      },
      "Flight": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "nullable": true,
            "description": "Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed.",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the record was created (ISO 8601, UTC).",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the record last changed.",
            "readOnly": true
          },
          "number": {
            "type": "string",
            "example": "SH 1042"
          },
          "airline_id": {
            "type": "integer",
            "description": "The id of a airline."
          },
          "origin": {
            "type": "string",
            "description": "IATA code.",
            "example": "MIA"
          },
          "destination": {
            "type": "string",
            "example": "EZE"
          },
          "origin_airport_id": {
            "type": "integer",
            "nullable": true,
            "description": "The id of a airport."
          },
          "destination_airport_id": {
            "type": "integer",
            "nullable": true,
            "description": "The id of a airport."
          },
          "departure_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Local date at the origin."
          },
          "scheduled_departure": {
            "type": "string",
            "format": "date-time"
          },
          "scheduled_arrival": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "estimated_departure": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "actual_departure": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "scheduled",
              "boarding",
              "departed",
              "in_air",
              "landed",
              "delayed",
              "cancelled",
              "diverted"
            ],
            "nullable": true,
            "example": "scheduled"
          },
          "delay_minutes": {
            "type": "integer",
            "nullable": true,
            "minimum": 0
          },
          "gate": {
            "type": "string",
            "nullable": true,
            "example": "D14"
          },
          "terminal": {
            "type": "string",
            "nullable": true
          },
          "aircraft": {
            "type": "string",
            "nullable": true,
            "example": "A321neo"
          },
          "duration_minutes": {
            "type": "integer",
            "nullable": true
          },
          "distance_km": {
            "type": "integer",
            "nullable": true
          },
          "seats_total": {
            "type": "integer",
            "nullable": true
          },
          "seats_available": {
            "type": "integer",
            "nullable": true,
            "readOnly": true
          },
          "base_fare": {
            "type": "number",
            "nullable": true,
            "description": "USD, economy."
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at",
          "number",
          "airline_id",
          "origin",
          "destination",
          "scheduled_departure",
          "seats_available"
        ]
      },
      "FlightInput": {
        "type": "object",
        "properties": {
          "number": {
            "type": "string",
            "example": "SH 1042"
          },
          "airline_id": {
            "type": "integer",
            "description": "The id of a airline."
          },
          "origin": {
            "type": "string",
            "description": "IATA code.",
            "example": "MIA"
          },
          "destination": {
            "type": "string",
            "example": "EZE"
          },
          "origin_airport_id": {
            "type": "integer",
            "nullable": true,
            "description": "The id of a airport."
          },
          "destination_airport_id": {
            "type": "integer",
            "nullable": true,
            "description": "The id of a airport."
          },
          "departure_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Local date at the origin."
          },
          "scheduled_departure": {
            "type": "string",
            "format": "date-time"
          },
          "scheduled_arrival": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "estimated_departure": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "actual_departure": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "scheduled",
              "boarding",
              "departed",
              "in_air",
              "landed",
              "delayed",
              "cancelled",
              "diverted"
            ],
            "nullable": true,
            "example": "scheduled"
          },
          "delay_minutes": {
            "type": "integer",
            "nullable": true,
            "minimum": 0
          },
          "gate": {
            "type": "string",
            "nullable": true,
            "example": "D14"
          },
          "terminal": {
            "type": "string",
            "nullable": true
          },
          "aircraft": {
            "type": "string",
            "nullable": true,
            "example": "A321neo"
          },
          "duration_minutes": {
            "type": "integer",
            "nullable": true
          },
          "distance_km": {
            "type": "integer",
            "nullable": true
          },
          "seats_total": {
            "type": "integer",
            "nullable": true
          },
          "base_fare": {
            "type": "number",
            "nullable": true,
            "description": "USD, economy."
          }
        },
        "required": [
          "number",
          "airline_id",
          "origin",
          "destination",
          "scheduled_departure"
        ],
        "example": {
          "number": "SH 1042",
          "airline_id": 1,
          "origin": "MIA",
          "destination": "EZE",
          "scheduled_departure": "2026-09-30T12:00:00Z",
          "status": "scheduled",
          "gate": "D14",
          "aircraft": "A321neo"
        }
      },
      "FlightList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Flight"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ListMeta"
          }
        }
      },
      "Booking": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "nullable": true,
            "description": "Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed.",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the record was created (ISO 8601, UTC).",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the record last changed.",
            "readOnly": true
          },
          "locator": {
            "type": "string",
            "nullable": true,
            "description": "Six-character record locator, unique.",
            "example": "K7M2QX",
            "readOnly": true
          },
          "flight_id": {
            "type": "integer",
            "description": "The id of a flight."
          },
          "passenger": {
            "type": "object",
            "additionalProperties": true,
            "description": "Shape: { first_name, last_name, email, document? }"
          },
          "seat": {
            "type": "string",
            "nullable": true,
            "description": "Assigned by the hub on POST when omitted.",
            "example": "14C"
          },
          "cabin": {
            "type": "string",
            "enum": [
              "economy",
              "premium",
              "business",
              "first"
            ],
            "nullable": true,
            "example": "economy"
          },
          "status": {
            "type": "string",
            "enum": [
              "confirmed",
              "checked_in",
              "boarded",
              "cancelled",
              "no_show"
            ],
            "nullable": true,
            "example": "confirmed"
          },
          "fare": {
            "type": "number",
            "nullable": true,
            "minimum": 0
          },
          "currency": {
            "type": "string",
            "nullable": true
          },
          "bags": {
            "type": "integer",
            "nullable": true,
            "minimum": 0,
            "maximum": 5
          },
          "frequent_flyer": {
            "type": "string",
            "nullable": true
          },
          "special_requests": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Shape: string[]"
          },
          "booked_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "checked_in_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at",
          "locator",
          "flight_id",
          "passenger"
        ]
      },
      "BookingInput": {
        "type": "object",
        "properties": {
          "flight_id": {
            "type": "integer",
            "description": "The id of a flight."
          },
          "passenger": {
            "type": "object",
            "additionalProperties": true,
            "description": "Shape: { first_name, last_name, email, document? }"
          },
          "seat": {
            "type": "string",
            "nullable": true,
            "description": "Assigned by the hub on POST when omitted.",
            "example": "14C"
          },
          "cabin": {
            "type": "string",
            "enum": [
              "economy",
              "premium",
              "business",
              "first"
            ],
            "nullable": true,
            "example": "economy"
          },
          "status": {
            "type": "string",
            "enum": [
              "confirmed",
              "checked_in",
              "boarded",
              "cancelled",
              "no_show"
            ],
            "nullable": true,
            "example": "confirmed"
          },
          "fare": {
            "type": "number",
            "nullable": true,
            "minimum": 0
          },
          "currency": {
            "type": "string",
            "nullable": true
          },
          "bags": {
            "type": "integer",
            "nullable": true,
            "minimum": 0,
            "maximum": 5
          },
          "frequent_flyer": {
            "type": "string",
            "nullable": true
          },
          "special_requests": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Shape: string[]"
          },
          "booked_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "checked_in_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "flight_id",
          "passenger"
        ],
        "example": {
          "flight_id": 1,
          "passenger": {},
          "seat": "14C",
          "cabin": "economy",
          "status": "confirmed"
        }
      },
      "BookingList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Booking"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ListMeta"
          }
        }
      }
    }
  }
}