{
  "openapi": "3.1.0",
  "info": {
    "title": "Stellar Control",
    "description": "The HTTP and WebSocket API of Stellar Control: direct telecommands, current values, runs of procedures, alarms, passes and schedules, file transfers, and the state of the topology.\n\nThe API is stateless: it resolves every request against the current compiled configuration and publishes it on NATS. Several instances can serve the same cell.\n\n**Identity.** Callers identify themselves with an OIDC token (`Authorization: Bearer`), or declare themselves with `X-Stellar-User` (and `X-Stellar-Role`, comma-separated) where the environment of the run allows declared identities.\n\n**Errors.** Every error answers `{\"errors\": [{\"code\", \"message\", \"help\"}]}` with a stable `code`, such as `run::unknown-pass` or `tc::target-held`.\n\n**WebSocket.** The routes that follow something (`…/events`, `…/watch`, `…/throughput`) upgrade to a WebSocket: each text message is one JSON document of the schema given for the `101` response.",
    "license": {
      "name": "Proprietary"
    },
    "version": "0.1.0"
  },
  "servers": [
    {
      "url": "http://localhost:8080",
      "description": "The API of a local cell"
    }
  ],
  "paths": {
    "/v1/tc": {
      "post": {
        "tags": [
          "telecommands"
        ],
        "summary": "Submit a direct telecommand",
        "description": "Resolves the telecommand against the current configuration (its name alone when unique in the platform, else `component.name`; arguments as written in a run request, converted into their unit, checked against their range, completed by their defaults) and submits it to the executor, which runs it as an implicit one-step procedure: `requires`, then ACK 1 (driver), ACK 2 (gateway) and ACK 3 (`verify`). An `id` chosen by the client makes the submission idempotent.",
        "operationId": "submit_telecommand",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Submission"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Accepted: follow it on `GET /v1/tc/{target}/{id}/events`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubmissionReply"
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or identifier: `api::invalid-body`, `api::invalid-id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Unknown target.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "The target is held by a run: `tc::target-held`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "422": {
            "description": "The telecommand does not resolve: unknown telecommand or instance, invalid argument, component not carried by the link (`tc::link-component`), environment required (`tc::environment-required`)…",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/encode": {
      "post": {
        "tags": [
          "telecommands"
        ],
        "summary": "Encode a telecommand without sending it",
        "description": "Resolves the telecommand as `POST /v1/tc` does (catalogue, types, ranges, defaults, environment), then asks the driver bound to its link (or the one named by `driver`) what it makes of it, in the context of the link: its parameters in the environment, the mode of the target and its parameters. Nothing is sent and no lease is taken; a driver keeping a state (a sequence counter) may still advance it. The frame is the frame of the medium on a link without transport, the unit handed to the transport otherwise.",
        "operationId": "encode_telecommand",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EncodeBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The frame.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Encoded"
                }
              }
            }
          },
          "400": {
            "description": "Invalid body: `api::invalid-body`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Unknown target.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "No driver bound to the link and none named: `driver::unbound`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "422": {
            "description": "The telecommand does not resolve (the codes of `POST /v1/tc`), or the driver fails to encode it: `driver::encode-failed`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "501": {
            "description": "The driver does not answer the verb: `driver::no-verb`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "504": {
            "description": "The driver does not answer: `driver::no-answer`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/decode": {
      "post": {
        "tags": [
          "telecommands"
        ],
        "summary": "Decode a frame without publishing it",
        "description": "Asks the driver bound to a link of the target (or the one named by `driver`) for the raw samples of a frame, in the context of the link, and calibrates them with the catalogue of the target. Nothing is published: the current values and the archives do not change. On a link with a transport, the frame is the unit the transport hands to the driver.",
        "operationId": "decode_frame",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DecodeBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The samples of the frame.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Decoded"
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or frame: `api::invalid-body`, `api::invalid-frame`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Unknown target: `api::unknown-target`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "No driver bound to the link and none named: `driver::unbound`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "422": {
            "description": "Unknown link or environment (`api::unknown-link`, `api::unknown-environment`), or the driver fails to decode the frame: `driver::decode-failed`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "501": {
            "description": "The driver does not answer the verb: `driver::no-verb`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "504": {
            "description": "The driver does not answer: `driver::no-answer`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/tc/{target}/{id}/events": {
      "get": {
        "tags": [
          "telecommands"
        ],
        "summary": "Follow a telecommand (WebSocket)",
        "description": "Replays the events of the telecommand, then follows the new ones, and closes on a final state (`REJECTED`, `ENCODE_FAILED`, `SEND_FAILED`, `VERIFIED`, `VERIFY_FAILED`, `VERIFY_TIMEOUT`, `COMPLETE`). Each message is a `TcEvent`.",
        "operationId": "follow_telecommand",
        "parameters": [
          {
            "name": "target",
            "in": "path",
            "description": "Target, as named in the topology (`sim-1`).",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "path",
            "description": "Telecommand identifier (ULID).",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "101": {
            "description": "WebSocket: one `TcEvent` per message.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TcEvent"
                }
              }
            }
          },
          "404": {
            "description": "Invalid target or identifier.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/tc/watch": {
      "get": {
        "tags": [
          "telecommands"
        ],
        "summary": "Follow every telecommand (WebSocket)",
        "description": "The events of the telecommands of every target (or of `target`) from now, in order, each with its target: PENDING names the telecommand, the next ones follow its chain of acknowledgements. Each message is a `TcWatched`.",
        "operationId": "watch_telecommands",
        "parameters": [
          {
            "name": "target",
            "in": "query",
            "description": "Only the telecommands of this target.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "101": {
            "description": "WebSocket: one `TcWatched` per message.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TcWatched"
                }
              }
            }
          },
          "404": {
            "description": "Invalid target.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/targets/{target}/values": {
      "get": {
        "tags": [
          "values"
        ],
        "summary": "Current values of a target",
        "description": "The latest sample of every measure and derived measure of the target, from the current value table (`stellar_values`).",
        "operationId": "current_values",
        "parameters": [
          {
            "name": "target",
            "in": "path",
            "description": "Target, as named in the topology (`sim-1`).",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current values, by key order.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Values"
                }
              }
            }
          },
          "404": {
            "description": "Invalid target.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/targets/{target}/values/watch": {
      "get": {
        "tags": [
          "values"
        ],
        "summary": "Watch the values of a target (WebSocket)",
        "description": "Sends the current values, then every update of the table. A measure is selected as `tcu[TCU1].responding` (one instance), `tcu.responding` (every instance) or `responding` (any component).",
        "operationId": "watch_values",
        "parameters": [
          {
            "name": "target",
            "in": "path",
            "description": "Target, as named in the topology (`sim-1`).",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "measures",
            "in": "query",
            "description": "Comma-separated measures; every measure without.",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "tcu[TCU1].responding,psu.voltage"
          }
        ],
        "responses": {
          "101": {
            "description": "WebSocket: one `CurrentValue` per message.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CurrentValue"
                }
              }
            }
          },
          "400": {
            "description": "Invalid measure selector: `api::invalid-measure`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Invalid target.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/targets/{target}/values/history": {
      "get": {
        "tags": [
          "values"
        ],
        "summary": "History of a measure",
        "description": "The samples of one measure or derived measure of the target over a window, as the compute stage published them. Beyond `limit` samples in the window, one in every few is kept (`thinned`), the last one always.",
        "operationId": "value_history",
        "parameters": [
          {
            "name": "target",
            "in": "path",
            "description": "Target, as named in the topology (`sim-1`).",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "measure",
            "in": "query",
            "description": "The measure: `tcu[TCU1].anode_voltage`, or `psu.voltage` for a component without instances.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "tcu[TCU1].anode_voltage"
          },
          {
            "name": "from",
            "in": "query",
            "description": "Start of the window (RFC 3339); 10 min before `to` by default.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "description": "End of the window (RFC 3339); now by default.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Samples returned at most: 2000 by default, 20000 at most.",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The samples of the window.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/History"
                }
              }
            }
          },
          "400": {
            "description": "Invalid measure or query: `api::invalid-measure`, `api::invalid-query`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Invalid target.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/targets/{target}/mode": {
      "get": {
        "tags": [
          "modes"
        ],
        "summary": "Current mode of a target",
        "description": "The mode the target is in (`stellar_modes`), else the default mode of the topology, with the modes of the topology and who set it last: an operator, or a run at the end of a `configure`.",
        "operationId": "get_mode",
        "parameters": [
          {
            "name": "target",
            "in": "path",
            "description": "Target, as named in the topology (`sim-1`).",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The mode of the target.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModeView"
                }
              }
            }
          },
          "404": {
            "description": "Unknown target: `api::unknown-target`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "modes"
        ],
        "summary": "Declare the mode of a target",
        "description": "Says which mode the target is in, as the operator of the request, without sending anything: after a manual reconfiguration, for instance. A `configure` of a run sets it by itself. Refused while a run holds the target.",
        "operationId": "set_mode",
        "parameters": [
          {
            "name": "target",
            "in": "path",
            "description": "Target, as named in the topology (`sim-1`).",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ModeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The mode, as recorded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModeView"
                }
              }
            }
          },
          "400": {
            "description": "Invalid body, or no identity: `api::invalid-body`, `api::anonymous`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Unknown target: `api::unknown-target`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "A run holds the target: `mode::target-held`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "422": {
            "description": "Not a mode of the topology: `mode::unknown`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/targets/{target}/parameters": {
      "get": {
        "tags": [
          "modes"
        ],
        "summary": "Parameters of a target",
        "description": "The parameters of the components of the target, in the order of the catalogue: their value in each mode (per-target values of the topology, with the overrides of the environment), the value of the current mode, the telecommand that sets it, and its readback with the current sample and whether it matches within the tolerance.",
        "operationId": "get_parameters",
        "parameters": [
          {
            "name": "target",
            "in": "path",
            "description": "Target, as named in the topology (`sim-1`).",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "environment",
            "in": "query",
            "description": "Environment of the overrides; by default the only environment of the target, else none.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ParametersView"
                }
              }
            }
          },
          "404": {
            "description": "Unknown target: `api::unknown-target`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "422": {
            "description": "The target is not engaged in the environment: `api::unknown-environment`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The catalogue of the target is missing (`api::no-catalogue`), or the MCS bus is unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/runs": {
      "get": {
        "tags": [
          "runs"
        ],
        "summary": "Recent runs",
        "description": "The most recent runs, newest first, with their state computed from their logs.",
        "operationId": "list_runs",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "How many runs: 20 by default, 200 at most.",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Runs, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Runs"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "runs"
        ],
        "summary": "Launch a run",
        "description": "Resolves the run request against the current configuration into a self-contained resolved run, stores it in `stellar_ir` and submits it to the executor. The environment applies its policies: allowed procedures, draft packages, identity, hazardous telecommands only from a schedule where planning is mandatory. A run bound to a pass (`plan`) must start within it and fit before its LOS minus `scheduler.margin`; a manual run in `in_orbit` needs an available link.",
        "operationId": "launch_run",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Submitted: follow it on `GET /v1/runs/{id}/events`. `warnings` names the passes in progress it may outlast.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunReply"
                }
              }
            }
          },
          "400": {
            "description": "Invalid body: `api::invalid-body`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "Identity required by the environment: `api::anonymous`, `auth::jwt-required`, `auth::invalid-token`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "Refused by the passes: `run::pass-cancelled`, `run::not-booked`, `run::before-aos`, `run::window`, `run::receive-only`, `run::no-link`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "422": {
            "description": "The request does not resolve, or breaks a policy: `run::not-allowed`, `run::draft-not-allowed`, `run::plan-required`, `run::must-be-scheduled`, `run::unknown-pass`, `run::link-component`…",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/runs/{id}": {
      "get": {
        "tags": [
          "runs"
        ],
        "summary": "State of a run",
        "description": "Computed from its log: step running, suspended, question or decision waiting (with the role awaited for a hazardous confirmation), outcome.",
        "operationId": "run_status",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Run identifier (ULID).",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "State of the run.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunStatus"
                }
              }
            }
          },
          "404": {
            "description": "Invalid identifier or no such run: `run::unknown`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/runs/{id}/events": {
      "get": {
        "tags": [
          "runs"
        ],
        "summary": "Follow a run (WebSocket)",
        "description": "Replays the log of the run, then follows it until its `finished` event. Each message is a `RunEvent`.",
        "operationId": "follow_run",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Run identifier (ULID).",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "101": {
            "description": "WebSocket: one `RunEvent` per message.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunEvent"
                }
              }
            }
          },
          "404": {
            "description": "Invalid identifier.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/runs/{id}/answers": {
      "post": {
        "tags": [
          "runs"
        ],
        "summary": "Answer a question or a decision",
        "description": "Answers the `ask` of a step (a confirmation, or a typed value) or a decision (`replay`, `skip`, `fail` or `abort` in `value`), as the operator identified by the request. The executor checks the answer: role expected, a person who has not confirmed the step yet, token checked again with `identity: jwt`; a refused answer is logged as `answer_refused`.",
        "operationId": "answer_run",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Run identifier (ULID).",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Answer"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Answer published to the executor."
          },
          "400": {
            "description": "Invalid body, or no identity: `api::invalid-body`, `api::anonymous`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "Identity refused by the environment of the run.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Invalid identifier or no such run.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/runs/{id}/{action}": {
      "post": {
        "tags": [
          "runs"
        ],
        "summary": "Suspend, resume or abort a run",
        "description": "`suspend` takes effect at the end of the current instruction and releases the leases of the run; `resume` takes them back, checks the targets again and applies the choice of the operator (`replay` the step where the run stopped, `skip` it, or `abort`); `abort` ends the run for good, without its `if failed` blocks. The command goes to the executor holding the run.",
        "operationId": "control_run",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Run identifier (ULID).",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "action",
            "in": "path",
            "description": "`suspend`, `resume` or `abort`.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "For `resume` only: the choice of the operator.",
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/Resume"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Command accepted by the executor."
          },
          "400": {
            "description": "Invalid body, or no identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Invalid identifier, or unknown command: `api::unknown-command`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "The run is not running (`run::not-running`) or the executor refused the command (`run::refused`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "504": {
            "description": "The executor did not answer: `run::timeout`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/runs/{id}/report": {
      "get": {
        "tags": [
          "runs"
        ],
        "summary": "Test report of a run",
        "description": "The HTML report archived at the end of the run (`stellar_reports`), else rendered from its log so far. The same log always gives the same report.",
        "operationId": "run_report",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Run identifier (ULID).",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The report.",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Invalid identifier or no such run.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/alarms": {
      "get": {
        "tags": [
          "alarms"
        ],
        "summary": "Alarms",
        "description": "The alarms not NORMAL or shelved, from `stellar_alarms`; every alarm recorded with `all`.",
        "operationId": "list_alarms",
        "parameters": [
          {
            "name": "target",
            "in": "query",
            "description": "Only the alarms of this target.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "all",
            "in": "query",
            "description": "Every alarm recorded, NORMAL included.",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Alarms, by key order.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Alarms"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/alarms/watch": {
      "get": {
        "tags": [
          "alarms"
        ],
        "summary": "Follow the alarm transitions (WebSocket)",
        "description": "Every transition from now, in order. Each message is an `AlarmEvent`.",
        "operationId": "watch_alarms",
        "parameters": [
          {
            "name": "target",
            "in": "query",
            "description": "Only the transitions of this target.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "101": {
            "description": "WebSocket: one `AlarmEvent` per message.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AlarmEvent"
                }
              }
            }
          },
          "404": {
            "description": "Invalid target.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/alarms/{target}/{alarm}/{action}": {
      "post": {
        "tags": [
          "alarms"
        ],
        "summary": "Acknowledge, shelve or unshelve an alarm",
        "description": "`acknowledge` moves ACTIVE_UNACK to ACTIVE_ACK and CLEARED_UNACK to NORMAL; `shelve` silences the reactions of the alarm for a bounded duration (at most `alarms.max_shelve`); `unshelve` ends it. The command goes to the alarm service, traced with the identity of the operator.",
        "operationId": "command_alarm",
        "parameters": [
          {
            "name": "target",
            "in": "path",
            "description": "Target, as named in the topology (`sim-1`).",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "alarm",
            "in": "path",
            "description": "Alarm: `tcu[TCU1].anode_voltage`, or `eps.undervoltage` without instance.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "action",
            "in": "path",
            "description": "`acknowledge`, `shelve` or `unshelve`.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "For `shelve` only: its duration.",
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/Shelve"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Command applied."
          },
          "400": {
            "description": "Invalid body, or no identity: `api::anonymous`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Invalid target or alarm, or unknown command.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "Refused: nothing to acknowledge, alarm not shelved or never recorded, duration out of bounds (`alarm::refused`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "No alarm service is running: `alarm::no-service`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "504": {
            "description": "The alarm service did not answer: `alarm::timeout`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/passes": {
      "get": {
        "tags": [
          "passes"
        ],
        "summary": "Passes",
        "description": "The passes not over yet, every pass with `all`, each with the gateway the reconciler checked for it before the AOS.",
        "operationId": "list_passes",
        "parameters": [
          {
            "name": "target",
            "in": "query",
            "description": "Only the passes of this target.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "all",
            "in": "query",
            "description": "Passes over too.",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Passes, by AOS.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Passes"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "passes"
        ],
        "summary": "Write a pass (feeder)",
        "description": "A pass from a feeder (`passes.feeders`), new or refined, merged with the pass of the other source: matched by identifier, by the identifier of a contribution, then by target, station and overlapping window. The booking gives the window, the elevation, the status and `uplink`.",
        "operationId": "upsert_pass",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Pass"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The pass as stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PassView"
                }
              }
            }
          },
          "401": {
            "description": "Token refused.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "Not a feeder (`pass::not-a-feeder`), or not its source (`pass::forbidden-source`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "422": {
            "description": "Invalid pass or unknown target: `pass::invalid`, `pass::unknown-target`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/passes/{target}/{id}": {
      "get": {
        "tags": [
          "passes"
        ],
        "summary": "A pass",
        "operationId": "get_pass",
        "parameters": [
          {
            "name": "target",
            "in": "path",
            "description": "Target, as named in the topology (`sim-1`).",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "path",
            "description": "Pass identifier.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The pass and its gateway.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PassView"
                }
              }
            }
          },
          "404": {
            "description": "No such pass: `pass::unknown`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/passes/replace_window": {
      "post": {
        "tags": [
          "passes"
        ],
        "summary": "Replace the passes of a window (feeder)",
        "description": "A complete snapshot of a source for a target over an interval: each pass is written, and the contribution of the source to every pass of the interval absent from the snapshot is cancelled.",
        "operationId": "replace_window",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceWindow"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "What was written and cancelled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Replaced"
                }
              }
            }
          },
          "401": {
            "description": "Token refused.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "Not a feeder, or not its source.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "422": {
            "description": "Invalid snapshot or unknown target.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/passes/watch": {
      "get": {
        "tags": [
          "passes"
        ],
        "summary": "Watch the passes (WebSocket)",
        "description": "Sends every pass with the check of its gateway, then each pass whose definition or gateway check changes.",
        "operationId": "watch_passes",
        "parameters": [
          {
            "name": "target",
            "in": "query",
            "description": "Only those of this target.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "101": {
            "description": "WebSocket: one `PassView` per message.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PassView"
                }
              }
            }
          },
          "404": {
            "description": "Invalid target: `api::invalid-target`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schedules": {
      "get": {
        "tags": [
          "schedules"
        ],
        "summary": "Schedules",
        "description": "The schedules not final (`scheduled`, `at_risk`), every one with `all` (`fired`, `missed`, `cancelled` too).",
        "operationId": "list_schedules",
        "parameters": [
          {
            "name": "pass",
            "in": "query",
            "description": "Only the schedules of this pass.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "all",
            "in": "query",
            "description": "Final schedules too.",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Schedules, by start.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Schedules"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "schedules"
        ],
        "summary": "Schedule a run on a pass",
        "description": "Resolves the run request on the current configuration with `plan` = the pass, stores the resolved run and keeps its maximum duration. The runs of a pass must fit between their start and LOS minus `scheduler.margin`, in order; in `in_orbit`, the pass must be booked. A schedule not fired yet can be replaced under the same identifier. A schedule whose run sends a hazardous telecommand where a supervisor confirms needs a validation (`needs_validation`).",
        "operationId": "create_schedule",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Schedule"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "The schedule as stored, with its state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Schedule"
                }
              }
            }
          },
          "401": {
            "description": "Identity required by the environment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "422": {
            "description": "Invalid, unresolved or refused schedule: `schedule::invalid`, `schedule::refused`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schedules/{id}": {
      "get": {
        "tags": [
          "schedules"
        ],
        "summary": "A schedule",
        "operationId": "get_schedule",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Schedule identifier.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The schedule.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Schedule"
                }
              }
            }
          },
          "404": {
            "description": "No such schedule: `schedule::unknown`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schedules/{id}/cancel": {
      "post": {
        "tags": [
          "schedules"
        ],
        "summary": "Cancel a schedule",
        "description": "Cancels a schedule not final yet, as the operator of `X-Stellar-User`.",
        "operationId": "cancel_schedule",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Schedule identifier.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The cancelled schedule.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Schedule"
                }
              }
            }
          },
          "404": {
            "description": "No such schedule.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "Already final (`schedule::final`), or changed meanwhile (`schedule::changed`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schedules/{id}/validate": {
      "post": {
        "tags": [
          "schedules"
        ],
        "summary": "Validate the plan of a schedule (supervisor)",
        "description": "A supervisor validates the plan of a schedule as it is: its resolved run (procedure, inputs, targets), its pass, and the AOS and LOS of the pass. Any later change of them makes the validation fall, and the schedule is `at_risk` again.",
        "operationId": "validate_schedule",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Schedule identifier.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The validated schedule.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Schedule"
                }
              }
            }
          },
          "401": {
            "description": "No identity, or refused by the environment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "Not a supervisor: `schedule::not-supervisor`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "No such schedule.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "422": {
            "description": "Refused: `schedule::refused`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schedule-rules": {
      "get": {
        "tags": [
          "schedules"
        ],
        "summary": "Recurring rules",
        "operationId": "list_schedule_rules",
        "responses": {
          "200": {
            "description": "Rules, by identifier.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Rules"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "schedules"
        ],
        "summary": "Write a recurring rule",
        "description": "A rule that schedules its run on every pass of its target matching its filter (`status`, `min_elevation`, `station`, `uplink`), as the scheduler sees the passes arrive. Its request is resolved on the current configuration; a procedure that sends a hazardous telecommand is refused.",
        "operationId": "create_schedule_rule",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScheduleRule"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "The rule as stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduleRule"
                }
              }
            }
          },
          "422": {
            "description": "Invalid or refused rule: `schedule::invalid`, `schedule::refused`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schedule-rules/{id}": {
      "delete": {
        "tags": [
          "schedules"
        ],
        "summary": "Remove a recurring rule",
        "description": "No new schedule from the rule; the schedules it made remain.",
        "operationId": "delete_schedule_rule",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Rule identifier.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Removed."
          },
          "404": {
            "description": "No such rule: `schedule::unknown-rule`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/schedules/watch": {
      "get": {
        "tags": [
          "schedules"
        ],
        "summary": "Watch the schedules (WebSocket)",
        "description": "Sends every schedule, then each one that changes (scheduled, at risk, cancelled, fired, missed).",
        "operationId": "watch_schedules",
        "parameters": [
          {
            "name": "target",
            "in": "query",
            "description": "Only the schedules on the passes of this target.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "101": {
            "description": "WebSocket: one `Schedule` per message.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Schedule"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/targets/{target}/files": {
      "get": {
        "tags": [
          "files"
        ],
        "summary": "On-board directory",
        "description": "The files of the last listings of the target (the instances of its `files` component in the current value table), by identifier, with the date each was last listed and the state of its transfer.",
        "operationId": "list_files",
        "parameters": [
          {
            "name": "target",
            "in": "path",
            "description": "Target, as named in the topology (`sim-1`).",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The directory.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Directory"
                }
              }
            }
          },
          "404": {
            "description": "Unknown target, or no on-board directory: `files::no-directory`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/targets/{target}/files/refresh": {
      "post": {
        "tags": [
          "files"
        ],
        "summary": "List the on-board directory",
        "description": "Sends the listing telecommand of the catalogue (`transfer.list`) as a direct telecommand.",
        "operationId": "refresh_files",
        "parameters": [
          {
            "name": "target",
            "in": "path",
            "description": "Target, as named in the topology (`sim-1`).",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "The listing telecommand, submitted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubmissionReply"
                }
              }
            }
          },
          "404": {
            "description": "Unknown target, or no on-board directory.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "The target is held by a run.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "422": {
            "description": "No listing telecommand: `files::no-listing`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/transfers": {
      "get": {
        "tags": [
          "files"
        ],
        "summary": "File transfers",
        "operationId": "list_transfers",
        "parameters": [
          {
            "name": "target",
            "in": "query",
            "description": "Only the transfers of this target.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Transfers, by priority then age.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transfers"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "files"
        ],
        "summary": "Download an on-board file",
        "description": "Creates the download of the current generation of a file, as last listed; the transfer already there when it exists. The transfer manager then asks the missing ranges, pass after pass.",
        "operationId": "create_transfer",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DownloadRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "The transfer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transfer"
                }
              }
            }
          },
          "404": {
            "description": "Unknown target.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request, no on-board directory, or file never listed: `transfer::invalid`, `files::no-directory`, `transfer::not-listed`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/transfers/{target}/{file_id}/{generation}": {
      "get": {
        "tags": [
          "files"
        ],
        "summary": "A file transfer",
        "operationId": "get_transfer",
        "parameters": [
          {
            "name": "target",
            "in": "path",
            "description": "Target, as named in the topology (`sim-1`).",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "file_id",
            "in": "path",
            "description": "On-board file identifier.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "generation",
            "in": "path",
            "description": "Generation of the file.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "direction",
            "in": "query",
            "description": "`upload` for an upload; a download without.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The transfer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transfer"
                }
              }
            }
          },
          "404": {
            "description": "No such transfer: `transfer::unknown`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/uploads": {
      "post": {
        "tags": [
          "files"
        ],
        "summary": "Store a content to upload",
        "description": "Stores the body (256 MiB at most) in the `stellar_uploads` object store under its SHA-256. The hash is the value of a `file` input of a run whose procedure uploads it (`upload <input> to sat.files[x]`).",
        "operationId": "store_upload",
        "requestBody": {
          "description": "The raw content, any bytes.",
          "content": {
            "application/octet-stream": {
              "schema": {
                "type": "string"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoredContent"
                }
              }
            }
          },
          "413": {
            "description": "Content larger than 256 MiB.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/transfers/watch": {
      "get": {
        "tags": [
          "files"
        ],
        "summary": "Watch the file transfers (WebSocket)",
        "description": "Sends every transfer, then each one that changes state or progresses.",
        "operationId": "watch_transfers",
        "parameters": [
          {
            "name": "target",
            "in": "query",
            "description": "Only those of this target.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "101": {
            "description": "WebSocket: one `Transfer` per message.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transfer"
                }
              }
            }
          },
          "404": {
            "description": "Invalid target: `api::invalid-target`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/topology": {
      "get": {
        "tags": [
          "monitoring"
        ],
        "summary": "Topology",
        "description": "The targets of the current configuration, their links as declared and as bound, readiness with its reasons, configuration revision and leases.",
        "operationId": "get_topology",
        "responses": {
          "200": {
            "description": "The topology and its state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TopologyView"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/instances": {
      "get": {
        "tags": [
          "monitoring"
        ],
        "summary": "Instances",
        "description": "The drivers, transports, gateways, connectors and components registered with the reconciler, with their health and the links bound to them.",
        "operationId": "list_instances",
        "responses": {
          "200": {
            "description": "Instances.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InstancesView"
                }
              }
            }
          }
        }
      }
    },
    "/v1/instances/{kind}/{instance}": {
      "get": {
        "tags": [
          "monitoring"
        ],
        "summary": "An instance",
        "description": "An instance, what it implements (a driver: catalogue coverage against the current configuration) or offers (a gateway: tags, link types and rates), its own status (the `status` verb), and the links bound to it with the consumers of their telecommands (delivered, pending, not acknowledged, redelivered).",
        "operationId": "get_instance",
        "parameters": [
          {
            "name": "kind",
            "in": "path",
            "description": "`driver`, `transport`, `gateway`, `connector` or a component of the MCS.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "instance",
            "in": "path",
            "description": "Instance name.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The instance.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InstanceDetail"
                }
              }
            }
          },
          "404": {
            "description": "No such instance.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/instances/gateway/{instance}/throughput": {
      "get": {
        "tags": [
          "monitoring"
        ],
        "summary": "Throughput of a gateway (WebSocket)",
        "description": "The throughput reports of a gateway, per target, as it publishes them every `metrics_period`.",
        "operationId": "watch_throughput",
        "parameters": [
          {
            "name": "instance",
            "in": "path",
            "description": "Gateway instance.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "101": {
            "description": "WebSocket: one `ThroughputView` per message.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThroughputView"
                }
              }
            }
          },
          "404": {
            "description": "Invalid instance.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/targets/{target}/catalogue": {
      "get": {
        "tags": [
          "monitoring"
        ],
        "summary": "Catalogue of a target",
        "description": "The components of the platform of the target, their instances, measures (limits included) and telecommands (arguments, `changes_state`, `hazardous`), with their descriptions.",
        "operationId": "get_catalogue",
        "parameters": [
          {
            "name": "target",
            "in": "path",
            "description": "Target, as named in the topology (`sim-1`).",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The catalogue.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogueView"
                }
              }
            }
          },
          "404": {
            "description": "Unknown target.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/procedures": {
      "get": {
        "tags": [
          "monitoring"
        ],
        "summary": "Procedures",
        "description": "The procedures of every library of the current configuration, with their roles, inputs, environments, maximum duration and whether they send a hazardous telecommand: what a run request needs.",
        "operationId": "list_procedures",
        "responses": {
          "200": {
            "description": "Procedures.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProceduresView"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/connectors": {
      "get": {
        "tags": [
          "monitoring"
        ],
        "summary": "Output connectors",
        "description": "The output connectors of the topology, their instance, and the lag of each of their consumers computed now (messages not delivered, not acknowledged, age of the oldest, at risk of being removed by the retention).",
        "operationId": "list_connectors",
        "responses": {
          "200": {
            "description": "Connectors.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectorsView"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/reconciler/events": {
      "get": {
        "tags": [
          "monitoring"
        ],
        "summary": "Journal of the reconciler",
        "description": "The changes the reconciler made to the bindings of the links (bound, unbound, rebound) and to the readiness and revision of the targets, newest first.",
        "operationId": "reconciler_events",
        "parameters": [
          {
            "name": "target",
            "in": "query",
            "description": "Only the changes of this target.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "since",
            "in": "query",
            "description": "Start of the window (RFC 3339); 24 h ago by default.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Newest entries returned: 200 by default, 5000 at most.",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The entries, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Journal"
                }
              }
            }
          },
          "400": {
            "description": "Invalid query: `api::invalid-query`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Invalid target: `api::invalid-target`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/reconciler/events/watch": {
      "get": {
        "tags": [
          "monitoring"
        ],
        "summary": "Follow the journal of the reconciler (WebSocket)",
        "description": "Sends every change of the reconciler from now on.",
        "operationId": "watch_reconciler_events",
        "parameters": [
          {
            "name": "target",
            "in": "query",
            "description": "Only the changes of this target.",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "101": {
            "description": "WebSocket: one journal `Entry` per message.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Entry"
                }
              }
            }
          },
          "404": {
            "description": "Invalid target: `api::invalid-target`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/auth/nats": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "NATS credentials of follow-up",
        "description": "Exchanges a checked OIDC token for a NATS user JWT valid `auth.nats_ttl`, signed with the account signing key, for the given user nkey. It may only subscribe to `stellar.run.evt.>`, `stellar.alarm.evt.>` and `_INBOX.>`, and publish nothing.",
        "operationId": "nats_credentials",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NatsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The JWT and its expiry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NatsCredentials"
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or key: `api::invalid-body`, `auth::invalid-key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "No token, or refused: `auth::jwt-required`, `auth::invalid-token`, `auth::no-provider`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "No account signing key: `auth::no-signing-key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        },
        "security": [
          {
            "oidc": []
          }
        ]
      }
    },
    "/v1/auth/config": {
      "get": {
        "tags": [
          "auth"
        ],
        "summary": "How to sign in",
        "description": "The identity provider, the public clients of the web console and of the CLI (`auth.issuer`, `auth.client_id`, `auth.cli_client_id`, `auth.organization`), without identity: the console and `stellar login` ask it before signing in.",
        "operationId": "auth_config",
        "responses": {
          "200": {
            "description": "The sign-in, if any.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthSettings"
                }
              }
            }
          }
        },
        "security": [
          {}
        ]
      }
    },
    "/v1/sim/{gateway}/faults": {
      "get": {
        "tags": [
          "simulation"
        ],
        "summary": "Faults of a simulated target",
        "description": "The fault scenarios of the simulation played by the gateway, and whether each is active (its `faults` verb).",
        "operationId": "list_faults",
        "parameters": [
          {
            "name": "gateway",
            "in": "path",
            "description": "Gateway instance of the simulated target (`sim-gw-1`).",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The reply of the simulator.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "No simulated gateway answers: `sim::unknown-gateway`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "422": {
            "description": "Not a simulated gateway, or refused: `sim::not-simulated`, `sim::refused`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "504": {
            "description": "The gateway did not answer: `sim::timeout`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/sim/{gateway}/faults/{fault}": {
      "put": {
        "tags": [
          "simulation"
        ],
        "summary": "Switch a fault on or off",
        "description": "While a fault is active, its values replace those of the model of the simulation. Each change is published on `stellar.sim.evt.<target>`, so that reports show the faults active during a run.",
        "operationId": "switch_fault",
        "parameters": [
          {
            "name": "gateway",
            "in": "path",
            "description": "Gateway instance of the simulated target.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fault",
            "in": "path",
            "description": "Fault, as named in the simulation.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Switch"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The reply of the simulator.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Invalid body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "No simulated gateway answers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "422": {
            "description": "Unknown fault, or not a simulated gateway.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "The MCS bus (NATS) is unavailable: `api::unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "504": {
            "description": "The gateway did not answer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/openapi.json": {
      "get": {
        "tags": [
          "meta"
        ],
        "summary": "`GET /v1/openapi.json`: this document.",
        "operationId": "openapi_document",
        "responses": {
          "200": {
            "description": "The OpenAPI 3.1 document of the API.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Alarm": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AlarmRef",
            "description": "Alarm."
          },
          {
            "type": "object",
            "required": [
              "target",
              "record"
            ],
            "properties": {
              "target": {
                "type": "string",
                "description": "Target."
              },
              "record": {
                "$ref": "#/components/schemas/AlarmRecord",
                "description": "Current state."
              }
            }
          }
        ],
        "description": "An alarm and its current state."
      },
      "AlarmCause": {
        "description": "Cause of an alarm transition.",
        "oneOf": [
          {
            "description": "The condition changed.",
            "enum": [
              "condition"
            ],
            "type": "string"
          },
          {
            "description": "Acknowledged by an operator.",
            "enum": [
              "acknowledged"
            ],
            "type": "string"
          },
          {
            "description": "Shelved by an operator.",
            "enum": [
              "shelved"
            ],
            "type": "string"
          },
          {
            "description": "Unshelved by an operator, or at the end of the shelving.",
            "enum": [
              "unshelved"
            ],
            "type": "string"
          }
        ]
      },
      "AlarmEvent": {
        "additionalProperties": false,
        "description": "Transition of an alarm, on `stellar.alarm.evt.<target>.<component>.<instance>.<alarm>`\n(stream `ALARMS`, `Nats-Msg-Id` `<target>.<component>.<instance>.<alarm>-<seq>`).",
        "properties": {
          "alarm": {
            "description": "Alarm: its name, or the measure of the limits.",
            "type": "string"
          },
          "at": {
            "description": "Time of the transition.",
            "type": "string"
          },
          "by": {
            "description": "Operator, for an acknowledgement or a shelving.",
            "type": [
              "string",
              "null"
            ]
          },
          "cause": {
            "$ref": "#/components/schemas/AlarmCause",
            "description": "Cause."
          },
          "component": {
            "description": "Component.",
            "type": "string"
          },
          "instance": {
            "description": "Component instance.",
            "type": [
              "string",
              "null"
            ]
          },
          "previous": {
            "$ref": "#/components/schemas/AlarmState",
            "description": "State before."
          },
          "seq": {
            "description": "Number of the transition.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "severity": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AlarmSeverity"
              },
              {
                "type": "null"
              }
            ],
            "description": "Severity of the activation."
          },
          "shelved_until": {
            "description": "End of the shelving in progress.",
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "$ref": "#/components/schemas/AlarmState",
            "description": "State after."
          },
          "target": {
            "description": "Target.",
            "type": "string"
          },
          "value": {
            "description": "Value of the measure, for the alarm of its limits."
          }
        },
        "required": [
          "target",
          "component",
          "alarm",
          "previous",
          "state",
          "at",
          "seq",
          "cause"
        ],
        "title": "Stellar Control alarm transition",
        "type": "object"
      },
      "AlarmRecord": {
        "additionalProperties": false,
        "description": "Current state of an alarm, in `stellar_alarms` under\n`<target>.<component>.<instance>.<alarm>`.",
        "properties": {
          "active_since": {
            "description": "Start of the activation.",
            "type": [
              "string",
              "null"
            ]
          },
          "by": {
            "description": "Operator of the last transition, when not the condition.",
            "type": [
              "string",
              "null"
            ]
          },
          "cause": {
            "$ref": "#/components/schemas/AlarmCause",
            "default": "condition",
            "description": "Cause of the last transition."
          },
          "changed_at": {
            "description": "Last transition.",
            "type": [
              "string",
              "null"
            ]
          },
          "previous": {
            "$ref": "#/components/schemas/AlarmState",
            "default": "NORMAL",
            "description": "State before the last transition."
          },
          "seq": {
            "description": "Number of the last transition, from 1; the transition event bears it.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "severity": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AlarmSeverity"
              },
              {
                "type": "null"
              }
            ],
            "description": "Severity of the activation; kept while cleared and unacknowledged."
          },
          "shelved_until": {
            "description": "End of the shelving: until then, the alarm triggers no reaction.",
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "$ref": "#/components/schemas/AlarmState",
            "description": "State."
          },
          "value": {
            "description": "Value of the measure at the last transition, for the alarm of its limits."
          }
        },
        "required": [
          "state",
          "seq"
        ],
        "type": "object"
      },
      "AlarmRef": {
        "additionalProperties": false,
        "description": "An alarm of a target: `(component, instance, alarm)`.",
        "properties": {
          "alarm": {
            "description": "Alarm: its name, or the measure of the limits.",
            "type": "string"
          },
          "component": {
            "description": "Component.",
            "type": "string"
          },
          "instance": {
            "description": "Component instance.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "component",
          "alarm"
        ],
        "type": "object"
      },
      "AlarmSeverity": {
        "description": "Severity of an alarm.",
        "oneOf": [
          {
            "description": "Outside the soft limits, or a named `warning` alarm.",
            "enum": [
              "warning"
            ],
            "type": "string"
          },
          {
            "description": "Outside the hard limits, or a named `critical` alarm.",
            "enum": [
              "critical"
            ],
            "type": "string"
          }
        ]
      },
      "AlarmState": {
        "description": "State of an alarm (spec « Alarmes »).",
        "oneOf": [
          {
            "description": "Condition false, nothing to acknowledge.",
            "enum": [
              "NORMAL"
            ],
            "type": "string"
          },
          {
            "description": "Condition true, not acknowledged.",
            "enum": [
              "ACTIVE_UNACK"
            ],
            "type": "string"
          },
          {
            "description": "Condition true, acknowledged.",
            "enum": [
              "ACTIVE_ACK"
            ],
            "type": "string"
          },
          {
            "description": "Condition false again, activation not acknowledged.",
            "enum": [
              "CLEARED_UNACK"
            ],
            "type": "string"
          }
        ]
      },
      "Alarms": {
        "type": "object",
        "description": "Body of `GET /v1/alarms`.",
        "required": [
          "alarms"
        ],
        "properties": {
          "alarms": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Alarm"
            },
            "description": "Alarms, by key order."
          }
        }
      },
      "Answer": {
        "type": "object",
        "description": "Body of `POST /v1/runs/{id}/answers`.",
        "required": [
          "path",
          "accepted"
        ],
        "properties": {
          "path": {
            "type": "string",
            "description": "Step asking, as in its `asked` or `decision_required` event."
          },
          "accepted": {
            "type": "boolean",
            "description": "Whether the operator confirms."
          },
          "value": {
            "description": "Typed answer, or decision: `replay`, `skip`, `fail` or `abort`."
          }
        },
        "additionalProperties": false
      },
      "ArgumentView": {
        "type": "object",
        "description": "An argument of a telecommand.",
        "required": [
          "name",
          "type",
          "values"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name."
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Description, from the catalogue."
          },
          "type": {
            "type": "string",
            "description": "Type."
          },
          "unit": {
            "type": [
              "string",
              "null"
            ],
            "description": "Unit."
          },
          "values": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Values of an enum."
          },
          "range": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "number",
              "format": "double"
            },
            "description": "Accepted range.",
            "maxItems": 2,
            "minItems": 2
          },
          "default": {
            "type": [
              "string",
              "null"
            ],
            "description": "Value when omitted, as written."
          }
        }
      },
      "AuthSettings": {
        "type": "object",
        "description": "Reply of `GET /v1/auth/config`.",
        "properties": {
          "oidc": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SignIn",
                "description": "How to sign in; none: a token pasted, or identities declared."
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "BindingDetail": {
        "type": "object",
        "description": "A link bound to an instance, and the consumer of the telecommands it takes.",
        "required": [
          "target",
          "link",
          "driver",
          "gateway",
          "config",
          "config_current",
          "encode",
          "uplink"
        ],
        "properties": {
          "target": {
            "type": "string",
            "description": "Target."
          },
          "link": {
            "type": "string",
            "description": "Link."
          },
          "driver": {
            "type": "string",
            "description": "Driver bound."
          },
          "transport": {
            "type": [
              "string",
              "null"
            ],
            "description": "Transport bound, when the link has one."
          },
          "gateway": {
            "type": "string",
            "description": "Gateway bound."
          },
          "config": {
            "type": "string",
            "description": "Configuration revision of the target."
          },
          "config_current": {
            "type": "boolean",
            "description": "Whether it is the current configuration."
          },
          "encode": {
            "type": "string",
            "description": "Subject of the telecommands to encode."
          },
          "uplink": {
            "type": "string",
            "description": "Subject of the frames to uplink."
          },
          "consumer": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ConsumerStats",
                "description": "Durable consumer of `TC_COMMANDS` the instance takes them from."
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "BoundView": {
        "type": "object",
        "description": "Instances bound to a link.",
        "required": [
          "driver",
          "gateway"
        ],
        "properties": {
          "driver": {
            "type": "string",
            "description": "Driver instance."
          },
          "transport": {
            "type": [
              "string",
              "null"
            ],
            "description": "Transport instance, when the link has one."
          },
          "gateway": {
            "type": "string",
            "description": "Gateway instance."
          }
        }
      },
      "CatalogueView": {
        "type": "object",
        "description": "Body of `GET /v1/targets/{target}/catalogue`.",
        "required": [
          "platform",
          "components"
        ],
        "properties": {
          "platform": {
            "type": "string",
            "description": "Platform, `package@version`."
          },
          "components": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ComponentView"
            },
            "description": "Components."
          }
        }
      },
      "Change": {
        "type": "string",
        "description": "What changed.",
        "enum": [
          "bound",
          "unbound",
          "rebound",
          "ready",
          "not_ready",
          "revision"
        ]
      },
      "ComponentView": {
        "type": "object",
        "description": "A component of a catalogue.",
        "required": [
          "name",
          "instances",
          "measures",
          "telecommands"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name."
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Description, from the catalogue."
          },
          "instances": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Instances of a multi-instance component."
          },
          "measures": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MeasureView"
            },
            "description": "Measures, derived ones included."
          },
          "telecommands": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TelecommandView"
            },
            "description": "Telecommands."
          }
        }
      },
      "ConnectorLag": {
        "description": "Lag of the consumer of one kind of data of an output connector, published by the leader of\nthe reconciler on `stellar.metrics.connector.<name>` (spec « Connecteurs de sortie »).",
        "properties": {
          "active": {
            "description": "Whether a client is pulling the consumer now.",
            "type": "boolean"
          },
          "at": {
            "description": "Computation.",
            "type": "string"
          },
          "at_risk": {
            "description": "Whether the retention is about to remove messages the connector has not read.",
            "type": "boolean"
          },
          "connector": {
            "description": "Connector.",
            "type": "string"
          },
          "consumer": {
            "description": "Durable consumer.",
            "type": "string"
          },
          "fill": {
            "description": "Filling of the stream against its `max_bytes`; `None` when not bounded by volume.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "kind": {
            "description": "Kind of data.",
            "type": "string"
          },
          "lag_seconds": {
            "description": "Age of that message, in seconds: 0 when the connector is up to date.",
            "format": "double",
            "type": "number"
          },
          "oldest_unread": {
            "description": "Storage of the oldest message not acknowledged, when there is one.",
            "type": [
              "string",
              "null"
            ]
          },
          "pending": {
            "description": "Messages not delivered yet.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "reason": {
            "description": "Why.",
            "type": [
              "string",
              "null"
            ]
          },
          "retention_seconds": {
            "description": "Maximum age of the stream, in seconds; `None` when not bounded by age.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "stream": {
            "description": "JetStream stream.",
            "type": "string"
          },
          "unacked": {
            "description": "Messages delivered and not acknowledged.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "connector",
          "kind",
          "stream",
          "consumer",
          "pending",
          "unacked",
          "lag_seconds",
          "active",
          "at_risk",
          "at"
        ],
        "type": "object"
      },
      "ConnectorView": {
        "type": "object",
        "description": "An output connector: as declared, its instance, and the lag of its consumers.",
        "required": [
          "name",
          "data",
          "targets",
          "lags"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name."
          },
          "data": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Kinds of data."
          },
          "targets": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Targets."
          },
          "instance": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/InstanceView",
                "description": "Its instance, when registered."
              },
              {
                "type": "null"
              }
            ]
          },
          "lags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConnectorLag"
            },
            "description": "Lag of each consumer created."
          }
        }
      },
      "ConnectorsView": {
        "type": "object",
        "description": "Body of `GET /v1/connectors`.",
        "required": [
          "connectors"
        ],
        "properties": {
          "connectors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConnectorView"
            },
            "description": "Connectors of the topology."
          }
        }
      },
      "ConsumerStats": {
        "type": "object",
        "description": "Statistics of a durable consumer.",
        "required": [
          "name",
          "delivered",
          "pending",
          "ack_pending",
          "redelivered"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name."
          },
          "delivered": {
            "type": "integer",
            "format": "int64",
            "description": "Messages delivered and acknowledged.",
            "minimum": 0
          },
          "pending": {
            "type": "integer",
            "format": "int64",
            "description": "Messages waiting to be delivered.",
            "minimum": 0
          },
          "ack_pending": {
            "type": "integer",
            "description": "Messages delivered and not acknowledged yet.",
            "minimum": 0
          },
          "redelivered": {
            "type": "integer",
            "description": "Messages delivered again.",
            "minimum": 0
          },
          "last_active": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Last delivery."
          }
        }
      },
      "CurrentValue": {
        "type": "object",
        "description": "Current value of a measure.",
        "required": [
          "component",
          "measure",
          "sample"
        ],
        "properties": {
          "component": {
            "type": "string",
            "description": "Component."
          },
          "instance": {
            "type": [
              "string",
              "null"
            ],
            "description": "Instance of a multi-instance component."
          },
          "measure": {
            "type": "string",
            "description": "Measure or derived measure."
          },
          "sample": {
            "$ref": "#/components/schemas/Sample",
            "description": "Latest sample."
          }
        }
      },
      "DecodeBody": {
        "type": "object",
        "description": "Body of `POST /v1/decode`: a frame received on a link of a target, and the driver to ask.",
        "required": [
          "target"
        ],
        "properties": {
          "target": {
            "type": "string",
            "description": "Target."
          },
          "frame": {
            "type": [
              "string",
              "null"
            ],
            "description": "The frame in hexadecimal (`56 4f 4c 54`, spaces allowed); or `text`."
          },
          "text": {
            "type": [
              "string",
              "null"
            ],
            "description": "The frame as text, for a text protocol (`VOLT 28.0`); or `frame`."
          },
          "link": {
            "type": [
              "string",
              "null"
            ],
            "description": "Link, when not the default one."
          },
          "environment": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment, which selects the parameters of the link."
          },
          "driver": {
            "type": [
              "string",
              "null"
            ],
            "description": "Driver instance to ask, when not the one bound to the link."
          }
        },
        "additionalProperties": false
      },
      "Decoded": {
        "type": "object",
        "description": "Reply of `POST /v1/decode`.",
        "required": [
          "target",
          "link",
          "driver",
          "samples"
        ],
        "properties": {
          "target": {
            "type": "string",
            "description": "Target."
          },
          "link": {
            "type": "string",
            "description": "Link."
          },
          "driver": {
            "type": "string",
            "description": "Driver instance that decoded it."
          },
          "environment": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment of the parameters of the link."
          },
          "samples": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DecodedSample"
            },
            "description": "Samples, in the order the driver gives them."
          }
        }
      },
      "DecodedSample": {
        "type": "object",
        "description": "A sample of a decoded frame: the raw value of the driver, and its value calibrated by the\ncatalogue of the target.",
        "required": [
          "component",
          "measure",
          "raw"
        ],
        "properties": {
          "component": {
            "type": "string",
            "description": "Component."
          },
          "instance": {
            "type": [
              "string",
              "null"
            ],
            "description": "Instance of a multi-instance component."
          },
          "measure": {
            "type": "string",
            "description": "Measure."
          },
          "raw": {
            "description": "Raw value, as the driver gives it."
          },
          "value": {
            "description": "Value in the unit of the measure, through its calibration; `None` when the catalogue has\nno such measure or the calibration does not cover the raw value."
          },
          "unit": {
            "type": [
              "string",
              "null"
            ],
            "description": "Unit of the measure."
          },
          "onboard_time": {
            "type": [
              "string",
              "null"
            ],
            "description": "On-board time, when the frame carries it."
          }
        }
      },
      "Directory": {
        "type": "object",
        "description": "Body of `GET /v1/targets/{target}/files`.",
        "required": [
          "component",
          "files"
        ],
        "properties": {
          "component": {
            "type": "string",
            "description": "Component of the on-board directory."
          },
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnboardFile"
            },
            "description": "Files, by identifier."
          }
        }
      },
      "DownloadRequest": {
        "type": "object",
        "description": "Body of `POST /v1/transfers`.",
        "required": [
          "target",
          "file_id"
        ],
        "properties": {
          "target": {
            "type": "string",
            "description": "Target."
          },
          "file_id": {
            "type": "string",
            "description": "File, by its on-board identifier."
          },
          "priority": {
            "type": "integer",
            "format": "int32",
            "description": "Priority: higher first."
          }
        },
        "additionalProperties": false
      },
      "DriverDetail": {
        "type": "object",
        "description": "What a driver implements, against the current configuration.",
        "required": [
          "codec",
          "catalogue",
          "telecommands",
          "measures",
          "missing_telecommands",
          "missing_measures"
        ],
        "properties": {
          "codec": {
            "type": "string",
            "description": "Codec."
          },
          "catalogue": {
            "type": "string",
            "description": "Catalogue and the versions it fits, `name@requirement`."
          },
          "catalogue_version": {
            "type": [
              "string",
              "null"
            ],
            "description": "The newest version of that catalogue in the current configuration satisfying the\nrequirement, against which its coverage is measured; `None` when there is none."
          },
          "telecommands": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Telecommands covered, `component.telecommand`."
          },
          "measures": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Measures covered, `component.measure`."
          },
          "missing_telecommands": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Telecommands of the catalogue it does not cover."
          },
          "missing_measures": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Measures of the catalogue it does not cover."
          }
        }
      },
      "EncodeBody": {
        "type": "object",
        "description": "Body of `POST /v1/encode`: a telecommand as for `POST /v1/tc`, and the driver to ask.",
        "required": [
          "target",
          "telecommand"
        ],
        "properties": {
          "target": {
            "type": "string",
            "description": "Target."
          },
          "telecommand": {
            "type": "string",
            "description": "Telecommand: its name alone when unique in the platform, else `component.name`."
          },
          "instance": {
            "type": [
              "string",
              "null"
            ],
            "description": "Instance of a multi-instance component, or file id for `files`."
          },
          "args": {
            "type": "object",
            "description": "Arguments: `100 V`, enum values, booleans, hexadecimal bytes.",
            "additionalProperties": {
              "$ref": "#/components/schemas/InputArg"
            },
            "propertyNames": {
              "type": "string"
            }
          },
          "link": {
            "type": [
              "string",
              "null"
            ],
            "description": "Link, when not the default one."
          },
          "environment": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment, which selects the parameters of the link."
          },
          "driver": {
            "type": [
              "string",
              "null"
            ],
            "description": "Driver instance to ask, when not the one bound to the link: a driver being developed."
          }
        },
        "additionalProperties": false
      },
      "Encoded": {
        "type": "object",
        "description": "Reply of `POST /v1/encode`.",
        "required": [
          "target",
          "link",
          "driver",
          "telecommand",
          "args",
          "frame",
          "size"
        ],
        "properties": {
          "target": {
            "type": "string",
            "description": "Target."
          },
          "link": {
            "type": "string",
            "description": "Link."
          },
          "driver": {
            "type": "string",
            "description": "Driver instance that encoded it."
          },
          "environment": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment of the parameters of the link."
          },
          "telecommand": {
            "type": "string",
            "description": "The telecommand, as written: `tcu[TCU1].set_mode`."
          },
          "args": {
            "type": "object",
            "description": "Its arguments, resolved: numbers in the unit of their argument, defaults applied.",
            "additionalProperties": {},
            "propertyNames": {
              "type": "string"
            }
          },
          "frame": {
            "type": "string",
            "description": "The frame, in hexadecimal: the frame of the medium on a link without transport, the unit\nthe driver hands to the transport otherwise."
          },
          "size": {
            "type": "integer",
            "description": "Its size, in bytes.",
            "minimum": 0
          },
          "text": {
            "type": [
              "string",
              "null"
            ],
            "description": "The frame as text, when it is printable text (SCPI and other text protocols)."
          }
        }
      },
      "Entry": {
        "type": "object",
        "description": "An entry of the journal.",
        "required": [
          "at",
          "target",
          "change"
        ],
        "properties": {
          "at": {
            "type": "string",
            "format": "date-time",
            "description": "When the reconciler made the change."
          },
          "target": {
            "type": "string",
            "description": "Target."
          },
          "link": {
            "type": [
              "string",
              "null"
            ],
            "description": "Link, for a change of a link."
          },
          "change": {
            "$ref": "#/components/schemas/Change",
            "description": "What changed."
          },
          "driver": {
            "type": [
              "string",
              "null"
            ],
            "description": "Driver bound after the change."
          },
          "transport": {
            "type": [
              "string",
              "null"
            ],
            "description": "Transport bound after the change."
          },
          "gateway": {
            "type": [
              "string",
              "null"
            ],
            "description": "Gateway bound after the change."
          },
          "config": {
            "type": [
              "string",
              "null"
            ],
            "description": "Configuration revision of the target after the change."
          },
          "reasons": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Why, in the words of the readiness: the reasons of the target or of the link."
          }
        }
      },
      "EnvironmentPolicy": {
        "type": "object",
        "description": "Policies of an environment.",
        "required": [
          "allow_draft"
        ],
        "properties": {
          "allow_draft": {
            "type": "boolean",
            "description": "Whether `draft` packages are accepted."
          },
          "human_orchestration": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/HumanOrchestrationView",
                "description": "Rules of human orchestration; `None` when off."
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "ErrorBody": {
        "type": "object",
        "description": "Body of an error response.",
        "required": [
          "errors"
        ],
        "properties": {
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ErrorItem"
            },
            "description": "Every error found."
          }
        }
      },
      "ErrorItem": {
        "type": "object",
        "description": "One error.",
        "required": [
          "code",
          "message"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable code."
          },
          "message": {
            "type": "string",
            "description": "Message for the operator."
          },
          "help": {
            "type": [
              "string",
              "null"
            ],
            "description": "Suggested fix."
          }
        }
      },
      "Evidence": {
        "description": "A sample a condition was judged on.",
        "properties": {
          "component": {
            "description": "Component.",
            "type": "string"
          },
          "ground_time": {
            "description": "Ground reception time.",
            "type": "string"
          },
          "instance": {
            "description": "Instance.",
            "type": [
              "string",
              "null"
            ]
          },
          "measure": {
            "description": "Measure.",
            "type": "string"
          },
          "target": {
            "description": "Target.",
            "type": "string"
          },
          "time": {
            "description": "Time of the sample.",
            "type": "string"
          },
          "value": {
            "description": "Value."
          }
        },
        "required": [
          "target",
          "component",
          "measure",
          "value",
          "time",
          "ground_time"
        ],
        "type": "object"
      },
      "FaultRequest": {
        "type": "object",
        "description": "A fault of the simulation of a target to switch on during the run, then off: to rehearse the\nrecovery of a procedure, its `if failed` blocks and the reactions to alarms.\n\n```yaml\nfaults:\n  - {target: chamber, fault: vacuum_leak, at: {step: Plateau, after: 10 s}, off: {after: 60 s}}\n```",
        "required": [
          "target",
          "fault"
        ],
        "properties": {
          "target": {
            "type": "string",
            "description": "Role of the target, as in `targets`."
          },
          "fault": {
            "type": "string",
            "description": "Fault, as the simulation of the target names it."
          },
          "at": {
            "$ref": "#/components/schemas/Trigger",
            "description": "When it is switched on: after the start of the run, or of the first entry in a step."
          },
          "off": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Trigger",
                "description": "When it is switched off, from when it was switched on; never during the run otherwise."
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "additionalProperties": false
      },
      "GatewayDetail": {
        "type": "object",
        "description": "What a gateway offers.",
        "required": [
          "tags"
        ],
        "properties": {
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Tags."
          },
          "uplink": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LinkCapability",
                "description": "Uplink."
              },
              {
                "type": "null"
              }
            ]
          },
          "downlink": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LinkCapability",
                "description": "Downlink."
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "Health": {
        "description": "Health of an instance.",
        "oneOf": [
          {
            "description": "Working normally.",
            "enum": [
              "healthy"
            ],
            "type": "string"
          },
          {
            "description": "Working with a problem, given in `reason`.",
            "enum": [
              "degraded"
            ],
            "type": "string"
          }
        ]
      },
      "Heartbeat": {
        "additionalProperties": false,
        "description": "Heartbeat, published on `stellar.ctl.hb.<kind>.<instance>` every period.",
        "properties": {
          "health": {
            "$ref": "#/components/schemas/Health",
            "description": "Health."
          },
          "link_available": {
            "description": "For a gateway: whether its link is available (satellite in view, station in service).\nA gateway without this notion always reports `true`.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "reason": {
            "description": "Why the instance is degraded.",
            "type": [
              "string",
              "null"
            ]
          },
          "sent_at": {
            "description": "Emission time.",
            "type": "string"
          }
        },
        "required": [
          "health",
          "sent_at"
        ],
        "title": "Stellar Control heartbeat",
        "type": "object"
      },
      "History": {
        "type": "object",
        "description": "Body of `GET /v1/targets/{target}/values/history`: the samples of one measure over a\nwindow, as the compute stage published them in the stream `PARAMS`.",
        "required": [
          "component",
          "measure",
          "samples",
          "thinned",
          "truncated"
        ],
        "properties": {
          "component": {
            "type": "string",
            "description": "Component."
          },
          "instance": {
            "type": [
              "string",
              "null"
            ],
            "description": "Instance of a multi-instance component."
          },
          "measure": {
            "type": "string",
            "description": "Measure or derived measure."
          },
          "samples": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Sample"
            },
            "description": "Samples in the order they were published: real-time ones by time, deferred ones when\nthey came down. With more than `limit` in the window, one in every few is kept, the\nlast one always."
          },
          "thinned": {
            "type": "boolean",
            "description": "Whether samples were left out to keep `limit`."
          },
          "truncated": {
            "type": "boolean",
            "description": "Whether the window holds more samples than are read at once: only its start is read."
          }
        }
      },
      "HumanOrchestrationView": {
        "type": "object",
        "description": "Rules of human orchestration of an environment.",
        "required": [
          "identity",
          "hazardous_confirmation",
          "hazardous_requires_plan"
        ],
        "properties": {
          "identity": {
            "type": "string",
            "description": "How operators are identified: `declared` or `jwt`."
          },
          "hazardous_confirmation": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Roles confirming a hazardous telecommand, in order: `operator`, `supervisor`."
          },
          "hazardous_requires_plan": {
            "type": "boolean",
            "description": "Whether runs with a hazardous telecommand must be planned on a pass."
          }
        }
      },
      "InputArg": {
        "oneOf": [
          {
            "type": "boolean",
            "description": "Boolean."
          },
          {
            "type": "number",
            "format": "double",
            "description": "Number without unit."
          },
          {
            "type": "string",
            "description": "Anything else: quantity, enum value, file id, hash, hexadecimal bytes."
          }
        ],
        "description": "An input value as written: `28 V`, `TCU2`, `true`, `3`."
      },
      "InputView": {
        "type": "object",
        "description": "An input of a procedure.",
        "required": [
          "name",
          "kind",
          "values"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name."
          },
          "kind": {
            "type": "string",
            "description": "`value`, `file_id` or `content`."
          },
          "type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Type, or file type for `file_id`."
          },
          "unit": {
            "type": [
              "string",
              "null"
            ],
            "description": "Unit."
          },
          "values": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Values of an enum."
          }
        }
      },
      "InstanceDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/InstanceView",
            "description": "As in the list."
          },
          {
            "type": "object",
            "required": [
              "heartbeat_period_ms",
              "public_key",
              "bindings"
            ],
            "properties": {
              "heartbeat_period_ms": {
                "type": "integer",
                "format": "int64",
                "description": "Heartbeat period, in milliseconds.",
                "minimum": 0
              },
              "public_key": {
                "type": "string",
                "description": "Public key of its nkey."
              },
              "driver": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/DriverDetail",
                    "description": "What a driver implements."
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "gateway": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/GatewayDetail",
                    "description": "What a gateway offers."
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "status": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/Status",
                    "description": "Its own status, asked with the `status` verb."
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "status_error": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Why the status could not be asked."
              },
              "bindings": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/BindingDetail"
                },
                "description": "Links bound to it."
              }
            }
          }
        ],
        "description": "Body of `GET /v1/instances/{kind}/{instance}`."
      },
      "InstanceView": {
        "type": "object",
        "description": "An instance registered with the reconciler.",
        "required": [
          "kind",
          "instance",
          "software",
          "version",
          "registered_at",
          "last_seen",
          "alive",
          "tags",
          "bound"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "description": "Kind: `driver`, `gateway`, or an MCS component."
          },
          "instance": {
            "type": "string",
            "description": "Instance name."
          },
          "software": {
            "type": "string",
            "description": "Software."
          },
          "version": {
            "type": "string",
            "description": "Version."
          },
          "registered_at": {
            "type": "string",
            "format": "date-time",
            "description": "Registration."
          },
          "last_seen": {
            "type": "string",
            "format": "date-time",
            "description": "Last registration or heartbeat."
          },
          "alive": {
            "type": "boolean",
            "description": "Whether heard within three heartbeat periods."
          },
          "health": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Health",
                "description": "Health of its last heartbeat."
              },
              {
                "type": "null"
              }
            ]
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why degraded."
          },
          "link_available": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "For a gateway: whether its link is available."
          },
          "catalogue": {
            "type": [
              "string",
              "null"
            ],
            "description": "For a driver: catalogue implemented, `name@version`."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "For a gateway: tags."
          },
          "uplink": {
            "type": [
              "string",
              "null"
            ],
            "description": "For a gateway: uplink and downlink types and theoretical rates."
          },
          "downlink": {
            "type": [
              "string",
              "null"
            ],
            "description": "Downlink."
          },
          "frames": {
            "type": [
              "string",
              "null"
            ],
            "description": "For a transport: what it frames and produces, `csp1 → can`."
          },
          "bound": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Links bound to it: `<target>.<link>`."
          }
        }
      },
      "InstancesView": {
        "type": "object",
        "description": "Body of `GET /v1/instances`.",
        "required": [
          "instances"
        ],
        "properties": {
          "instances": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InstanceView"
            },
            "description": "Instances registered, drivers and gateways first."
          }
        }
      },
      "Journal": {
        "type": "object",
        "description": "Body of `GET /v1/reconciler/events`.",
        "required": [
          "events",
          "truncated"
        ],
        "properties": {
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Entry"
            },
            "description": "Entries, newest first."
          },
          "truncated": {
            "type": "boolean",
            "description": "Whether older entries of the window were left out by the limit."
          }
        }
      },
      "LeaseView": {
        "type": "object",
        "description": "Runs holding a target.",
        "required": [
          "runs",
          "shared"
        ],
        "properties": {
          "runs": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Runs."
          },
          "shared": {
            "type": "boolean",
            "description": "Whether shared by runs that do not change the on-board state."
          }
        }
      },
      "LinkCapability": {
        "additionalProperties": false,
        "description": "Physical link in one direction.",
        "properties": {
          "link_type": {
            "description": "Link type: `rf`, `can`, `rs422`, `ethernet`, `sim`…",
            "type": "string"
          },
          "rate_bps": {
            "description": "Theoretical throughput, in bits per second.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "link_type",
          "rate_bps"
        ],
        "type": "object"
      },
      "LinkView": {
        "type": "object",
        "description": "A link, as declared and as bound.",
        "required": [
          "name",
          "default",
          "driver",
          "gateway"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name."
          },
          "default": {
            "type": "boolean",
            "description": "Whether it is the default link."
          },
          "driver": {
            "type": "string",
            "description": "Driver required: `package@versions`."
          },
          "transport": {
            "type": [
              "string",
              "null"
            ],
            "description": "Transport required, when the link has one: `package@versions`."
          },
          "gateway": {
            "type": "string",
            "description": "Gateway required: an instance, or `any(tag: …)`."
          },
          "bound": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/BoundView",
                "description": "Instances bound, when bound."
              },
              {
                "type": "null"
              }
            ]
          },
          "available": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether its gateway reports the link available (in pass, station in service)."
          }
        }
      },
      "MeasureView": {
        "type": "object",
        "description": "A measure.",
        "required": [
          "name",
          "type",
          "derived"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name."
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Description, from the catalogue."
          },
          "type": {
            "type": "string",
            "description": "Type."
          },
          "unit": {
            "type": [
              "string",
              "null"
            ],
            "description": "Unit."
          },
          "soft": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "number",
              "format": "double"
            },
            "description": "Soft limits, `[low, high]`.",
            "maxItems": 2,
            "minItems": 2
          },
          "hard": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "number",
              "format": "double"
            },
            "description": "Hard limits.",
            "maxItems": 2,
            "minItems": 2
          },
          "derived": {
            "type": "boolean",
            "description": "Whether derived from other measures."
          }
        }
      },
      "ModeRequest": {
        "type": "object",
        "description": "Body of `PUT /v1/targets/{target}/mode`.",
        "required": [
          "mode"
        ],
        "properties": {
          "mode": {
            "type": "string",
            "description": "Mode to set."
          }
        },
        "additionalProperties": false
      },
      "ModeView": {
        "type": "object",
        "description": "Body of `GET` and `PUT /v1/targets/{target}/mode`.",
        "required": [
          "target",
          "modes"
        ],
        "properties": {
          "target": {
            "type": "string",
            "description": "Target."
          },
          "mode": {
            "type": [
              "string",
              "null"
            ],
            "description": "Mode the target is in; `None` when the topology declares no modes."
          },
          "default": {
            "type": [
              "string",
              "null"
            ],
            "description": "Default mode of the topology."
          },
          "modes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Modes of the topology, in their order."
          },
          "since": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the mode was last set; `None` for the default mode never set."
          },
          "by": {
            "type": [
              "string",
              "null"
            ],
            "description": "Who set it."
          },
          "run": {
            "type": [
              "string",
              "null"
            ],
            "description": "Run that set it, at the end of a `configure`."
          }
        }
      },
      "NatsCredentials": {
        "type": "object",
        "description": "Reply of `POST /v1/auth/nats`.",
        "required": [
          "jwt",
          "expires"
        ],
        "properties": {
          "jwt": {
            "type": "string",
            "description": "NATS user JWT."
          },
          "expires": {
            "type": "integer",
            "format": "int64",
            "description": "Expiry (seconds since the epoch)."
          }
        }
      },
      "NatsRequest": {
        "type": "object",
        "description": "Body of `POST /v1/auth/nats`.",
        "required": [
          "public_key"
        ],
        "properties": {
          "public_key": {
            "type": "string",
            "description": "Public nkey of the user (`U…`) the credentials are for."
          }
        },
        "additionalProperties": false
      },
      "OnboardFile": {
        "type": "object",
        "description": "A file of the on-board directory, as last listed.",
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Identifier."
          },
          "file_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Type (`lttm`, `log`…)."
          },
          "size": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "Size, in bytes.",
            "minimum": 0
          },
          "checksum": {
            "type": [
              "string",
              "null"
            ],
            "description": "Checksum, hexadecimal."
          },
          "generation": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "Generation: a file rewritten on board gets the next one.",
            "minimum": 0
          },
          "transfer": {
            "type": [
              "string",
              "null"
            ],
            "description": "State of its transfer."
          },
          "listed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Last listing."
          }
        }
      },
      "ParameterView": {
        "type": "object",
        "description": "A parameter of a target and its values.",
        "required": [
          "name",
          "component",
          "parameter",
          "values"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Written in full: `rf.tx_baudrate`, `tcu[TCU1].anode_voltage`."
          },
          "component": {
            "type": "string",
            "description": "Component."
          },
          "instance": {
            "type": [
              "string",
              "null"
            ],
            "description": "Instance of a multi-instance component."
          },
          "parameter": {
            "type": "string",
            "description": "Parameter."
          },
          "unit": {
            "type": [
              "string",
              "null"
            ],
            "description": "Unit of its values."
          },
          "value": {
            "description": "Value in the mode of the target; `None` without one."
          },
          "values": {
            "type": "object",
            "description": "Values by mode.",
            "additionalProperties": {},
            "propertyNames": {
              "type": "string"
            }
          },
          "set": {
            "type": [
              "string",
              "null"
            ],
            "description": "Telecommand setting it, `configure` sends."
          },
          "readback": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Readback",
                "description": "Measure reading it back, and its current sample."
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "ParametersView": {
        "type": "object",
        "description": "Body of `GET /v1/targets/{target}/parameters`.",
        "required": [
          "target",
          "parameters"
        ],
        "properties": {
          "target": {
            "type": "string",
            "description": "Target."
          },
          "mode": {
            "type": [
              "string",
              "null"
            ],
            "description": "Mode the target is in."
          },
          "environment": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment of the values; `None`: without overrides."
          },
          "parameters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ParameterView"
            },
            "description": "Parameters of its components, in the order of the catalogue."
          }
        }
      },
      "Pass": {
        "additionalProperties": false,
        "description": "A pass of a target over a ground station, in `stellar_passes` under `<target>.<id>`.",
        "properties": {
          "aos": {
            "description": "Acquisition of signal (UTC).",
            "type": "string"
          },
          "contributions": {
            "description": "Contribution of each source to a merged pass, set by the MCS.",
            "items": {
              "$ref": "#/components/schemas/Pass"
            },
            "type": "array"
          },
          "feeder": {
            "description": "Feeder that wrote it, set by the MCS.",
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "description": "Stable identifier, given by the feeder.",
            "type": "string"
          },
          "los": {
            "description": "Loss of signal (UTC).",
            "type": "string"
          },
          "max_elevation": {
            "description": "Maximum elevation (`47.3 deg`).",
            "type": "string"
          },
          "protocol": {
            "description": "Protocol (`ccsds`, `csp`, `dvb-s2`…).",
            "type": [
              "string",
              "null"
            ]
          },
          "rates": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PassRates"
              },
              {
                "type": "null"
              }
            ],
            "description": "Expected rates."
          },
          "source": {
            "$ref": "#/components/schemas/PassSource",
            "description": "Source."
          },
          "station": {
            "description": "Ground station.",
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/PassStatus",
            "description": "Status."
          },
          "target": {
            "description": "Target.",
            "type": "string"
          },
          "transceiver": {
            "description": "On-board transceiver (`sband`, `xband`…).",
            "type": [
              "string",
              "null"
            ]
          },
          "updated_at": {
            "description": "Last update, set by the MCS.",
            "type": [
              "string",
              "null"
            ]
          },
          "uplink": {
            "description": "Whether telecommands can be sent; a receive-only pass refuses any `send`.",
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "target",
          "station",
          "aos",
          "los",
          "max_elevation",
          "source",
          "status"
        ],
        "title": "Stellar Control pass",
        "type": "object"
      },
      "PassFilter": {
        "additionalProperties": false,
        "description": "Passes a rule applies to.",
        "properties": {
          "min_elevation": {
            "description": "Lowest maximum elevation (`20 deg`).",
            "type": [
              "string",
              "null"
            ]
          },
          "station": {
            "description": "Ground station.",
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PassStatus"
              },
              {
                "type": "null"
              }
            ],
            "description": "Status of the pass (`booked`)."
          },
          "uplink": {
            "description": "Whether the pass must allow the uplink.",
            "type": [
              "boolean",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "PassGateway": {
        "additionalProperties": false,
        "description": "Gateway of a pass, checked by the reconciler before the AOS, in `stellar_pass_gateways` under\n`<target>.<id>`.",
        "properties": {
          "checked_at": {
            "description": "Time of the check.",
            "type": "string"
          },
          "gateway": {
            "description": "Gateway registered for the station, healthy.",
            "type": [
              "string",
              "null"
            ]
          },
          "reason": {
            "description": "Why none is.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "checked_at"
        ],
        "type": "object"
      },
      "PassRates": {
        "additionalProperties": false,
        "description": "Expected rates of a pass.",
        "properties": {
          "downlink": {
            "description": "Downlink rate (`2 Mbps`).",
            "type": [
              "string",
              "null"
            ]
          },
          "uplink": {
            "description": "Uplink rate (`64 kbps`).",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "PassSource": {
        "description": "Source of a pass.",
        "oneOf": [
          {
            "description": "Flight dynamics: predictions.",
            "enum": [
              "fds"
            ],
            "type": "string"
          },
          {
            "description": "Ground station provider: bookings.",
            "enum": [
              "provider"
            ],
            "type": "string"
          }
        ]
      },
      "PassStatus": {
        "description": "Status of a pass.",
        "oneOf": [
          {
            "description": "Predicted by the flight dynamics.",
            "enum": [
              "predicted"
            ],
            "type": "string"
          },
          {
            "description": "Booking confirmed by the provider.",
            "enum": [
              "booked"
            ],
            "type": "string"
          },
          {
            "description": "Cancelled.",
            "enum": [
              "cancelled"
            ],
            "type": "string"
          }
        ]
      },
      "PassView": {
        "type": "object",
        "description": "A pass and the gateway checked for it.",
        "required": [
          "pass"
        ],
        "properties": {
          "pass": {
            "$ref": "#/components/schemas/Pass",
            "description": "Pass."
          },
          "gateway": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/PassGateway",
                "description": "Gateway checked by the reconciler before the AOS."
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "Passes": {
        "type": "object",
        "description": "Body of `GET /v1/passes`.",
        "required": [
          "passes"
        ],
        "properties": {
          "passes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PassView"
            },
            "description": "Passes, by AOS."
          }
        }
      },
      "Pending": {
        "type": "object",
        "description": "A question or a decision waiting for an operator.",
        "required": [
          "path",
          "kind",
          "prompt"
        ],
        "properties": {
          "path": {
            "type": "string",
            "description": "Step asking."
          },
          "kind": {
            "type": "string",
            "description": "`ask` or `decision`."
          },
          "prompt": {
            "type": "string",
            "description": "Question, or why a decision is needed."
          },
          "role": {
            "type": [
              "string",
              "null"
            ],
            "description": "Role whose confirmation is awaited, for a `hazardous` telecommand."
          }
        }
      },
      "PlanValidation": {
        "additionalProperties": false,
        "description": "Validation of a plan by a supervisor: what was validated, which any change invalidates.",
        "properties": {
          "aos": {
            "description": "AOS of the pass validated.",
            "type": "string"
          },
          "at": {
            "description": "Time of the validation.",
            "type": "string"
          },
          "by": {
            "description": "Supervisor.",
            "type": "string"
          },
          "ir": {
            "description": "Hash of the resolved run validated: procedure, inputs, targets.",
            "type": "string"
          },
          "los": {
            "description": "LOS of the pass validated.",
            "type": "string"
          },
          "pass": {
            "description": "Pass.",
            "type": "string"
          }
        },
        "required": [
          "by",
          "at",
          "pass",
          "aos",
          "los",
          "ir"
        ],
        "type": "object"
      },
      "ProcedureView": {
        "type": "object",
        "description": "A procedure, as a run request names it.",
        "required": [
          "name",
          "library",
          "version",
          "roles",
          "inputs",
          "allowed_in",
          "max_duration",
          "hazardous"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name."
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Description, from the library."
          },
          "library": {
            "type": "string",
            "description": "Library package: the `library` of a run request."
          },
          "version": {
            "type": "string",
            "description": "Library version."
          },
          "roles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RoleView"
            },
            "description": "Roles and their platform."
          },
          "inputs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InputView"
            },
            "description": "Inputs."
          },
          "allowed_in": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Environments where it may run; empty when not restricted."
          },
          "max_duration": {
            "type": "string",
            "description": "Longest duration."
          },
          "hazardous": {
            "type": "boolean",
            "description": "Whether it sends a `hazardous` telecommand."
          }
        }
      },
      "ProceduresView": {
        "type": "object",
        "description": "Body of `GET /v1/procedures`.",
        "required": [
          "procedures"
        ],
        "properties": {
          "procedures": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProcedureView"
            },
            "description": "Procedures of every library."
          }
        }
      },
      "Readback": {
        "type": "object",
        "description": "The readback of a parameter.",
        "required": [
          "measure"
        ],
        "properties": {
          "measure": {
            "type": "string",
            "description": "Measure."
          },
          "sample": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Sample",
                "description": "Current sample; `None` before any."
              },
              {
                "type": "null"
              }
            ]
          },
          "matches": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether it has the value of the mode (within the tolerance of the parameter); `None`\nwithout a sample or a value."
          }
        }
      },
      "ReplaceWindow": {
        "type": "object",
        "description": "Body of `POST /v1/passes/replace_window`: a complete snapshot of a source for a target over\nan interval.",
        "required": [
          "source",
          "target",
          "from",
          "to",
          "passes"
        ],
        "properties": {
          "source": {
            "$ref": "#/components/schemas/PassSource",
            "description": "Source of the snapshot."
          },
          "target": {
            "type": "string",
            "description": "Target."
          },
          "from": {
            "type": "string",
            "format": "date-time",
            "description": "Start of the interval."
          },
          "to": {
            "type": "string",
            "format": "date-time",
            "description": "End of the interval."
          },
          "passes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Pass"
            },
            "description": "Every pass of the source in the interval."
          }
        },
        "additionalProperties": false
      },
      "Replaced": {
        "type": "object",
        "description": "What a `replace_window` did.",
        "required": [
          "upserted",
          "cancelled"
        ],
        "properties": {
          "upserted": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Passes written, as stored."
          },
          "cancelled": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Passes whose contribution of the source was cancelled, as stored."
          }
        }
      },
      "Resume": {
        "type": "object",
        "description": "Body of `POST /v1/runs/{id}/resume`.",
        "required": [
          "choice"
        ],
        "properties": {
          "choice": {
            "type": "string",
            "description": "`replay` the step where the run stopped, `skip` it, `fail` it (the `if failed` blocks\nrun), or `abort` the run."
          }
        },
        "additionalProperties": false
      },
      "RoleView": {
        "type": "object",
        "description": "A role of a procedure.",
        "required": [
          "name",
          "platform"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name."
          },
          "platform": {
            "type": "string",
            "description": "Platform package."
          }
        }
      },
      "Rules": {
        "type": "object",
        "description": "Body of `GET /v1/schedule-rules`.",
        "required": [
          "rules"
        ],
        "properties": {
          "rules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ScheduleRule"
            },
            "description": "Rules, by identifier."
          }
        }
      },
      "RunEvent": {
        "description": "An event of a run, published on `stellar.run.evt.<run_id>`: the log of the run.",
        "oneOf": [
          {
            "description": "The run starts.",
            "properties": {
              "by": {
                "description": "Identity declared by the operator.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "environment": {
                "description": "Environment.",
                "type": "string"
              },
              "event": {
                "enum": [
                  "started"
                ],
                "type": "string"
              },
              "inputs": {
                "additionalProperties": true,
                "description": "Input values, resolved (numbers in the unit of their input).",
                "type": "object"
              },
              "ir": {
                "description": "Hash of the resolved run.",
                "type": "string"
              },
              "library": {
                "description": "Library and version.",
                "type": "string"
              },
              "procedure": {
                "description": "Procedure.",
                "type": "string"
              },
              "targets": {
                "additionalProperties": {
                  "type": "string"
                },
                "description": "Target of each role.",
                "type": "object"
              }
            },
            "required": [
              "event",
              "procedure",
              "library",
              "environment",
              "targets",
              "ir"
            ],
            "type": "object"
          },
          {
            "description": "A procedure starts.",
            "properties": {
              "event": {
                "enum": [
                  "procedure_started"
                ],
                "type": "string"
              },
              "path": {
                "description": "Procedure.",
                "type": "string"
              }
            },
            "required": [
              "event",
              "path"
            ],
            "type": "object"
          },
          {
            "description": "A procedure ends.",
            "properties": {
              "event": {
                "enum": [
                  "procedure_finished"
                ],
                "type": "string"
              },
              "ok": {
                "description": "Whether every action succeeded.",
                "type": "boolean"
              },
              "path": {
                "description": "Procedure.",
                "type": "string"
              }
            },
            "required": [
              "event",
              "path",
              "ok"
            ],
            "type": "object"
          },
          {
            "description": "An attempt of a step starts.",
            "properties": {
              "attempt": {
                "default": 1,
                "description": "Attempt, from 1.",
                "format": "uint32",
                "minimum": 0,
                "type": "integer"
              },
              "event": {
                "enum": [
                  "step_started"
                ],
                "type": "string"
              },
              "inputs": {
                "additionalProperties": true,
                "description": "Inputs of the step, resolved.",
                "type": "object"
              },
              "path": {
                "description": "Step.",
                "type": "string"
              }
            },
            "required": [
              "event",
              "path"
            ],
            "type": "object"
          },
          {
            "description": "A telecommand is about to be sent; its identifier is in the log before it leaves.",
            "properties": {
              "changes_state": {
                "description": "Whether it changes the on-board state: a step interrupted after it is not replayed\nwithout an operator decision.",
                "type": "boolean"
              },
              "event": {
                "enum": [
                  "telecommand_sent"
                ],
                "type": "string"
              },
              "path": {
                "description": "Step.",
                "type": "string"
              },
              "retry_of": {
                "description": "Telecommand of the first attempt of the step this one retries.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "target": {
                "description": "Target.",
                "type": "string"
              },
              "tc": {
                "description": "Telecommand.",
                "type": "string"
              },
              "telecommand": {
                "description": "`component[instance].telecommand`.",
                "type": "string"
              }
            },
            "required": [
              "event",
              "path",
              "tc",
              "target",
              "telecommand",
              "changes_state"
            ],
            "type": "object"
          },
          {
            "description": "A telecommand reached its final state.",
            "properties": {
              "acks": {
                "description": "Its events, in order: the chain of acknowledgements.",
                "items": {
                  "$ref": "#/components/schemas/TcEvent"
                },
                "type": "array"
              },
              "detail": {
                "description": "Reason of a failure.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "event": {
                "enum": [
                  "telecommand_finished"
                ],
                "type": "string"
              },
              "path": {
                "description": "Step.",
                "type": "string"
              },
              "state": {
                "$ref": "#/components/schemas/TcState",
                "description": "Final state."
              },
              "tc": {
                "description": "Telecommand.",
                "type": "string"
              }
            },
            "required": [
              "event",
              "path",
              "tc",
              "state"
            ],
            "type": "object"
          },
          {
            "description": "A condition of an `expect`, a `check` or a `wait until` was judged: the evidence.",
            "properties": {
              "condition": {
                "description": "The condition, as written.",
                "type": "string"
              },
              "event": {
                "enum": [
                  "checked"
                ],
                "type": "string"
              },
              "ok": {
                "description": "Whether it held.",
                "type": "boolean"
              },
              "path": {
                "description": "Step.",
                "type": "string"
              },
              "reason": {
                "description": "Why not.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "samples": {
                "description": "Samples it was judged on.",
                "items": {
                  "$ref": "#/components/schemas/Evidence"
                },
                "type": "array"
              },
              "statement": {
                "description": "`expect`, `check` or `wait_until`.",
                "type": "string"
              }
            },
            "required": [
              "event",
              "path",
              "statement",
              "condition",
              "ok"
            ],
            "type": "object"
          },
          {
            "description": "Values written by a `log`: its text, each value in its place, and the samples read.",
            "properties": {
              "event": {
                "enum": [
                  "logged"
                ],
                "type": "string"
              },
              "message": {
                "description": "The text, values included (`sat.tcu[TCU2].anode_voltage = 248.7 V`); a missing value\nis `unknown`, a stale one is followed by `(stale)`.",
                "type": "string"
              },
              "path": {
                "description": "Step.",
                "type": "string"
              },
              "samples": {
                "description": "Samples it was written from.",
                "items": {
                  "$ref": "#/components/schemas/Evidence"
                },
                "type": "array"
              }
            },
            "required": [
              "event",
              "path",
              "message"
            ],
            "type": "object"
          },
          {
            "description": "A question to the operator.",
            "properties": {
              "event": {
                "enum": [
                  "asked"
                ],
                "type": "string"
              },
              "path": {
                "description": "Step.",
                "type": "string"
              },
              "prompt": {
                "description": "Question.",
                "type": "string"
              },
              "role": {
                "description": "Role whose confirmation is awaited, for a `hazardous` telecommand.",
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "event",
              "path",
              "prompt"
            ],
            "type": "object"
          },
          {
            "description": "The answer to a question.",
            "properties": {
              "accepted": {
                "description": "Whether the operator confirmed.",
                "type": "boolean"
              },
              "by": {
                "description": "Who answered; none when acknowledged automatically (no human orchestration).",
                "type": [
                  "string",
                  "null"
                ]
              },
              "event": {
                "enum": [
                  "answered"
                ],
                "type": "string"
              },
              "path": {
                "description": "Step.",
                "type": "string"
              },
              "role": {
                "description": "Role confirmed, for a `hazardous` telecommand.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "value": {
                "description": "Typed answer."
              }
            },
            "required": [
              "event",
              "path",
              "accepted"
            ],
            "type": "object"
          },
          {
            "description": "An answer not taken: not the role awaited, the same person twice, a token refused.",
            "properties": {
              "by": {
                "description": "Who answered.",
                "type": "string"
              },
              "event": {
                "enum": [
                  "answer_refused"
                ],
                "type": "string"
              },
              "path": {
                "description": "Step.",
                "type": "string"
              },
              "reason": {
                "description": "Why it is not taken.",
                "type": "string"
              }
            },
            "required": [
              "event",
              "path",
              "by",
              "reason"
            ],
            "type": "object"
          },
          {
            "description": "The mode of a target was set, at the end of a `configure`.",
            "properties": {
              "event": {
                "enum": [
                  "mode_changed"
                ],
                "type": "string"
              },
              "mode": {
                "description": "Mode.",
                "type": "string"
              },
              "path": {
                "description": "Step.",
                "type": "string"
              },
              "target": {
                "description": "Target.",
                "type": "string"
              }
            },
            "required": [
              "event",
              "path",
              "target",
              "mode"
            ],
            "type": "object"
          },
          {
            "description": "An executor takes the run up after a restart, replaying its log.",
            "properties": {
              "by": {
                "description": "Executor instance.",
                "type": "string"
              },
              "event": {
                "enum": [
                  "taken_over"
                ],
                "type": "string"
              }
            },
            "required": [
              "event",
              "by"
            ],
            "type": "object"
          },
          {
            "description": "The run is suspended at the end of an instruction; its leases are released.",
            "properties": {
              "by": {
                "description": "Operator.",
                "type": "string"
              },
              "event": {
                "enum": [
                  "suspended"
                ],
                "type": "string"
              },
              "path": {
                "description": "Step where it stopped.",
                "type": "string"
              }
            },
            "required": [
              "event",
              "path",
              "by"
            ],
            "type": "object"
          },
          {
            "description": "The run goes on after a suspension, leases taken again and targets checked.",
            "properties": {
              "by": {
                "description": "Operator.",
                "type": "string"
              },
              "choice": {
                "description": "`replay` the step, `skip` it, or `abort` the run.",
                "type": "string"
              },
              "event": {
                "enum": [
                  "continued"
                ],
                "type": "string"
              },
              "path": {
                "description": "Step where it stopped.",
                "type": "string"
              }
            },
            "required": [
              "event",
              "path",
              "by",
              "choice"
            ],
            "type": "object"
          },
          {
            "description": "A step waits for an operator decision, answered like an `ask`: `replay`, `skip` or\n`abort`. Asked for a step not eligible for retry that failed, and for a step interrupted\nafter a telecommand changing the on-board state.",
            "properties": {
              "event": {
                "enum": [
                  "decision_required"
                ],
                "type": "string"
              },
              "path": {
                "description": "Step.",
                "type": "string"
              },
              "reason": {
                "description": "Why.",
                "type": "string"
              }
            },
            "required": [
              "event",
              "path",
              "reason"
            ],
            "type": "object"
          },
          {
            "description": "An attempt of a step ends.",
            "properties": {
              "attempt": {
                "default": 1,
                "description": "Attempt, from 1.",
                "format": "uint32",
                "minimum": 0,
                "type": "integer"
              },
              "event": {
                "enum": [
                  "step_finished"
                ],
                "type": "string"
              },
              "ok": {
                "description": "Whether it succeeded.",
                "type": "boolean"
              },
              "path": {
                "description": "Step.",
                "type": "string"
              },
              "reason": {
                "description": "Why it failed.",
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "event",
              "path",
              "ok"
            ],
            "type": "object"
          },
          {
            "description": "The run ends.",
            "properties": {
              "event": {
                "enum": [
                  "finished"
                ],
                "type": "string"
              },
              "ok": {
                "description": "Whether the procedure succeeded.",
                "type": "boolean"
              },
              "reason": {
                "description": "Why it failed.",
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "event",
              "ok"
            ],
            "type": "object"
          }
        ],
        "properties": {
          "at": {
            "description": "Time of the event.",
            "type": "string"
          },
          "run": {
            "description": "Run.",
            "type": "string"
          },
          "seq": {
            "description": "Position in the log, from 1.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "run",
          "seq",
          "at"
        ],
        "title": "Stellar Control run event",
        "type": "object"
      },
      "RunReply": {
        "type": "object",
        "description": "Body of the reply to a launched run.",
        "required": [
          "run",
          "ir"
        ],
        "properties": {
          "run": {
            "type": "string",
            "description": "Identifier of the run."
          },
          "ir": {
            "type": "string",
            "description": "Hash of the resolved run in `stellar_ir`."
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "What the operator should know: a run that may end after the LOS of the pass in progress."
          }
        }
      },
      "RunRequest": {
        "type": "object",
        "description": "A run request, as the API, the CLI and the scheduler write it.",
        "required": [
          "run",
          "environment",
          "targets"
        ],
        "properties": {
          "run": {
            "type": "string",
            "description": "Procedure."
          },
          "library": {
            "type": [
              "string",
              "null"
            ],
            "description": "Library of the procedure, when several have a procedure of that name."
          },
          "environment": {
            "type": "string",
            "description": "Environment."
          },
          "targets": {
            "type": "object",
            "description": "Target of each role.",
            "additionalProperties": {
              "type": "string"
            },
            "propertyNames": {
              "type": "string"
            }
          },
          "inputs": {
            "type": "object",
            "description": "Input values.",
            "additionalProperties": {
              "$ref": "#/components/schemas/InputArg"
            },
            "propertyNames": {
              "type": "string"
            }
          },
          "plan": {
            "type": [
              "string",
              "null"
            ],
            "description": "Pass the run is planned on, set by the scheduler."
          },
          "faults": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FaultRequest"
            },
            "description": "Faults of the simulations to switch on during the run: simulated targets only."
          }
        },
        "additionalProperties": false
      },
      "RunStatus": {
        "type": "object",
        "description": "State of a run, from its log.",
        "required": [
          "run",
          "procedure",
          "suspended"
        ],
        "properties": {
          "run": {
            "type": "string",
            "description": "Run."
          },
          "procedure": {
            "type": "string",
            "description": "Procedure."
          },
          "step": {
            "type": [
              "string",
              "null"
            ],
            "description": "Step running or last run."
          },
          "suspended": {
            "type": "boolean",
            "description": "Whether it is suspended."
          },
          "pending": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Pending",
                "description": "Question or decision waiting for an operator."
              },
              {
                "type": "null"
              }
            ]
          },
          "finished": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Outcome, once finished."
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why it failed."
          }
        }
      },
      "RunSummary": {
        "allOf": [
          {
            "$ref": "#/components/schemas/RunStatus",
            "description": "State."
          },
          {
            "type": "object",
            "required": [
              "environment",
              "targets"
            ],
            "properties": {
              "environment": {
                "type": "string",
                "description": "Environment."
              },
              "targets": {
                "type": "object",
                "description": "Target of each role.",
                "additionalProperties": {
                  "type": "string"
                },
                "propertyNames": {
                  "type": "string"
                }
              },
              "by": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Who launched it."
              },
              "started_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Start."
              },
              "updated_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Last event."
              }
            }
          }
        ],
        "description": "A run in the list of the recent runs."
      },
      "Runs": {
        "type": "object",
        "description": "Body of `GET /v1/runs`.",
        "required": [
          "runs"
        ],
        "properties": {
          "runs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RunSummary"
            },
            "description": "Runs, newest first."
          }
        }
      },
      "Sample": {
        "additionalProperties": false,
        "description": "A measure sample, published by the compute stage on\n`stellar.param.<target>.<component>.<instance>.<measure>`.",
        "properties": {
          "delivery": {
            "description": "`realtime` or `deferred`; deferred when any input of a derived measure is.",
            "type": "string"
          },
          "ground_time": {
            "description": "Ground reception time, reference of freshness; for a derived measure, that of its oldest\ninput.",
            "type": "string"
          },
          "link": {
            "description": "Link of the frame; for a derived measure, that of its most recent input.",
            "type": "string"
          },
          "raw": {
            "description": "Raw value of a measure calibrated by the MCS."
          },
          "time": {
            "description": "Time of the sample: on-board time when known, else ground reception time; for a derived\nmeasure, that of its most recent input.",
            "type": "string"
          },
          "value": {
            "description": "Physical value: number in the unit of the measure, boolean, enum value, hexadecimal bytes;\n`null` when a temporal derived measure becomes unknown (empty window)."
          }
        },
        "required": [
          "value",
          "time",
          "ground_time",
          "link",
          "delivery"
        ],
        "title": "Stellar Control measure sample",
        "type": "object"
      },
      "Schedule": {
        "additionalProperties": false,
        "description": "A run bound to a pass, in `stellar_schedule` under its identifier.",
        "properties": {
          "by": {
            "description": "Who created it.",
            "type": [
              "string",
              "null"
            ]
          },
          "environment": {
            "description": "Environment; by default the last environment of the target of the pass.",
            "type": [
              "string",
              "null"
            ]
          },
          "fire_at": {
            "description": "Start time from the current pass, set by the MCS.",
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "description": "Identifier.",
            "type": "string"
          },
          "inputs": {
            "additionalProperties": true,
            "description": "Input values, as written in a run request.",
            "type": "object"
          },
          "ir": {
            "description": "Hash of the resolved run, set by the MCS.",
            "type": [
              "string",
              "null"
            ]
          },
          "library": {
            "description": "Library of the procedure, when several have a procedure of that name.",
            "type": [
              "string",
              "null"
            ]
          },
          "max_duration": {
            "description": "Maximum duration of the run, set by the MCS.",
            "type": [
              "string",
              "null"
            ]
          },
          "needs_validation": {
            "default": false,
            "description": "Whether a supervisor must validate the plan before it starts: a `hazardous`\ntelecommand in an environment where the supervisor confirms. Set by the MCS.",
            "type": "boolean"
          },
          "pass": {
            "description": "Pass.",
            "type": "string"
          },
          "reasons": {
            "description": "Why at risk, cancelled or missed.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "run": {
            "description": "Procedure.",
            "type": "string"
          },
          "run_id": {
            "description": "Run submitted, set by the MCS.",
            "type": [
              "string",
              "null"
            ]
          },
          "sends": {
            "default": false,
            "description": "Whether the run sends telecommands, set by the MCS.",
            "type": "boolean"
          },
          "start": {
            "description": "Start relative to the AOS: `aos`, `aos + 30 s`.",
            "type": "string"
          },
          "state": {
            "$ref": "#/components/schemas/ScheduleState",
            "default": "scheduled",
            "description": "State, set by the MCS."
          },
          "target": {
            "description": "Target of the pass, set by the MCS.",
            "type": [
              "string",
              "null"
            ]
          },
          "targets": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Target of each role.",
            "type": "object"
          },
          "updated_at": {
            "description": "Last change.",
            "type": [
              "string",
              "null"
            ]
          },
          "validation": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PlanValidation"
              },
              {
                "type": "null"
              }
            ],
            "description": "Validation of the plan, while it holds."
          }
        },
        "required": [
          "id",
          "pass",
          "start",
          "run",
          "targets"
        ],
        "title": "Stellar Control schedule",
        "type": "object"
      },
      "ScheduleRule": {
        "additionalProperties": false,
        "description": "A recurring rule, in `stellar_schedule_rules`: every pass of `target` matching `filter`\ngets the schedule `<rule>-<pass>`.",
        "properties": {
          "by": {
            "description": "Who created it.",
            "type": [
              "string",
              "null"
            ]
          },
          "environment": {
            "description": "Environment; by default the last environment of the target.",
            "type": [
              "string",
              "null"
            ]
          },
          "filter": {
            "$ref": "#/components/schemas/PassFilter",
            "default": {},
            "description": "Passes it applies to."
          },
          "id": {
            "description": "Identifier.",
            "type": "string"
          },
          "inputs": {
            "additionalProperties": true,
            "description": "Input values, as written in a run request.",
            "type": "object"
          },
          "library": {
            "description": "Library of the procedure, when several have a procedure of that name.",
            "type": [
              "string",
              "null"
            ]
          },
          "run": {
            "description": "Procedure.",
            "type": "string"
          },
          "start": {
            "description": "Start relative to the AOS: `aos`, `aos + 30 s`.",
            "type": "string"
          },
          "target": {
            "description": "Target of the passes.",
            "type": "string"
          },
          "targets": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Target of each role.",
            "type": "object"
          }
        },
        "required": [
          "id",
          "target",
          "start",
          "run",
          "targets"
        ],
        "title": "Stellar Control schedule rule",
        "type": "object"
      },
      "ScheduleState": {
        "description": "State of a schedule.",
        "oneOf": [
          {
            "description": "Will start at its time.",
            "enum": [
              "scheduled"
            ],
            "type": "string"
          },
          {
            "description": "Will not start unless its pass changes again: see `reasons`.",
            "enum": [
              "at_risk"
            ],
            "type": "string"
          },
          {
            "description": "Its pass, or an operator, cancelled it.",
            "enum": [
              "cancelled"
            ],
            "type": "string"
          },
          {
            "description": "Its run was submitted.",
            "enum": [
              "fired"
            ],
            "type": "string"
          },
          {
            "description": "Its time came while at risk: not started.",
            "enum": [
              "missed"
            ],
            "type": "string"
          }
        ]
      },
      "Schedules": {
        "type": "object",
        "description": "Body of `GET /v1/schedules`.",
        "required": [
          "schedules"
        ],
        "properties": {
          "schedules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Schedule"
            },
            "description": "Schedules, by start."
          }
        }
      },
      "Shelve": {
        "type": "object",
        "description": "Body of `POST /v1/alarms/{target}/{alarm}/shelve`.",
        "required": [
          "for"
        ],
        "properties": {
          "for": {
            "type": "string",
            "example": "30 min"
          }
        },
        "additionalProperties": false
      },
      "SignIn": {
        "type": "object",
        "description": "How the web console signs its users in at the identity provider.",
        "required": [
          "issuer",
          "client_id",
          "scopes"
        ],
        "properties": {
          "issuer": {
            "type": "string",
            "description": "OpenID Connect issuer: its discovery document is `<issuer>/.well-known/openid-configuration`."
          },
          "client_id": {
            "type": "string",
            "description": "Public client of the console (authorization code with PKCE)."
          },
          "cli_client_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Public client of the CLI (device authorization grant, `stellar login`), if any."
          },
          "organization": {
            "type": [
              "string",
              "null"
            ],
            "description": "Organization (Logto) whose token the console asks for, its audience\n`urn:logto:organization:<organization>`; none: the token of the sign-in itself."
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Scopes to ask beyond those of OpenID: the roles of the MCS with `auth.roles_prefix`\n(`stellar:operator`), which the provider puts in the token only when asked."
          }
        }
      },
      "Software": {
        "additionalProperties": false,
        "description": "Software of an instance.",
        "properties": {
          "name": {
            "description": "Name, such as `platform-v3-ccsds`.",
            "type": "string"
          },
          "version": {
            "description": "Semantic version, such as `3.1.0`.",
            "type": "string"
          }
        },
        "required": [
          "name",
          "version"
        ],
        "type": "object"
      },
      "Status": {
        "additionalProperties": false,
        "description": "Reply to the `status` control verb.",
        "properties": {
          "bound": {
            "description": "Whether the instance holds a JWT issued by the reconciler.",
            "type": "boolean"
          },
          "heartbeat": {
            "$ref": "#/components/schemas/Heartbeat",
            "description": "Last heartbeat content."
          },
          "instance": {
            "description": "Instance.",
            "type": "string"
          },
          "kind": {
            "description": "Kind.",
            "type": "string"
          },
          "software": {
            "$ref": "#/components/schemas/Software",
            "description": "Software."
          },
          "started_at": {
            "description": "Start time.",
            "type": "string"
          }
        },
        "required": [
          "kind",
          "instance",
          "software",
          "heartbeat",
          "started_at",
          "bound"
        ],
        "type": "object"
      },
      "StoredContent": {
        "type": "object",
        "description": "Reply of `POST /v1/uploads`.",
        "required": [
          "hash",
          "size"
        ],
        "properties": {
          "hash": {
            "type": "string",
            "description": "Hexadecimal SHA-256: the value of a `file` input."
          },
          "size": {
            "type": "integer",
            "format": "int64",
            "description": "Size, in bytes.",
            "minimum": 0
          }
        }
      },
      "Submission": {
        "type": "object",
        "description": "Body of `POST /v1/tc`.",
        "required": [
          "target",
          "telecommand"
        ],
        "properties": {
          "target": {
            "type": "string",
            "description": "Target."
          },
          "telecommand": {
            "type": "string",
            "description": "Telecommand: its name alone when unique in the platform, else `component.name`."
          },
          "instance": {
            "type": [
              "string",
              "null"
            ],
            "description": "Instance of a multi-instance component, or file id for `files`."
          },
          "args": {
            "type": "object",
            "description": "Arguments: `100 V`, enum values, booleans, hexadecimal bytes.",
            "additionalProperties": {
              "$ref": "#/components/schemas/InputArg"
            },
            "propertyNames": {
              "type": "string"
            }
          },
          "link": {
            "type": [
              "string",
              "null"
            ],
            "description": "Link, when not the default one."
          },
          "environment": {
            "type": [
              "string",
              "null"
            ],
            "description": "Environment, which selects the parameters of the link; required when the link overrides\nthem by environment and the target is engaged in several."
          },
          "id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Identifier chosen by the client, to make the submission idempotent."
          }
        },
        "additionalProperties": false
      },
      "SubmissionReply": {
        "type": "object",
        "description": "Body of the reply to an accepted submission.",
        "required": [
          "id",
          "duplicate"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Identifier of the telecommand."
          },
          "duplicate": {
            "type": "boolean",
            "description": "Whether the same identifier was already submitted: nothing new is sent."
          }
        }
      },
      "Switch": {
        "type": "object",
        "description": "Body of `PUT /v1/sim/{gateway}/faults/{fault}`.",
        "required": [
          "active"
        ],
        "properties": {
          "active": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "TargetView": {
        "type": "object",
        "description": "A target and its state.",
        "required": [
          "name",
          "platform",
          "environments",
          "links",
          "reasons"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name."
          },
          "platform": {
            "type": "string",
            "description": "Platform, `package@version`."
          },
          "environments": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Environments where it can be engaged."
          },
          "links": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LinkView"
            },
            "description": "Links."
          },
          "ready": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether it can be engaged; `None` when the reconciler published nothing yet."
          },
          "reasons": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Why it is not ready."
          },
          "config": {
            "type": [
              "string",
              "null"
            ],
            "description": "Configuration revision it runs with."
          },
          "lease": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LeaseView",
                "description": "Runs holding it."
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "TcEvent": {
        "additionalProperties": false,
        "description": "A transition of a telecommand, published on `stellar.tc.evt.<target>.<tc_id>`.",
        "properties": {
          "at": {
            "description": "Time of the transition.",
            "type": "string"
          },
          "conforming": {
            "description": "For an `ECHO` event: whether the echo conforms.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "detail": {
            "description": "Explanation: failed precondition, error of the driver or the gateway, echo…",
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "$ref": "#/components/schemas/TcState",
            "description": "New state."
          },
          "tc": {
            "description": "Telecommand.",
            "type": "string"
          },
          "telecommand": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TcRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "For a `PENDING` event: the telecommand, for `sent_at` in derived measures."
          }
        },
        "required": [
          "tc",
          "state",
          "at"
        ],
        "title": "Stellar Control telecommand event",
        "type": "object"
      },
      "TcRef": {
        "additionalProperties": false,
        "description": "A telecommand of a component instance.",
        "properties": {
          "component": {
            "description": "Component.",
            "type": "string"
          },
          "instance": {
            "description": "Instance.",
            "type": [
              "string",
              "null"
            ]
          },
          "telecommand": {
            "description": "Telecommand.",
            "type": "string"
          }
        },
        "required": [
          "component",
          "telecommand"
        ],
        "type": "object"
      },
      "TcState": {
        "description": "State of a telecommand (spec « Cycle de vie d'une TC »).",
        "oneOf": [
          {
            "description": "Accepted, preconditions not yet evaluated.",
            "enum": [
              "PENDING"
            ],
            "type": "string"
          },
          {
            "description": "A precondition (`requires`) does not hold; never encoded.",
            "enum": [
              "REJECTED"
            ],
            "type": "string"
          },
          {
            "description": "Encoded by the driver (ACK 1).",
            "enum": [
              "ENCODED"
            ],
            "type": "string"
          },
          {
            "description": "The driver could not encode it.",
            "enum": [
              "ENCODE_FAILED"
            ],
            "type": "string"
          },
          {
            "description": "Sent by the gateway (ACK 2).",
            "enum": [
              "SENT"
            ],
            "type": "string"
          },
          {
            "description": "The gateway could not send it.",
            "enum": [
              "SEND_FAILED"
            ],
            "type": "string"
          },
          {
            "description": "Its verification holds (ACK 3).",
            "enum": [
              "VERIFIED"
            ],
            "type": "string"
          },
          {
            "description": "An echo is not conforming, or a verification without window is false.",
            "enum": [
              "VERIFY_FAILED"
            ],
            "type": "string"
          },
          {
            "description": "Its verification did not hold within its window.",
            "enum": [
              "VERIFY_TIMEOUT"
            ],
            "type": "string"
          },
          {
            "description": "Sent, without verification.",
            "enum": [
              "COMPLETE"
            ],
            "type": "string"
          },
          {
            "description": "Not a state: on-board echo seen by the driver, `conforming` or not.",
            "enum": [
              "ECHO"
            ],
            "type": "string"
          }
        ]
      },
      "TcWatched": {
        "type": "object",
        "description": "An event of a telecommand, with its target: a message of `GET /v1/tc/watch`.",
        "required": [
          "target",
          "event"
        ],
        "properties": {
          "target": {
            "type": "string",
            "description": "Target of the telecommand."
          },
          "event": {
            "$ref": "#/components/schemas/TcEvent",
            "description": "The event."
          }
        }
      },
      "TelecommandView": {
        "type": "object",
        "description": "A telecommand.",
        "required": [
          "name",
          "args",
          "changes_state",
          "hazardous"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name."
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Description, from the catalogue."
          },
          "args": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ArgumentView"
            },
            "description": "Arguments."
          },
          "changes_state": {
            "type": "boolean",
            "description": "Whether it changes the on-board state."
          },
          "hazardous": {
            "type": "boolean",
            "description": "Whether it needs a confirmation."
          }
        }
      },
      "ThroughputReport": {
        "additionalProperties": false,
        "description": "Throughput of a gateway for one target, published on `stellar.metrics.<gateway>.<target>`.",
        "properties": {
          "downlink_bps": {
            "description": "Mean downlink throughput over the window, in bits per second.",
            "format": "double",
            "type": "number"
          },
          "downlink_bytes": {
            "description": "Bytes received from the target since the gateway started.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "uplink_bps": {
            "description": "Mean uplink throughput over the window, in bits per second.",
            "format": "double",
            "type": "number"
          },
          "uplink_bytes": {
            "description": "Bytes sent to the target since the gateway started.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "window_ms": {
            "description": "Length of the window, in milliseconds.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "uplink_bps",
          "downlink_bps",
          "uplink_bytes",
          "downlink_bytes",
          "window_ms"
        ],
        "title": "Stellar Control gateway throughput",
        "type": "object"
      },
      "ThroughputView": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ThroughputReport",
            "description": "Report."
          },
          {
            "type": "object",
            "required": [
              "target",
              "at"
            ],
            "properties": {
              "target": {
                "type": "string",
                "description": "Target."
              },
              "at": {
                "type": "string",
                "format": "date-time",
                "description": "Reception by the API."
              }
            }
          }
        ],
        "description": "A throughput report of a gateway for one target."
      },
      "TopologyView": {
        "type": "object",
        "description": "Body of `GET /v1/topology`.",
        "required": [
          "config",
          "environments",
          "policies",
          "targets"
        ],
        "properties": {
          "config": {
            "type": "string",
            "description": "Current configuration revision."
          },
          "environments": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Environments."
          },
          "policies": {
            "type": "object",
            "description": "Policies of each environment.",
            "additionalProperties": {
              "$ref": "#/components/schemas/EnvironmentPolicy"
            },
            "propertyNames": {
              "type": "string"
            }
          },
          "targets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TargetView"
            },
            "description": "Targets."
          }
        }
      },
      "Transfer": {
        "additionalProperties": false,
        "description": "A file transfer, in `stellar_transfers` under `<target>.<file_id>.<generation>`.",
        "properties": {
          "by": {
            "description": "Who asked for it.",
            "type": [
              "string",
              "null"
            ]
          },
          "checksum": {
            "description": "Checksum of the whole file, hexadecimal, as listed.",
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "description": "Creation.",
            "type": "string"
          },
          "direction": {
            "$ref": "#/components/schemas/TransferDirection",
            "default": "download",
            "description": "Direction."
          },
          "file_id": {
            "description": "File identifier.",
            "type": "string"
          },
          "file_type": {
            "description": "Type of the file (`lttm`…).",
            "type": [
              "string",
              "null"
            ]
          },
          "generation": {
            "description": "Generation of the file.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "priority": {
            "default": 0,
            "description": "Priority: higher first.",
            "format": "int32",
            "type": "integer"
          },
          "reason": {
            "description": "Why corrupted or superseded.",
            "type": [
              "string",
              "null"
            ]
          },
          "received": {
            "description": "Ranges received, `[start, end)` in bytes, sorted and disjoint.",
            "items": {
              "items": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "maxItems": 2,
              "minItems": 2,
              "type": "array"
            },
            "type": "array"
          },
          "size": {
            "description": "Size, in bytes.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "source": {
            "description": "Content uploaded: its hexadecimal SHA-256 in [`UPLOADS_STORE`].",
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "$ref": "#/components/schemas/TransferState",
            "default": "REQUESTED",
            "description": "State."
          },
          "target": {
            "description": "Target.",
            "type": "string"
          },
          "updated_at": {
            "description": "Last change.",
            "type": "string"
          }
        },
        "required": [
          "target",
          "file_id",
          "generation",
          "size",
          "created_at",
          "updated_at"
        ],
        "title": "Stellar Control file transfer",
        "type": "object"
      },
      "TransferDirection": {
        "description": "Direction of a transfer.",
        "oneOf": [
          {
            "description": "From the target.",
            "enum": [
              "download"
            ],
            "type": "string"
          },
          {
            "description": "To the target.",
            "enum": [
              "upload"
            ],
            "type": "string"
          }
        ]
      },
      "TransferState": {
        "description": "State of a transfer (spec « Téléchargement »), the value of `files[f].transfer`.",
        "oneOf": [
          {
            "description": "Created, nothing received.",
            "enum": [
              "REQUESTED"
            ],
            "type": "string"
          },
          {
            "description": "Some ranges received.",
            "enum": [
              "PARTIAL"
            ],
            "type": "string"
          },
          {
            "description": "Every byte received.",
            "enum": [
              "COMPLETE"
            ],
            "type": "string"
          },
          {
            "description": "Checksum verified.",
            "enum": [
              "VERIFIED"
            ],
            "type": "string"
          },
          {
            "description": "Processed after verification (LTTM decoded).",
            "enum": [
              "PROCESSED"
            ],
            "type": "string"
          },
          {
            "description": "Checksum not verified.",
            "enum": [
              "CORRUPTED"
            ],
            "type": "string"
          },
          {
            "description": "Rewritten on board before its end.",
            "enum": [
              "SUPERSEDED"
            ],
            "type": "string"
          }
        ]
      },
      "Transfers": {
        "type": "object",
        "description": "Body of `GET /v1/transfers`.",
        "required": [
          "transfers"
        ],
        "properties": {
          "transfers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Transfer"
            },
            "description": "Transfers, by priority then age."
          }
        }
      },
      "Trigger": {
        "type": "object",
        "description": "When a scheduled fault switches: `after` a delay from the start of the run (or from its\nswitching on, for `off`), or from the first entry in the step `step`.",
        "properties": {
          "step": {
            "type": [
              "string",
              "null"
            ],
            "description": "Step whose first entry starts the delay: its name (`Plateau`), or its path (`TVAC cycle /\nPlateau`)."
          },
          "after": {
            "type": "string",
            "description": "Delay."
          }
        },
        "additionalProperties": false
      },
      "Values": {
        "type": "object",
        "description": "Body of `GET /v1/targets/{target}/values`.",
        "required": [
          "values"
        ],
        "properties": {
          "values": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CurrentValue"
            },
            "description": "Current values, by key order."
          }
        }
      }
    },
    "securitySchemes": {
      "declared": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Stellar-User",
        "description": "Identity declared by the caller, with its roles in `X-Stellar-Role`; accepted where the environment allows it (`identity: declared`, or no human orchestration)."
      },
      "oidc": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "OIDC token of the identity provider (`auth.jwks_file`, `auth.issuer`, `auth.audience`), its roles at `auth.roles_claim`."
      }
    }
  },
  "security": [
    {},
    {
      "oidc": []
    },
    {
      "declared": []
    }
  ],
  "tags": [
    {
      "name": "telecommands",
      "description": "Direct telecommands and their acknowledgement chain."
    },
    {
      "name": "values",
      "description": "Current values of the measures of a target."
    },
    {
      "name": "modes",
      "description": "Modes of the targets and the values of their parameters in each mode."
    },
    {
      "name": "runs",
      "description": "Runs of procedures: launch, follow-up, answers, control and reports."
    },
    {
      "name": "alarms",
      "description": "Alarms: current states, acknowledgement and shelving, transitions."
    },
    {
      "name": "passes",
      "description": "Passes of the targets over the ground stations, pushed by the feeders."
    },
    {
      "name": "schedules",
      "description": "Runs scheduled on passes, and the recurring rules that schedule them."
    },
    {
      "name": "files",
      "description": "On-board directory, file transfers and contents to upload."
    },
    {
      "name": "monitoring",
      "description": "Topology, instances, catalogues, procedures and output connectors, as the web console shows them."
    },
    {
      "name": "auth",
      "description": "How to sign in, and NATS credentials of follow-up."
    },
    {
      "name": "simulation",
      "description": "Faults of simulated targets."
    },
    {
      "name": "meta",
      "description": "The API itself."
    }
  ]
}