{
  "components": {
    "schemas": {
      "APIError": {
        "additionalProperties": false,
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ErrorDetail"
          }
        },
        "required": [
          "error"
        ],
        "type": "object"
      },
      "APIKey": {
        "additionalProperties": false,
        "properties": {
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "expires_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "hint": {
            "description": "Prefix of the key, for recognizing it",
            "type": "string"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "last_used_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "last_used_ip": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "scopes": {
            "description": "Permissions the key is limited to; null means all of the owner's permissions",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "name",
          "hint",
          "scopes",
          "last_used_at",
          "last_used_ip",
          "expires_at",
          "created_at"
        ],
        "type": "object"
      },
      "APIKeysOutputBody": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/APIKey"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "Add-ssh-keyRequest": {
        "additionalProperties": false,
        "properties": {
          "name": {
            "maxLength": 100,
            "type": "string"
          },
          "public_key": {
            "description": "One line in OpenSSH format, e.g. ssh-ed25519 AAAA... me@pc",
            "maxLength": 16384,
            "minLength": 20,
            "type": "string"
          }
        },
        "required": [
          "public_key"
        ],
        "type": "object"
      },
      "AgentRelease": {
        "additionalProperties": false,
        "properties": {
          "arch": {
            "type": "string"
          },
          "os": {
            "type": "string"
          },
          "sha256": {
            "type": "string"
          },
          "size": {
            "format": "int64",
            "type": "integer"
          },
          "version": {
            "type": "string"
          }
        },
        "required": [
          "version",
          "os",
          "arch",
          "size",
          "sha256"
        ],
        "type": "object"
      },
      "AuditEvent": {
        "additionalProperties": false,
        "properties": {
          "action": {
            "type": "string"
          },
          "actor_api_key_id": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "actor_label": {
            "type": "string"
          },
          "actor_user_id": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "details": {},
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "ip": {
            "type": [
              "string",
              "null"
            ]
          },
          "outcome": {
            "enum": [
              "success",
              "failure",
              "denied"
            ],
            "type": "string"
          },
          "target_id": {
            "type": "string"
          },
          "target_type": {
            "type": "string"
          },
          "ts": {
            "format": "date-time",
            "type": "string"
          },
          "user_agent": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "ts",
          "actor_user_id",
          "actor_api_key_id",
          "actor_label",
          "ip",
          "user_agent",
          "action",
          "target_type",
          "target_id",
          "outcome",
          "details"
        ],
        "type": "object"
      },
      "BackupView": {
        "additionalProperties": false,
        "properties": {
          "completed_at": {
            "format": "date-time",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "error": {
            "type": "string"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "location": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "provider": {
            "type": "string"
          },
          "restore_error": {
            "type": "string"
          },
          "restore_status": {
            "enum": [
              "",
              "running",
              "completed",
              "failed"
            ],
            "type": "string"
          },
          "restored_at": {
            "format": "date-time",
            "type": "string"
          },
          "scheduled": {
            "type": "boolean"
          },
          "size_bytes": {
            "format": "int64",
            "type": "integer"
          },
          "status": {
            "enum": [
              "pending",
              "running",
              "completed",
              "failed",
              "deleted"
            ],
            "type": "string"
          },
          "target": {
            "type": "string"
          },
          "target_id": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "id",
          "target",
          "provider",
          "status",
          "scheduled",
          "location",
          "size_bytes",
          "error",
          "message",
          "created_at",
          "restore_status",
          "restore_error"
        ],
        "type": "object"
      },
      "Begin-uploadRequest": {
        "additionalProperties": false,
        "properties": {
          "overwrite": {
            "type": "boolean"
          },
          "path": {
            "maxLength": 4096,
            "minLength": 1,
            "type": "string"
          },
          "size": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "path",
          "size"
        ],
        "type": "object"
      },
      "Branding": {
        "additionalProperties": false,
        "properties": {
          "product_name": {
            "description": "Name shown in the UI title bar and login page",
            "maxLength": 40,
            "type": "string"
          },
          "support_url": {
            "description": "Optional link shown on the login page",
            "maxLength": 300,
            "type": "string"
          }
        },
        "required": [
          "product_name",
          "support_url"
        ],
        "type": "object"
      },
      "BrandingOutputBody": {
        "additionalProperties": false,
        "properties": {
          "password_min_length": {
            "description": "Password policy, for form hints",
            "format": "int64",
            "type": "integer"
          },
          "product_name": {
            "type": "string"
          },
          "support_url": {
            "type": "string"
          }
        },
        "required": [
          "product_name",
          "support_url",
          "password_min_length"
        ],
        "type": "object"
      },
      "BuiltinDB": {
        "additionalProperties": false,
        "properties": {
          "available": {
            "type": "boolean"
          },
          "kind": {
            "description": "bundled: the installer's PostgreSQL (Windows); local: this server's PostgreSQL prepared by the package (Linux)",
            "enum": [
              "bundled",
              "local",
              "none"
            ],
            "type": "string"
          },
          "note": {
            "type": "string"
          }
        },
        "required": [
          "available",
          "kind"
        ],
        "type": "object"
      },
      "CAInfo": {
        "additionalProperties": false,
        "properties": {
          "ca_hash": {
            "description": "sha256:\u003chex\u003e of the CA's SubjectPublicKeyInfo",
            "type": "string"
          },
          "ca_pem": {
            "type": "string"
          }
        },
        "required": [
          "ca_pem",
          "ca_hash"
        ],
        "type": "object"
      },
      "CatalogBody": {
        "additionalProperties": false,
        "properties": {
          "description": {
            "maxLength": 500,
            "type": "string"
          },
          "kind": {
            "description": "Fixed after creation",
            "enum": [
              "workshop",
              "workshop_collection"
            ],
            "type": "string"
          },
          "name": {
            "description": "Default: the Workshop title (required for collections)",
            "maxLength": 120,
            "type": "string"
          },
          "workshop_id": {
            "maxLength": 20,
            "type": "string"
          }
        },
        "required": [
          "workshop_id"
        ],
        "type": "object"
      },
      "CatalogMod": {
        "additionalProperties": false,
        "properties": {
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "game_id": {
            "type": "string"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "kind": {
            "enum": [
              "workshop",
              "workshop_collection"
            ],
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          },
          "workshop_id": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "id",
          "game_id",
          "name",
          "kind",
          "workshop_id",
          "description",
          "created_at",
          "updated_at"
        ],
        "type": "object"
      },
      "CatalogOutputBody": {
        "additionalProperties": false,
        "properties": {
          "permissions": {
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "roles": {
            "items": {
              "$ref": "#/components/schemas/RoleInfo"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "service_permissions": {
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "roles",
          "permissions",
          "service_permissions"
        ],
        "type": "object"
      },
      "Change-service-packageRequest": {
        "additionalProperties": false,
        "properties": {
          "package_id": {
            "format": "int64",
            "minimum": 1,
            "type": "integer"
          },
          "slots": {
            "description": "0 = keep the current slots, clamped into the package's range",
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "package_id"
        ],
        "type": "object"
      },
      "CodeInputBody": {
        "additionalProperties": false,
        "properties": {
          "code": {
            "maxLength": 10,
            "minLength": 6,
            "type": "string"
          }
        },
        "required": [
          "code"
        ],
        "type": "object"
      },
      "ConfigFileView": {
        "additionalProperties": false,
        "properties": {
          "error": {
            "description": "Why the file could not be read or parsed",
            "type": "string"
          },
          "exists": {
            "type": "boolean"
          },
          "format": {
            "type": "string"
          },
          "hash": {
            "description": "Content version; send it back to detect concurrent edits",
            "type": "string"
          },
          "index": {
            "description": "Position in the game definition's config_files",
            "format": "int64",
            "type": "integer"
          },
          "label": {
            "type": "string"
          },
          "path": {
            "type": "string"
          },
          "settings": {
            "items": {
              "$ref": "#/components/schemas/ConfigSettingView"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "index",
          "path",
          "label",
          "format",
          "exists",
          "settings"
        ],
        "type": "object"
      },
      "ConfigSettingView": {
        "additionalProperties": false,
        "properties": {
          "bound": {
            "description": "The panel value this setting follows: var.\u003ckey\u003e, slots, or another template (read-only)",
            "type": "string"
          },
          "default": {},
          "description": {
            "type": "string"
          },
          "drift": {
            "description": "The file differs from the bound value until the next start",
            "type": "boolean"
          },
          "editable": {
            "type": "boolean"
          },
          "has_value": {
            "description": "The setting is present in the file (passwords: set)",
            "type": "boolean"
          },
          "key": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "max": {
            "format": "double",
            "type": "number"
          },
          "min": {
            "format": "double",
            "type": "number"
          },
          "options": {
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "step": {
            "format": "double",
            "type": "number"
          },
          "type": {
            "enum": [
              "string",
              "text",
              "int",
              "float",
              "bool",
              "password",
              "select",
              "slider",
              "list"
            ],
            "type": "string"
          },
          "value": {
            "description": "Current value (passwords: always null)"
          }
        },
        "required": [
          "key",
          "label",
          "type",
          "value",
          "has_value",
          "editable"
        ],
        "type": "object"
      },
      "CrashPolicy": {
        "additionalProperties": false,
        "properties": {
          "backoff": {
            "enum": [
              "exponential",
              "fixed"
            ],
            "type": "string"
          },
          "base_delay_sec": {
            "format": "int32",
            "maximum": 3600,
            "minimum": 0,
            "type": "integer"
          },
          "max_restarts": {
            "format": "int32",
            "maximum": 100,
            "minimum": 0,
            "type": "integer"
          },
          "restart": {
            "enum": [
              "always",
              "on_failure",
              "never"
            ],
            "type": "string"
          },
          "window_sec": {
            "format": "int32",
            "maximum": 86400,
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "restart",
          "max_restarts",
          "window_sec",
          "backoff"
        ],
        "type": "object"
      },
      "Create-enrollment-tokenRequest": {
        "additionalProperties": false,
        "properties": {
          "datacenter_id": {
            "format": "int64",
            "minimum": 1,
            "type": "integer"
          },
          "node_name": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "ttl_minutes": {
            "description": "Default 60",
            "format": "int64",
            "maximum": 10080,
            "minimum": 5,
            "type": "integer"
          }
        },
        "required": [
          "datacenter_id",
          "node_name"
        ],
        "type": "object"
      },
      "Create-service-backupRequest": {
        "additionalProperties": false,
        "properties": {
          "target_id": {
            "format": "int64",
            "minimum": 1,
            "type": "integer"
          }
        },
        "required": [
          "target_id"
        ],
        "type": "object"
      },
      "Create-serviceRequest": {
        "additionalProperties": false,
        "properties": {
          "cpu_limit_percent": {
            "description": "Without a package: 0 = unlimited; 100 = one core",
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "crash_policy": {
            "$ref": "#/components/schemas/CrashPolicy"
          },
          "datacenter_id": {
            "description": "Pick the node in this datacenter",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "disk_limit_bytes": {
            "description": "Without a package: 0 = unlimited",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "external_id": {
            "description": "Billing reference (e.g. whmcs-123), unique in the caller's tenancy",
            "maxLength": 100,
            "type": "string"
          },
          "game_id": {
            "description": "Required without a package",
            "maxLength": 64,
            "type": "string"
          },
          "memory_limit_bytes": {
            "description": "Without a package: 0 = unlimited",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "name": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "node_id": {
            "description": "Callers who can see nodes; 0 = picked (online, the game's OS, memory left)",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "owner_display_name": {
            "maxLength": 100,
            "type": "string"
          },
          "owner_email": {
            "description": "Billing: the customer by e-mail address (created when unknown)",
            "maxLength": 254,
            "type": "string"
          },
          "owner_password": {
            "description": "Billing: password for a new customer (default: generated and returned once)",
            "maxLength": 256,
            "type": "string"
          },
          "owner_user_id": {
            "description": "Default: the caller",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "owner_username": {
            "description": "Billing: username for a new customer (default: from the e-mail address)",
            "maxLength": 32,
            "type": "string"
          },
          "package_id": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "slots": {
            "description": "Default: the package's or the game's default",
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "start": {
            "description": "Start right away (after the install); default: the package's start_on_create, else no",
            "type": "boolean"
          },
          "steam_account_id": {
            "description": "Administrators: the Steam account to install with (default: the vault's default)",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "variables": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "Create-sso-linkRequest": {
        "additionalProperties": false,
        "properties": {
          "service_id": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "type": "object"
      },
      "CreateAPIKeyInputBody": {
        "additionalProperties": false,
        "properties": {
          "expires_at": {
            "format": "date-time",
            "type": "string"
          },
          "name": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "scopes": {
            "description": "Limit the key to these permissions; omit for all of yours",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "CreateAPIKeyOutputBody": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "$ref": "#/components/schemas/APIKey"
          },
          "token": {
            "description": "The key itself. Shown only now; store it safely.",
            "type": "string"
          }
        },
        "required": [
          "api_key",
          "token"
        ],
        "type": "object"
      },
      "CreateOutBody": {
        "additionalProperties": false,
        "properties": {
          "cpu_limit_percent": {
            "description": "0 = unlimited; 100 = one core",
            "format": "int32",
            "type": "integer"
          },
          "cpu_percent": {
            "format": "float",
            "type": [
              "number",
              "null"
            ]
          },
          "crash_policy": {
            "$ref": "#/components/schemas/CrashPolicy"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "desired_state": {
            "enum": [
              "running",
              "stopped"
            ],
            "type": "string"
          },
          "disk_limit_bytes": {
            "description": "File manager / SFTP / upload quota; 0 = unlimited",
            "format": "int64",
            "type": "integer"
          },
          "existing": {
            "description": "external_id was already provisioned: this is that game server (nothing was created)",
            "type": "boolean"
          },
          "external_id": {
            "description": "The billing system's reference",
            "type": [
              "string",
              "null"
            ]
          },
          "file_deny": {
            "description": "Deny globs added for this service (on top of the game definition's): matching paths are hidden from everyone except administrators",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "game_id": {
            "type": "string"
          },
          "has_rcon": {
            "description": "The game has a remote console (only on GET /services/{id})",
            "type": "boolean"
          },
          "has_workshop": {
            "description": "The game takes Steam Workshop mods (only on GET /services/{id})",
            "type": "boolean"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "install": {
            "$ref": "#/components/schemas/InstallProgress",
            "description": "While installing / updating"
          },
          "install_dir": {
            "type": "string"
          },
          "installed": {
            "description": "The game files are in place",
            "type": "boolean"
          },
          "ip": {
            "type": "string"
          },
          "last_error": {
            "description": "The last command the agent refused, and why",
            "type": "string"
          },
          "last_exit_code": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "max_players": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "memory_limit_bytes": {
            "description": "0 = unlimited",
            "format": "int64",
            "type": "integer"
          },
          "memory_used_bytes": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "metrics_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "mods": {
            "additionalProperties": {
              "items": {
                "$ref": "#/components/schemas/WorkshopItem"
              },
              "type": [
                "array",
                "null"
              ]
            },
            "description": "Workshop items per modlist variable",
            "type": "object"
          },
          "name": {
            "type": "string"
          },
          "node_connected": {
            "description": "The node's agent link is up",
            "type": "boolean"
          },
          "node_id": {
            "format": "int64",
            "type": "integer"
          },
          "node_name": {
            "type": "string"
          },
          "node_os": {
            "enum": [
              "windows",
              "linux"
            ],
            "type": "string"
          },
          "observed_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "observed_message": {
            "type": "string"
          },
          "observed_status": {
            "description": "What the agent last reported",
            "type": "string"
          },
          "os_user": {
            "type": "string"
          },
          "owner_created": {
            "description": "owner_email named no account: a customer account was created",
            "type": "boolean"
          },
          "owner_password": {
            "description": "The new customer account's generated password (only when none was given; shown once)",
            "type": "string"
          },
          "owner_user_id": {
            "format": "int64",
            "type": "integer"
          },
          "owner_username": {
            "type": "string"
          },
          "package_id": {
            "description": "The package it was ordered with (null = none)",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "permissions": {
            "description": "What the caller may do on this service (absent on WebSocket events)",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "players": {
            "description": "From the game's status query while it runs (null = unknown)",
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "ports": {
            "description": "Only on GET /services/{id}",
            "items": {
              "$ref": "#/components/schemas/PortView"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "primary_port": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "process_count": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "processes": {
            "description": "Only on GET /services/{id}",
            "items": {
              "$ref": "#/components/schemas/ProcessView"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "query_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "query_map": {
            "type": "string"
          },
          "query_name": {
            "description": "Server name the game reports",
            "type": "string"
          },
          "restarts": {
            "description": "Crash restarts within the crash-policy window",
            "format": "int32",
            "type": "integer"
          },
          "secret_variables": {
            "description": "Password variables that have a value (values are never returned)",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "sftp": {
            "$ref": "#/components/schemas/SFTPInfo",
            "description": "How the caller connects with SFTP (only on GET /services/{id}, with the files permission)"
          },
          "slots": {
            "format": "int32",
            "type": "integer"
          },
          "status": {
            "enum": [
              "installing",
              "install_failed",
              "stopped",
              "starting",
              "running",
              "stopping",
              "crashed",
              "suspended",
              "moving",
              "deleting"
            ],
            "type": "string"
          },
          "steam_account_id": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "suspend_reason": {
            "description": "Why it was suspended (billing or an administrator)",
            "type": "string"
          },
          "suspended": {
            "type": "boolean"
          },
          "variables": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object"
          }
        },
        "required": [
          "existing",
          "id",
          "name",
          "game_id",
          "node_id",
          "node_name",
          "node_os",
          "node_connected",
          "owner_user_id",
          "owner_username",
          "status",
          "desired_state",
          "observed_status",
          "observed_message",
          "observed_at",
          "last_error",
          "restarts",
          "last_exit_code",
          "install_dir",
          "os_user",
          "ip",
          "primary_port",
          "slots",
          "variables",
          "cpu_limit_percent",
          "memory_limit_bytes",
          "disk_limit_bytes",
          "file_deny",
          "crash_policy",
          "cpu_percent",
          "memory_used_bytes",
          "process_count",
          "metrics_at",
          "players",
          "max_players",
          "query_name",
          "query_map",
          "query_at",
          "suspended",
          "suspend_reason",
          "package_id",
          "external_id",
          "installed",
          "secret_variables",
          "mods",
          "steam_account_id",
          "created_at"
        ],
        "type": "object"
      },
      "CreateUserInputBody": {
        "additionalProperties": false,
        "properties": {
          "denied_permissions": {
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "display_name": {
            "maxLength": 100,
            "type": "string"
          },
          "email": {
            "maxLength": 254,
            "type": "string"
          },
          "extra_permissions": {
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "must_change_password": {
            "type": "boolean"
          },
          "password": {
            "maxLength": 1024,
            "type": "string"
          },
          "reseller_id": {
            "description": "Admins only; resellers' new users always belong to them",
            "format": "int64",
            "type": "integer"
          },
          "role": {
            "enum": [
              "superadmin",
              "admin",
              "reseller",
              "user",
              "subuser"
            ],
            "type": "string"
          },
          "status": {
            "enum": [
              "active",
              "suspended",
              "disabled"
            ],
            "type": "string"
          },
          "username": {
            "description": "3-32 characters: lower-case letters, digits, '-' and '_' (not first). Upper case is lower-cased.",
            "maxLength": 32,
            "type": "string"
          }
        },
        "required": [
          "email",
          "username",
          "password",
          "role"
        ],
        "type": "object"
      },
      "Datacenter": {
        "additionalProperties": false,
        "properties": {
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "location": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "node_count": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "id",
          "name",
          "location",
          "node_count",
          "created_at"
        ],
        "type": "object"
      },
      "DcBody": {
        "additionalProperties": false,
        "properties": {
          "location": {
            "maxLength": 200,
            "type": "string"
          },
          "name": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "Delivery": {
        "additionalProperties": false,
        "properties": {
          "attempts": {
            "format": "int32",
            "type": "integer"
          },
          "channel": {
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "event": {
            "type": "string"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "last_error": {
            "type": "string"
          },
          "sent_at": {
            "format": "date-time",
            "type": "string"
          },
          "status": {
            "enum": [
              "pending",
              "sent",
              "failed"
            ],
            "type": "string"
          },
          "target": {
            "type": "string"
          },
          "webhook": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "webhook",
          "channel",
          "event",
          "target",
          "status",
          "attempts",
          "last_error",
          "created_at"
        ],
        "type": "object"
      },
      "Direct-downloadRequest": {
        "additionalProperties": false,
        "properties": {
          "path": {
            "maxLength": 4096,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "path"
        ],
        "type": "object"
      },
      "Direct-downloadResponse": {
        "additionalProperties": false,
        "properties": {
          "direct": {
            "$ref": "#/components/schemas/DirectTarget"
          }
        },
        "required": [
          "direct"
        ],
        "type": "object"
      },
      "DirectTarget": {
        "additionalProperties": false,
        "properties": {
          "expires_at": {
            "format": "date-time",
            "type": "string"
          },
          "token": {
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        },
        "required": [
          "url",
          "token",
          "expires_at"
        ],
        "type": "object"
      },
      "Disk": {
        "additionalProperties": false,
        "properties": {
          "mount": {
            "maxLength": 260,
            "type": "string"
          },
          "total_bytes": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "mount",
          "total_bytes"
        ],
        "type": "object"
      },
      "DiskUsage": {
        "additionalProperties": false,
        "properties": {
          "mount": {
            "type": "string"
          },
          "total_bytes": {
            "format": "int64",
            "type": "integer"
          },
          "used_bytes": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "mount",
          "used_bytes",
          "total_bytes"
        ],
        "type": "object"
      },
      "EnrollmentToken": {
        "additionalProperties": false,
        "properties": {
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "datacenter_id": {
            "format": "int64",
            "type": "integer"
          },
          "expires_at": {
            "format": "date-time",
            "type": "string"
          },
          "hint": {
            "type": "string"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "node_name": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "hint",
          "datacenter_id",
          "node_name",
          "expires_at",
          "created_at"
        ],
        "type": "object"
      },
      "ErrorDetail": {
        "additionalProperties": false,
        "properties": {
          "code": {
            "description": "Stable machine-readable code, e.g. validation_failed",
            "type": "string"
          },
          "details": {
            "description": "Per-field problems for validation errors",
            "items": {
              "$ref": "#/components/schemas/FieldDetail"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "message": {
            "description": "Human-readable explanation, safe to show to users",
            "type": "string"
          }
        },
        "required": [
          "code",
          "message"
        ],
        "type": "object"
      },
      "Expand-workshopRequest": {
        "additionalProperties": false,
        "properties": {
          "ref": {
            "maxLength": 500,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "ref"
        ],
        "type": "object"
      },
      "FieldDetail": {
        "additionalProperties": false,
        "properties": {
          "location": {
            "description": "Where the problem is, e.g. body.email",
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "value": {}
        },
        "required": [
          "message"
        ],
        "type": "object"
      },
      "File-operationRequest": {
        "additionalProperties": false,
        "properties": {
          "dest": {
            "maxLength": 4096,
            "type": "string"
          },
          "mode": {
            "description": "0-511 (0o777)",
            "format": "int32",
            "maximum": 511,
            "minimum": 0,
            "type": "integer"
          },
          "op": {
            "enum": [
              "mkdir",
              "rename",
              "copy",
              "delete",
              "chmod",
              "compress",
              "extract"
            ],
            "type": "string"
          },
          "overwrite": {
            "type": "boolean"
          },
          "path": {
            "maxLength": 4096,
            "type": "string"
          },
          "paths": {
            "items": {
              "type": "string"
            },
            "maxItems": 1000,
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "op"
        ],
        "type": "object"
      },
      "File-operationResponse": {
        "additionalProperties": false,
        "properties": {
          "entry": {
            "$ref": "#/components/schemas/FileEntry"
          },
          "files": {
            "description": "extract: files written",
            "format": "int64",
            "type": "integer"
          },
          "skipped": {
            "description": "extract: entries left out (existing, denied, links)",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "FileContentOut": {
        "additionalProperties": false,
        "properties": {
          "binary": {
            "description": "Not UTF-8 text: download it instead",
            "type": "boolean"
          },
          "content": {
            "description": "UTF-8 text; empty when binary",
            "type": "string"
          },
          "entry": {
            "$ref": "#/components/schemas/FileEntry"
          },
          "hash": {
            "description": "Send back as expect when saving",
            "type": "string"
          }
        },
        "required": [
          "entry",
          "content",
          "binary",
          "hash"
        ],
        "type": "object"
      },
      "FileEntry": {
        "additionalProperties": false,
        "properties": {
          "mode": {
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "modified": {
            "format": "date-time",
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "path": {
            "type": "string"
          },
          "size": {
            "format": "int64",
            "type": "integer"
          },
          "type": {
            "enum": [
              "file",
              "dir",
              "link",
              "other"
            ],
            "type": "string"
          }
        },
        "required": [
          "name",
          "path",
          "type",
          "size",
          "mode",
          "modified"
        ],
        "type": "object"
      },
      "Game": {
        "additionalProperties": false,
        "properties": {
          "category": {
            "type": "string"
          },
          "has_rcon": {
            "description": "The game has a remote console (RCON console, rcon tasks, stop over RCON)",
            "type": "boolean"
          },
          "has_workshop": {
            "description": "modlist variables take Steam Workshop ids or links",
            "type": "boolean"
          },
          "id": {
            "type": "string"
          },
          "install_steps": {
            "additionalProperties": {
              "format": "int64",
              "type": "integer"
            },
            "description": "Install steps per OS",
            "type": "object"
          },
          "name": {
            "type": "string"
          },
          "needs_steam_account": {
            "description": "Installing needs a Steam account in the vault",
            "type": "boolean"
          },
          "platforms": {
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "ports": {
            "items": {
              "$ref": "#/components/schemas/GamePort"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "slots_default": {
            "format": "int64",
            "type": "integer"
          },
          "slots_max": {
            "format": "int64",
            "type": "integer"
          },
          "slots_min": {
            "format": "int64",
            "type": "integer"
          },
          "variables": {
            "items": {
              "$ref": "#/components/schemas/GameVariable"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "version": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "id",
          "name",
          "category",
          "platforms",
          "slots_min",
          "slots_max",
          "slots_default",
          "ports",
          "variables",
          "version",
          "has_workshop",
          "has_rcon",
          "needs_steam_account",
          "install_steps"
        ],
        "type": "object"
      },
      "GameAdmin": {
        "additionalProperties": false,
        "properties": {
          "category": {
            "type": "string"
          },
          "enabled": {
            "type": "boolean"
          },
          "has_rcon": {
            "description": "The game has a remote console (RCON console, rcon tasks, stop over RCON)",
            "type": "boolean"
          },
          "has_workshop": {
            "description": "modlist variables take Steam Workshop ids or links",
            "type": "boolean"
          },
          "id": {
            "type": "string"
          },
          "install_steps": {
            "additionalProperties": {
              "format": "int64",
              "type": "integer"
            },
            "description": "Install steps per OS",
            "type": "object"
          },
          "name": {
            "type": "string"
          },
          "needs_steam_account": {
            "description": "Installing needs a Steam account in the vault",
            "type": "boolean"
          },
          "origin": {
            "description": "builtin definitions refresh with the controller until someone edits them",
            "enum": [
              "builtin",
              "custom"
            ],
            "type": "string"
          },
          "platforms": {
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "ports": {
            "items": {
              "$ref": "#/components/schemas/GamePort"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "service_count": {
            "format": "int64",
            "type": "integer"
          },
          "slots_default": {
            "format": "int64",
            "type": "integer"
          },
          "slots_max": {
            "format": "int64",
            "type": "integer"
          },
          "slots_min": {
            "format": "int64",
            "type": "integer"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          },
          "variables": {
            "items": {
              "$ref": "#/components/schemas/GameVariable"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "version": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "origin",
          "enabled",
          "service_count",
          "updated_at",
          "id",
          "name",
          "category",
          "platforms",
          "slots_min",
          "slots_max",
          "slots_default",
          "ports",
          "variables",
          "version",
          "has_workshop",
          "has_rcon",
          "needs_steam_account",
          "install_steps"
        ],
        "type": "object"
      },
      "GamePort": {
        "additionalProperties": false,
        "properties": {
          "default": {
            "format": "int64",
            "type": "integer"
          },
          "offset": {
            "format": "int64",
            "type": "integer"
          },
          "proto": {
            "enum": [
              "tcp",
              "udp",
              "both"
            ],
            "type": "string"
          },
          "role": {
            "type": "string"
          }
        },
        "required": [
          "role",
          "proto",
          "offset"
        ],
        "type": "object"
      },
      "GameSource": {
        "additionalProperties": false,
        "properties": {
          "category": {
            "type": "string"
          },
          "enabled": {
            "type": "boolean"
          },
          "has_rcon": {
            "description": "The game has a remote console (RCON console, rcon tasks, stop over RCON)",
            "type": "boolean"
          },
          "has_workshop": {
            "description": "modlist variables take Steam Workshop ids or links",
            "type": "boolean"
          },
          "id": {
            "type": "string"
          },
          "install_steps": {
            "additionalProperties": {
              "format": "int64",
              "type": "integer"
            },
            "description": "Install steps per OS",
            "type": "object"
          },
          "name": {
            "type": "string"
          },
          "needs_steam_account": {
            "description": "Installing needs a Steam account in the vault",
            "type": "boolean"
          },
          "origin": {
            "description": "builtin definitions refresh with the controller until someone edits them",
            "enum": [
              "builtin",
              "custom"
            ],
            "type": "string"
          },
          "platforms": {
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "ports": {
            "items": {
              "$ref": "#/components/schemas/GamePort"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "scripts": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object"
          },
          "service_count": {
            "format": "int64",
            "type": "integer"
          },
          "slots_default": {
            "format": "int64",
            "type": "integer"
          },
          "slots_max": {
            "format": "int64",
            "type": "integer"
          },
          "slots_min": {
            "format": "int64",
            "type": "integer"
          },
          "source_yaml": {
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          },
          "variables": {
            "items": {
              "$ref": "#/components/schemas/GameVariable"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "version": {
            "format": "int64",
            "type": "integer"
          },
          "versions": {
            "items": {
              "$ref": "#/components/schemas/GameVersion"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "source_yaml",
          "scripts",
          "versions",
          "origin",
          "enabled",
          "service_count",
          "updated_at",
          "id",
          "name",
          "category",
          "platforms",
          "slots_min",
          "slots_max",
          "slots_default",
          "ports",
          "variables",
          "version",
          "has_workshop",
          "has_rcon",
          "needs_steam_account",
          "install_steps"
        ],
        "type": "object"
      },
      "GameUpload": {
        "additionalProperties": false,
        "properties": {
          "scripts": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "scripts/\u003cname\u003e -\u003e content",
            "type": "object"
          },
          "source_yaml": {
            "description": "game.yaml",
            "maxLength": 262144,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "source_yaml"
        ],
        "type": "object"
      },
      "GameVariable": {
        "additionalProperties": false,
        "properties": {
          "admin_only": {
            "description": "Only administrators may set it",
            "type": "boolean"
          },
          "default": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "generate": {
            "description": "A random value is created when left empty",
            "type": "boolean"
          },
          "key": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "max": {
            "format": "int64",
            "type": "integer"
          },
          "min": {
            "format": "int64",
            "type": "integer"
          },
          "options": {
            "description": "Choices of a select",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "required": {
            "description": "A game server cannot be saved without a value",
            "type": "boolean"
          },
          "type": {
            "enum": [
              "string",
              "int",
              "bool",
              "password",
              "modlist",
              "select"
            ],
            "type": "string"
          },
          "user_editable": {
            "type": "boolean"
          }
        },
        "required": [
          "key",
          "label",
          "type",
          "default",
          "user_editable"
        ],
        "type": "object"
      },
      "GameVersion": {
        "additionalProperties": false,
        "properties": {
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "created_by": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "version": {
            "format": "int32",
            "type": "integer"
          }
        },
        "required": [
          "version",
          "created_by",
          "created_at"
        ],
        "type": "object"
      },
      "Get-game-definition-versionResponse": {
        "additionalProperties": false,
        "properties": {
          "source_yaml": {
            "type": "string"
          }
        },
        "required": [
          "source_yaml"
        ],
        "type": "object"
      },
      "Get-node-metricsResponse": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/MetricSample"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "Get-service-metricsResponse": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/ServiceMetricSample"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "Grant": {
        "additionalProperties": false,
        "properties": {
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "display_name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "permissions": {
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "role": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          },
          "user_id": {
            "format": "int64",
            "type": "integer"
          },
          "username": {
            "type": "string"
          }
        },
        "required": [
          "user_id",
          "username",
          "email",
          "display_name",
          "role",
          "status",
          "permissions",
          "created_at",
          "updated_at"
        ],
        "type": "object"
      },
      "GrantResult": {
        "additionalProperties": false,
        "properties": {
          "account_created": {
            "description": "No account had this e-mail address: a sub-user account was created",
            "type": "boolean"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "display_name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "one_time_password": {
            "description": "The new account's password (shown once; it must be changed at the first sign-in)",
            "type": "string"
          },
          "permissions": {
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "role": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          },
          "user_id": {
            "format": "int64",
            "type": "integer"
          },
          "username": {
            "type": "string"
          }
        },
        "required": [
          "account_created",
          "user_id",
          "username",
          "email",
          "display_name",
          "role",
          "status",
          "permissions",
          "created_at",
          "updated_at"
        ],
        "type": "object"
      },
      "GrantsOutBody": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/Grant"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "InstallProgress": {
        "additionalProperties": false,
        "properties": {
          "bytes_done": {
            "format": "int64",
            "type": "integer"
          },
          "bytes_total": {
            "format": "int64",
            "type": "integer"
          },
          "kind": {
            "enum": [
              "install",
              "reinstall",
              "update"
            ],
            "type": "string"
          },
          "percent": {
            "description": "0..100 of the current step; -1 = unknown",
            "format": "double",
            "type": "number"
          },
          "phase": {
            "type": "string"
          },
          "step": {
            "format": "int32",
            "type": "integer"
          },
          "step_name": {
            "type": "string"
          },
          "steps": {
            "format": "int32",
            "type": "integer"
          },
          "waiting_for": {
            "description": "steam_guard: type the code into the console",
            "type": "string"
          }
        },
        "required": [
          "kind",
          "step",
          "steps",
          "step_name",
          "percent",
          "phase",
          "bytes_done",
          "bytes_total"
        ],
        "type": "object"
      },
      "Inventory": {
        "additionalProperties": false,
        "properties": {
          "agent_version": {
            "maxLength": 64,
            "type": "string"
          },
          "arch": {
            "maxLength": 16,
            "type": "string"
          },
          "capabilities": {
            "items": {
              "type": "string"
            },
            "maxItems": 32,
            "type": [
              "array",
              "null"
            ]
          },
          "cpu_cores": {
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "disks": {
            "items": {
              "$ref": "#/components/schemas/Disk"
            },
            "maxItems": 64,
            "type": [
              "array",
              "null"
            ]
          },
          "hostname": {
            "maxLength": 255,
            "type": "string"
          },
          "ip_addresses": {
            "items": {
              "type": "string"
            },
            "maxItems": 64,
            "type": [
              "array",
              "null"
            ]
          },
          "memory_bytes": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "os": {
            "enum": [
              "windows",
              "linux"
            ],
            "type": "string"
          },
          "os_version": {
            "maxLength": 200,
            "type": "string"
          }
        },
        "required": [
          "hostname",
          "os",
          "arch",
          "os_version",
          "agent_version",
          "cpu_cores",
          "memory_bytes",
          "disks",
          "ip_addresses",
          "capabilities"
        ],
        "type": "object"
      },
      "ItemsCatalogModBody": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/CatalogMod"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "ItemsDeliveryBody": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/Delivery"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "ItemsScheduleRunViewBody": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/ScheduleRunView"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "ItemsStringBody": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "ItemsTargetViewBody": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/TargetView"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "ItemsTaskViewBody": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/TaskView"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "ItemsTemplateViewBody": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/TemplateView"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "ItemsTimeBody": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "format": "date-time",
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "ItemsWebhookViewBody": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/WebhookView"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "ItemsWorkshopItemBody": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/WorkshopItem"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "List-agent-releasesResponse": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/AgentRelease"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "List-configsResponse": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/ConfigFileView"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "List-datacentersResponse": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/Datacenter"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "List-enrollment-tokensResponse": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/EnrollmentToken"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "List-filesResponse": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/FileEntry"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "path": {
            "type": "string"
          }
        },
        "required": [
          "path",
          "items"
        ],
        "type": "object"
      },
      "List-game-definitionsResponse": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/GameAdmin"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "List-gamesResponse": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/Game"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "List-nodesResponse": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/Node"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "List-servicesResponse": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/View"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "List-ssh-keysResponse": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/SSHKeyOut"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "List-steam-accountsResponse": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/SteamAccount"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "LoginBody": {
        "additionalProperties": false,
        "properties": {
          "csrf_token": {
            "description": "Send as X-CSRF-Token on every state-changing request",
            "type": "string"
          },
          "mfa_token": {
            "description": "Send with the code to POST /auth/login/mfa (valid 5 minutes)",
            "type": "string"
          },
          "status": {
            "enum": [
              "ok",
              "mfa_required"
            ],
            "type": "string"
          },
          "user": {
            "$ref": "#/components/schemas/User"
          }
        },
        "required": [
          "status"
        ],
        "type": "object"
      },
      "LoginInputBody": {
        "additionalProperties": false,
        "properties": {
          "login": {
            "description": "Username or email address",
            "maxLength": 254,
            "minLength": 1,
            "type": "string"
          },
          "password": {
            "maxLength": 1024,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "login",
          "password"
        ],
        "type": "object"
      },
      "LogoutAllOutputBody": {
        "additionalProperties": false,
        "properties": {
          "sessions_ended": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "sessions_ended"
        ],
        "type": "object"
      },
      "MFAInputBody": {
        "additionalProperties": false,
        "properties": {
          "code": {
            "description": "6-digit code from the authenticator app",
            "maxLength": 10,
            "type": "string"
          },
          "mfa_token": {
            "maxLength": 200,
            "minLength": 1,
            "type": "string"
          },
          "recovery_code": {
            "description": "One of the recovery codes, instead of a code",
            "maxLength": 32,
            "type": "string"
          }
        },
        "required": [
          "mfa_token"
        ],
        "type": "object"
      },
      "MeBody": {
        "additionalProperties": false,
        "properties": {
          "auth_method": {
            "enum": [
              "session",
              "api_key"
            ],
            "type": "string"
          },
          "branding": {
            "$ref": "#/components/schemas/MeBranding",
            "description": "What this account sees: the panel's branding, overridden by its reseller's"
          },
          "client_ip": {
            "description": "The address this request came from, as the controller sees it",
            "type": "string"
          },
          "csrf_token": {
            "type": "string"
          },
          "mfa_enrollment_required": {
            "description": "Policy requires turning on 2FA before anything else",
            "type": "boolean"
          },
          "password_min_length": {
            "description": "Current password policy, for form hints",
            "format": "int64",
            "type": "integer"
          },
          "permissions": {
            "description": "Effective global permissions",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "recovery_codes_left": {
            "format": "int64",
            "type": "integer"
          },
          "user": {
            "$ref": "#/components/schemas/User"
          }
        },
        "required": [
          "user",
          "permissions",
          "auth_method",
          "mfa_enrollment_required",
          "recovery_codes_left",
          "password_min_length",
          "client_ip",
          "branding"
        ],
        "type": "object"
      },
      "MeBranding": {
        "additionalProperties": false,
        "properties": {
          "accent_color": {
            "description": "#rrggbb, or empty for the panel's own accent",
            "type": "string"
          },
          "product_name": {
            "type": "string"
          },
          "support_url": {
            "type": "string"
          }
        },
        "required": [
          "product_name",
          "support_url",
          "accent_color"
        ],
        "type": "object"
      },
      "MetricSample": {
        "additionalProperties": false,
        "properties": {
          "cpu_percent": {
            "format": "float",
            "type": [
              "number",
              "null"
            ]
          },
          "disk_bytes": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "mem_bytes": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "net_in_bytes": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "net_out_bytes": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "ts": {
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "ts",
          "cpu_percent",
          "mem_bytes",
          "disk_bytes",
          "net_in_bytes",
          "net_out_bytes"
        ],
        "type": "object"
      },
      "ModList": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/WorkshopItem"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "label": {
            "type": "string"
          },
          "variable": {
            "type": "string"
          }
        },
        "required": [
          "variable",
          "label",
          "items"
        ],
        "type": "object"
      },
      "NewTokenOutBody": {
        "additionalProperties": false,
        "properties": {
          "ca_hash": {
            "type": "string"
          },
          "commands": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Ready-to-paste commands: windows, linux (enroll an agent installed from its package); linux_install, windows_install (one-line installers, present when the panel serves the agent packages)",
            "type": "object"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "datacenter_id": {
            "format": "int64",
            "type": "integer"
          },
          "expires_at": {
            "format": "date-time",
            "type": "string"
          },
          "hint": {
            "type": "string"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "node_name": {
            "type": "string"
          },
          "token": {
            "description": "Shown once",
            "type": "string"
          }
        },
        "required": [
          "token",
          "ca_hash",
          "commands",
          "id",
          "hint",
          "datacenter_id",
          "node_name",
          "expires_at",
          "created_at"
        ],
        "type": "object"
      },
      "Node": {
        "additionalProperties": false,
        "properties": {
          "agent_version": {
            "type": "string"
          },
          "arch": {
            "type": "string"
          },
          "capabilities": {
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "cert_not_after": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "connected": {
            "description": "The agent link is up right now",
            "type": "boolean"
          },
          "connected_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "cpu_cores": {
            "format": "int32",
            "type": "integer"
          },
          "cpu_percent": {
            "format": "float",
            "type": [
              "number",
              "null"
            ]
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "datacenter_id": {
            "format": "int64",
            "type": "integer"
          },
          "disk_bytes": {
            "format": "int64",
            "type": "integer"
          },
          "disks": {
            "items": {
              "$ref": "#/components/schemas/DiskUsage"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "firewall_managed": {
            "type": "boolean"
          },
          "hostname": {
            "type": "string"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "ip_addresses": {
            "description": "Only on GET /nodes/{id}",
            "items": {
              "$ref": "#/components/schemas/NodeIP"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "last_seen_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "memory_bytes": {
            "format": "int64",
            "type": "integer"
          },
          "memory_used_bytes": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "metrics_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "mode": {
            "description": "Operator mode; draining/disabled persist across disconnects (see connected for the link)",
            "enum": [
              "active",
              "draining",
              "disabled"
            ],
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "net_rx_bytes": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "net_tx_bytes": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "os": {
            "enum": [
              "windows",
              "linux"
            ],
            "type": "string"
          },
          "os_version": {
            "type": "string"
          },
          "overcommit_percent": {
            "format": "int32",
            "type": "integer"
          },
          "port_range_end": {
            "format": "int32",
            "type": "integer"
          },
          "port_range_start": {
            "format": "int32",
            "type": "integer"
          },
          "services_dir": {
            "type": "string"
          },
          "status": {
            "enum": [
              "pending",
              "online",
              "offline",
              "draining",
              "disabled"
            ],
            "type": "string"
          },
          "steamcmd_dir": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "datacenter_id",
          "hostname",
          "os",
          "arch",
          "os_version",
          "agent_version",
          "status",
          "mode",
          "connected",
          "connected_at",
          "last_seen_at",
          "capabilities",
          "cpu_cores",
          "memory_bytes",
          "disk_bytes",
          "cpu_percent",
          "memory_used_bytes",
          "disks",
          "net_rx_bytes",
          "net_tx_bytes",
          "metrics_at",
          "cert_not_after",
          "overcommit_percent",
          "services_dir",
          "steamcmd_dir",
          "port_range_start",
          "port_range_end",
          "firewall_managed",
          "created_at"
        ],
        "type": "object"
      },
      "NodeIP": {
        "additionalProperties": false,
        "properties": {
          "ip": {
            "type": "string"
          },
          "is_primary": {
            "type": "boolean"
          },
          "label": {
            "type": "string"
          }
        },
        "required": [
          "ip",
          "label",
          "is_primary"
        ],
        "type": "object"
      },
      "Package": {
        "additionalProperties": false,
        "properties": {
          "allowed_datacenter_ids": {
            "description": "Empty = any datacenter",
            "items": {
              "format": "int64",
              "type": "integer"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "cpu_limit_percent": {
            "description": "0 = unlimited; 100 = one core",
            "format": "int32",
            "type": "integer"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "disk_limit_bytes": {
            "description": "File manager / SFTP / upload quota; 0 = unlimited",
            "format": "int64",
            "type": "integer"
          },
          "enabled": {
            "description": "Disabled packages cannot be ordered; existing game servers keep running",
            "type": "boolean"
          },
          "game_id": {
            "type": "string"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "memory_limit_bytes": {
            "description": "0 = unlimited",
            "format": "int64",
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "reseller_id": {
            "description": "0 = a global package (every reseller may sell it)",
            "format": "int64",
            "type": "integer"
          },
          "service_count": {
            "format": "int64",
            "type": "integer"
          },
          "slots_default": {
            "format": "int32",
            "type": "integer"
          },
          "slots_max": {
            "format": "int32",
            "type": "integer"
          },
          "slots_min": {
            "format": "int32",
            "type": "integer"
          },
          "start_on_create": {
            "description": "Start new game servers after the install",
            "type": "boolean"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          },
          "variables": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Startup variable defaults for new game servers",
            "type": "object"
          }
        },
        "required": [
          "id",
          "reseller_id",
          "name",
          "description",
          "game_id",
          "slots_min",
          "slots_max",
          "slots_default",
          "cpu_limit_percent",
          "memory_limit_bytes",
          "disk_limit_bytes",
          "allowed_datacenter_ids",
          "variables",
          "start_on_create",
          "enabled",
          "service_count",
          "created_at",
          "updated_at"
        ],
        "type": "object"
      },
      "PackageBody": {
        "additionalProperties": false,
        "properties": {
          "allowed_datacenter_ids": {
            "description": "Empty = any datacenter",
            "items": {
              "format": "int64",
              "type": "integer"
            },
            "maxItems": 100,
            "type": [
              "array",
              "null"
            ]
          },
          "cpu_limit_percent": {
            "description": "0 = unlimited; 100 = one core",
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "description": {
            "maxLength": 500,
            "type": "string"
          },
          "disk_limit_bytes": {
            "description": "0 = unlimited",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "enabled": {
            "type": "boolean"
          },
          "game_id": {
            "description": "Required on create; the game cannot change later",
            "maxLength": 64,
            "type": "string"
          },
          "memory_limit_bytes": {
            "description": "0 = unlimited",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "name": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "reseller_id": {
            "description": "Administrators: the reseller that owns it (0 = global); ignored for resellers and on update",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "slots_default": {
            "description": "0 = the game's default, inside the range",
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "slots_max": {
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "slots_min": {
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "start_on_create": {
            "type": "boolean"
          },
          "variables": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Startup variable defaults (no passwords)",
            "type": "object"
          }
        },
        "required": [
          "name",
          "slots_min",
          "slots_max",
          "enabled"
        ],
        "type": "object"
      },
      "PackagesOutBody": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/Package"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "PageAuditEvent": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/AuditEvent"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "next_cursor": {
            "description": "Pass as ?cursor= to get the next page; empty when there are no more",
            "type": "string"
          }
        },
        "required": [
          "items",
          "next_cursor"
        ],
        "type": "object"
      },
      "PageUser": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/User"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "next_cursor": {
            "description": "Pass as ?cursor= to get the next page; empty when there are no more",
            "type": "string"
          }
        },
        "required": [
          "items",
          "next_cursor"
        ],
        "type": "object"
      },
      "PasswordInputBody": {
        "additionalProperties": false,
        "properties": {
          "current_password": {
            "maxLength": 1024,
            "minLength": 1,
            "type": "string"
          },
          "new_password": {
            "maxLength": 1024,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "current_password",
          "new_password"
        ],
        "type": "object"
      },
      "PortView": {
        "additionalProperties": false,
        "properties": {
          "port": {
            "format": "int32",
            "type": "integer"
          },
          "proto": {
            "enum": [
              "tcp",
              "udp"
            ],
            "type": "string"
          },
          "role": {
            "type": "string"
          }
        },
        "required": [
          "role",
          "port",
          "proto"
        ],
        "type": "object"
      },
      "ProcessView": {
        "additionalProperties": false,
        "properties": {
          "index": {
            "format": "int32",
            "type": "integer"
          },
          "pid": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "role": {
            "type": "string"
          },
          "started_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "role",
          "index",
          "pid",
          "started_at"
        ],
        "type": "object"
      },
      "RconReply": {
        "additionalProperties": false,
        "properties": {
          "at": {
            "format": "date-time",
            "type": "string"
          },
          "output": {
            "type": "string"
          }
        },
        "required": [
          "output",
          "at"
        ],
        "type": "object"
      },
      "ReauthInputBody": {
        "additionalProperties": false,
        "properties": {
          "password": {
            "maxLength": 1024,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "password"
        ],
        "type": "object"
      },
      "RecoveryCodesOutputBody": {
        "additionalProperties": false,
        "properties": {
          "recovery_codes": {
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "recovery_codes"
        ],
        "type": "object"
      },
      "Request": {
        "additionalProperties": false,
        "properties": {
          "csr_pem": {
            "description": "PEM certificate request for the agent's new key",
            "maxLength": 8192,
            "minLength": 1,
            "type": "string"
          },
          "inventory": {
            "$ref": "#/components/schemas/Inventory"
          },
          "token": {
            "description": "One-time enrollment token (ngcpe_...)",
            "maxLength": 200,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "token",
          "csr_pem",
          "inventory"
        ],
        "type": "object"
      },
      "Reseller": {
        "additionalProperties": false,
        "properties": {
          "accounts": {
            "description": "Accounts of this reseller, including its own reseller accounts",
            "format": "int64",
            "type": "integer"
          },
          "allowed_game_ids": {
            "description": "Games the reseller may sell; empty = all",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "allowed_node_ids": {
            "description": "Nodes its customers' game servers may be placed on; empty = all",
            "items": {
              "format": "int64",
              "type": "integer"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "branding": {
            "$ref": "#/components/schemas/ResellerBranding"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "quotas": {
            "$ref": "#/components/schemas/ResellerQuotas"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          },
          "usage": {
            "$ref": "#/components/schemas/ResellerUsage"
          }
        },
        "required": [
          "id",
          "name",
          "branding",
          "quotas",
          "allowed_game_ids",
          "allowed_node_ids",
          "usage",
          "accounts",
          "created_at",
          "updated_at"
        ],
        "type": "object"
      },
      "ResellerBody": {
        "additionalProperties": false,
        "properties": {
          "allowed_game_ids": {
            "description": "Empty = every game",
            "items": {
              "type": "string"
            },
            "maxItems": 500,
            "type": [
              "array",
              "null"
            ]
          },
          "allowed_node_ids": {
            "description": "Empty = every node",
            "items": {
              "format": "int64",
              "type": "integer"
            },
            "maxItems": 500,
            "type": [
              "array",
              "null"
            ]
          },
          "branding": {
            "$ref": "#/components/schemas/ResellerBranding"
          },
          "name": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "quotas": {
            "$ref": "#/components/schemas/ResellerQuotas"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "ResellerBranding": {
        "additionalProperties": false,
        "properties": {
          "accent_color": {
            "description": "#rrggbb; empty = the panel's accent",
            "maxLength": 7,
            "type": "string"
          },
          "product_name": {
            "description": "Shown in the title bar instead of the panel's name",
            "maxLength": 40,
            "type": "string"
          },
          "support_url": {
            "description": "Help link for the reseller's customers",
            "maxLength": 300,
            "type": "string"
          }
        },
        "type": "object"
      },
      "ResellerQuotas": {
        "additionalProperties": false,
        "properties": {
          "disk_bytes": {
            "description": "Sum of the game servers' disk quotas; 0 = unlimited",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "memory_bytes": {
            "description": "Sum of the game servers' memory limits; 0 = unlimited",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "services": {
            "description": "Game servers; 0 = unlimited",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "slots": {
            "description": "Player slots over all game servers; 0 = unlimited",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "users": {
            "description": "Customer accounts (users and sub-users); 0 = unlimited",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "type": "object"
      },
      "ResellerUsage": {
        "additionalProperties": false,
        "properties": {
          "disk_bytes": {
            "format": "int64",
            "type": "integer"
          },
          "memory_bytes": {
            "format": "int64",
            "type": "integer"
          },
          "services": {
            "format": "int64",
            "type": "integer"
          },
          "slots": {
            "format": "int64",
            "type": "integer"
          },
          "users": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "users",
          "services",
          "slots",
          "memory_bytes",
          "disk_bytes"
        ],
        "type": "object"
      },
      "ResellersOutBody": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/Reseller"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "ResetPasswordInputBody": {
        "additionalProperties": false,
        "properties": {
          "must_change_password": {
            "description": "Force a change at next sign-in",
            "type": "boolean"
          },
          "password": {
            "maxLength": 1024,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "password"
        ],
        "type": "object"
      },
      "Response": {
        "additionalProperties": false,
        "properties": {
          "ca_pem": {
            "description": "Verify its SubjectPublicKeyInfo hash against the --ca-hash from the token",
            "type": "string"
          },
          "certificate_pem": {
            "type": "string"
          },
          "grpc_address": {
            "description": "host:port of the AgentLink endpoint",
            "type": "string"
          },
          "node_id": {
            "format": "int64",
            "type": "integer"
          },
          "node_name": {
            "type": "string"
          },
          "update_public_key": {
            "description": "Ed25519 key (hex) that signs agent updates",
            "type": "string"
          }
        },
        "required": [
          "node_id",
          "node_name",
          "certificate_pem",
          "ca_pem",
          "grpc_address",
          "update_public_key"
        ],
        "type": "object"
      },
      "Result": {
        "additionalProperties": false,
        "properties": {
          "existing_admins": {
            "description": "The database already had accounts; no new administrator was created",
            "type": "boolean"
          },
          "local_node": {
            "description": "Name of the game node this server joins as (the local agent enrolls within seconds)",
            "type": "string"
          },
          "login_url": {
            "type": "string"
          }
        },
        "required": [
          "login_url",
          "existing_admins"
        ],
        "type": "object"
      },
      "RoleInfo": {
        "additionalProperties": false,
        "properties": {
          "permissions": {
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "role": {
            "type": "string"
          }
        },
        "required": [
          "role",
          "permissions"
        ],
        "type": "object"
      },
      "SFTPInfo": {
        "additionalProperties": false,
        "properties": {
          "host": {
            "type": "string"
          },
          "host_key_fingerprint": {
            "description": "Compare with what the client shows on first connect",
            "type": "string"
          },
          "port": {
            "format": "int32",
            "type": "integer"
          },
          "username": {
            "description": "\u003cpanel username\u003e.\u003cservice id\u003e",
            "type": "string"
          }
        },
        "required": [
          "host",
          "port",
          "username",
          "host_key_fingerprint"
        ],
        "type": "object"
      },
      "SMTPView": {
        "additionalProperties": false,
        "properties": {
          "from": {
            "type": "string"
          },
          "has_password": {
            "type": "boolean"
          },
          "host": {
            "type": "string"
          },
          "port": {
            "format": "int64",
            "type": "integer"
          },
          "security": {
            "enum": [
              "starttls",
              "tls",
              "none",
              ""
            ],
            "type": "string"
          },
          "username": {
            "type": "string"
          }
        },
        "required": [
          "host",
          "port",
          "security",
          "username",
          "from",
          "has_password"
        ],
        "type": "object"
      },
      "SSHKeyOut": {
        "additionalProperties": false,
        "properties": {
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "fingerprint": {
            "type": "string"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "last_used_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "public_key": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "fingerprint",
          "public_key",
          "created_at",
          "last_used_at"
        ],
        "type": "object"
      },
      "ScheduleRunView": {
        "additionalProperties": false,
        "properties": {
          "action": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "ok": {
            "type": "boolean"
          },
          "ran_at": {
            "format": "date-time",
            "type": "string"
          },
          "skipped": {
            "type": "boolean"
          },
          "task_id": {
            "format": "int64",
            "type": "integer"
          },
          "task_name": {
            "type": "string"
          }
        },
        "required": [
          "task_name",
          "action",
          "ran_at",
          "ok",
          "skipped",
          "message"
        ],
        "type": "object"
      },
      "Search-filesResponse": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/FileEntry"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "truncated": {
            "description": "More than 500 matches",
            "type": "boolean"
          }
        },
        "required": [
          "items",
          "truncated"
        ],
        "type": "object"
      },
      "Security": {
        "additionalProperties": false,
        "properties": {
          "admin_ip_allowlist": {
            "description": "CIDRs SuperAdmins and Admins may sign in from; empty allows any",
            "items": {
              "type": "string"
            },
            "maxItems": 100,
            "type": [
              "array",
              "null"
            ]
          },
          "password_min_length": {
            "format": "int64",
            "maximum": 128,
            "minimum": 8,
            "type": "integer"
          },
          "require_2fa_for_admins": {
            "description": "SuperAdmins and Admins must enroll TOTP before using the panel",
            "type": "boolean"
          },
          "session_idle_hours": {
            "description": "A session ends after this long without use",
            "format": "int64",
            "maximum": 720,
            "minimum": 1,
            "type": "integer"
          },
          "session_max_days": {
            "description": "A session ends this long after sign-in regardless of use",
            "format": "int64",
            "maximum": 90,
            "minimum": 1,
            "type": "integer"
          },
          "sftp_password_with_2fa": {
            "description": "Accounts with two-factor authentication may use their password for SFTP (skips the second factor)",
            "type": "boolean"
          }
        },
        "required": [
          "password_min_length",
          "require_2fa_for_admins",
          "session_idle_hours",
          "session_max_days",
          "admin_ip_allowlist",
          "sftp_password_with_2fa"
        ],
        "type": "object"
      },
      "Send-console-inputRequest": {
        "additionalProperties": false,
        "properties": {
          "line": {
            "maxLength": 1024,
            "type": "string"
          }
        },
        "required": [
          "line"
        ],
        "type": "object"
      },
      "Service-actionRequest": {
        "additionalProperties": false,
        "properties": {
          "reason": {
            "description": "suspend: why (e.g. Overdue on Payment); shown to the customer",
            "maxLength": 200,
            "type": "string"
          }
        },
        "type": "object"
      },
      "Service-rconRequest": {
        "additionalProperties": false,
        "properties": {
          "command": {
            "maxLength": 512,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "command"
        ],
        "type": "object"
      },
      "ServiceDiskUsage": {
        "additionalProperties": false,
        "properties": {
          "quota_bytes": {
            "description": "0 = unlimited",
            "format": "int64",
            "type": "integer"
          },
          "used_bytes": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "used_bytes",
          "quota_bytes"
        ],
        "type": "object"
      },
      "ServiceMetricSample": {
        "additionalProperties": false,
        "properties": {
          "cpu_percent": {
            "format": "float",
            "type": [
              "number",
              "null"
            ]
          },
          "mem_bytes": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "players": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "ts": {
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "ts",
          "cpu_percent",
          "mem_bytes",
          "players"
        ],
        "type": "object"
      },
      "ServiceModsView": {
        "additionalProperties": false,
        "properties": {
          "catalog": {
            "items": {
              "$ref": "#/components/schemas/CatalogMod"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "installed": {
            "type": "boolean"
          },
          "lists": {
            "items": {
              "$ref": "#/components/schemas/ModList"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "workshop": {
            "description": "The game takes Steam Workshop mods",
            "type": "boolean"
          }
        },
        "required": [
          "lists",
          "catalog",
          "workshop",
          "installed"
        ],
        "type": "object"
      },
      "Session": {
        "additionalProperties": false,
        "properties": {
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "current": {
            "description": "True for the session making this request",
            "type": "boolean"
          },
          "expires_at": {
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "ip": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_seen_at": {
            "format": "date-time",
            "type": "string"
          },
          "user_agent": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "ip",
          "user_agent",
          "created_at",
          "last_seen_at",
          "expires_at",
          "current"
        ],
        "type": "object"
      },
      "SessionsOutputBody": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/Session"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "Set-game-definition-enabledRequest": {
        "additionalProperties": false,
        "properties": {
          "enabled": {
            "type": "boolean"
          }
        },
        "required": [
          "enabled"
        ],
        "type": "object"
      },
      "Set-service-modsRequest": {
        "additionalProperties": false,
        "properties": {
          "ids": {
            "description": "Workshop ids",
            "items": {
              "type": "string"
            },
            "maxItems": 200,
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "ids"
        ],
        "type": "object"
      },
      "Set-subuserRequest": {
        "additionalProperties": false,
        "properties": {
          "email": {
            "maxLength": 254,
            "minLength": 3,
            "type": "string"
          },
          "permissions": {
            "description": "view, control, console, files, config, mods, schedule, backups, settings, subusers, reinstall",
            "items": {
              "type": "string"
            },
            "maxItems": 20,
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "email",
          "permissions"
        ],
        "type": "object"
      },
      "SetModsOutBody": {
        "additionalProperties": false,
        "properties": {
          "cpu_limit_percent": {
            "description": "0 = unlimited; 100 = one core",
            "format": "int32",
            "type": "integer"
          },
          "cpu_percent": {
            "format": "float",
            "type": [
              "number",
              "null"
            ]
          },
          "crash_policy": {
            "$ref": "#/components/schemas/CrashPolicy"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "desired_state": {
            "enum": [
              "running",
              "stopped"
            ],
            "type": "string"
          },
          "disk_limit_bytes": {
            "description": "File manager / SFTP / upload quota; 0 = unlimited",
            "format": "int64",
            "type": "integer"
          },
          "external_id": {
            "description": "The billing system's reference",
            "type": [
              "string",
              "null"
            ]
          },
          "file_deny": {
            "description": "Deny globs added for this service (on top of the game definition's): matching paths are hidden from everyone except administrators",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "game_id": {
            "type": "string"
          },
          "has_rcon": {
            "description": "The game has a remote console (only on GET /services/{id})",
            "type": "boolean"
          },
          "has_workshop": {
            "description": "The game takes Steam Workshop mods (only on GET /services/{id})",
            "type": "boolean"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "install": {
            "$ref": "#/components/schemas/InstallProgress",
            "description": "While installing / updating"
          },
          "install_dir": {
            "type": "string"
          },
          "installed": {
            "description": "The game files are in place",
            "type": "boolean"
          },
          "ip": {
            "type": "string"
          },
          "last_error": {
            "description": "The last command the agent refused, and why",
            "type": "string"
          },
          "last_exit_code": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "max_players": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "memory_limit_bytes": {
            "description": "0 = unlimited",
            "format": "int64",
            "type": "integer"
          },
          "memory_used_bytes": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "metrics_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "mods": {
            "additionalProperties": {
              "items": {
                "$ref": "#/components/schemas/WorkshopItem"
              },
              "type": [
                "array",
                "null"
              ]
            },
            "description": "Workshop items per modlist variable",
            "type": "object"
          },
          "mods_changed": {
            "description": "Run the update action to download the new mods",
            "type": "boolean"
          },
          "name": {
            "type": "string"
          },
          "node_connected": {
            "description": "The node's agent link is up",
            "type": "boolean"
          },
          "node_id": {
            "format": "int64",
            "type": "integer"
          },
          "node_name": {
            "type": "string"
          },
          "node_os": {
            "enum": [
              "windows",
              "linux"
            ],
            "type": "string"
          },
          "observed_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "observed_message": {
            "type": "string"
          },
          "observed_status": {
            "description": "What the agent last reported",
            "type": "string"
          },
          "os_user": {
            "type": "string"
          },
          "owner_user_id": {
            "format": "int64",
            "type": "integer"
          },
          "owner_username": {
            "type": "string"
          },
          "package_id": {
            "description": "The package it was ordered with (null = none)",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "permissions": {
            "description": "What the caller may do on this service (absent on WebSocket events)",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "players": {
            "description": "From the game's status query while it runs (null = unknown)",
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "ports": {
            "description": "Only on GET /services/{id}",
            "items": {
              "$ref": "#/components/schemas/PortView"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "primary_port": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "process_count": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "processes": {
            "description": "Only on GET /services/{id}",
            "items": {
              "$ref": "#/components/schemas/ProcessView"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "query_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "query_map": {
            "type": "string"
          },
          "query_name": {
            "description": "Server name the game reports",
            "type": "string"
          },
          "restarts": {
            "description": "Crash restarts within the crash-policy window",
            "format": "int32",
            "type": "integer"
          },
          "secret_variables": {
            "description": "Password variables that have a value (values are never returned)",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "sftp": {
            "$ref": "#/components/schemas/SFTPInfo",
            "description": "How the caller connects with SFTP (only on GET /services/{id}, with the files permission)"
          },
          "slots": {
            "format": "int32",
            "type": "integer"
          },
          "status": {
            "enum": [
              "installing",
              "install_failed",
              "stopped",
              "starting",
              "running",
              "stopping",
              "crashed",
              "suspended",
              "moving",
              "deleting"
            ],
            "type": "string"
          },
          "steam_account_id": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "suspend_reason": {
            "description": "Why it was suspended (billing or an administrator)",
            "type": "string"
          },
          "suspended": {
            "type": "boolean"
          },
          "variables": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object"
          }
        },
        "required": [
          "mods_changed",
          "id",
          "name",
          "game_id",
          "node_id",
          "node_name",
          "node_os",
          "node_connected",
          "owner_user_id",
          "owner_username",
          "status",
          "desired_state",
          "observed_status",
          "observed_message",
          "observed_at",
          "last_error",
          "restarts",
          "last_exit_code",
          "install_dir",
          "os_user",
          "ip",
          "primary_port",
          "slots",
          "variables",
          "cpu_limit_percent",
          "memory_limit_bytes",
          "disk_limit_bytes",
          "file_deny",
          "crash_policy",
          "cpu_percent",
          "memory_used_bytes",
          "process_count",
          "metrics_at",
          "players",
          "max_players",
          "query_name",
          "query_map",
          "query_at",
          "suspended",
          "suspend_reason",
          "package_id",
          "external_id",
          "installed",
          "secret_variables",
          "mods",
          "steam_account_id",
          "created_at"
        ],
        "type": "object"
      },
      "Settings": {
        "additionalProperties": false,
        "properties": {
          "branding": {
            "$ref": "#/components/schemas/Branding"
          },
          "security": {
            "$ref": "#/components/schemas/Security"
          }
        },
        "required": [
          "branding",
          "security"
        ],
        "type": "object"
      },
      "SetupCompleteInBody": {
        "additionalProperties": false,
        "properties": {
          "admin_email": {
            "maxLength": 254,
            "minLength": 3,
            "type": "string"
          },
          "admin_password": {
            "maxLength": 1024,
            "minLength": 1,
            "type": "string"
          },
          "admin_username": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "database_mode": {
            "enum": [
              "builtin",
              "external"
            ],
            "type": "string"
          },
          "database_url": {
            "maxLength": 2000,
            "type": "string"
          },
          "grpc_advertise": {
            "description": "host:port agents dial (default: the public URL's host, port 8443)",
            "maxLength": 255,
            "type": "string"
          },
          "local_node": {
            "description": "Also run game servers on this server: the NGCP agent installed here joins the panel by itself",
            "type": "boolean"
          },
          "local_node_name": {
            "description": "The game node's name (default: this computer's name)",
            "maxLength": 64,
            "type": "string"
          },
          "public_url": {
            "description": "How browsers and agents reach the panel",
            "maxLength": 255,
            "minLength": 8,
            "type": "string"
          },
          "tls_cert_file": {
            "maxLength": 1024,
            "type": "string"
          },
          "tls_key_file": {
            "maxLength": 1024,
            "type": "string"
          },
          "tls_mode": {
            "description": "none: plain HTTP, or TLS ends at a reverse proxy",
            "enum": [
              "none",
              "files",
              "self-signed"
            ],
            "type": "string"
          },
          "token": {
            "maxLength": 100,
            "type": "string"
          }
        },
        "required": [
          "database_mode",
          "admin_username",
          "admin_email",
          "admin_password",
          "public_url",
          "tls_mode"
        ],
        "type": "object"
      },
      "SetupDBInBody": {
        "additionalProperties": false,
        "properties": {
          "token": {
            "maxLength": 100,
            "type": "string"
          },
          "url": {
            "description": "postgres://user:password@host:5432/dbname?sslmode=...",
            "maxLength": 2000,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "url"
        ],
        "type": "object"
      },
      "SetupStatus": {
        "additionalProperties": false,
        "properties": {
          "active": {
            "description": "The controller waits for its first-run setup",
            "type": "boolean"
          },
          "allowed": {
            "description": "This request may run the setup (a right token, or a local request)",
            "type": "boolean"
          },
          "builtin_database": {
            "$ref": "#/components/schemas/BuiltinDB"
          },
          "local_agent": {
            "description": "The NGCP agent is installed on this server (the setup can make it a game node)",
            "type": "boolean"
          },
          "os": {
            "type": "string"
          },
          "suggested_public_url": {
            "description": "The address this page was opened with",
            "type": "string"
          },
          "version": {
            "type": "string"
          }
        },
        "required": [
          "active",
          "allowed"
        ],
        "type": "object"
      },
      "SetupToken": {
        "additionalProperties": false,
        "properties": {
          "token": {
            "description": "Not needed from the server itself (localhost)",
            "maxLength": 100,
            "type": "string"
          }
        },
        "type": "object"
      },
      "SsoOutBody": {
        "additionalProperties": false,
        "properties": {
          "expires_at": {
            "format": "date-time",
            "type": "string"
          },
          "url": {
            "description": "Open this in the customer's browser; it works once, for 60 seconds",
            "type": "string"
          }
        },
        "required": [
          "url",
          "expires_at"
        ],
        "type": "object"
      },
      "SteamAccount": {
        "additionalProperties": false,
        "properties": {
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "is_default": {
            "type": "boolean"
          },
          "label": {
            "type": "string"
          },
          "service_count": {
            "format": "int64",
            "type": "integer"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          },
          "username": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "label",
          "username",
          "is_default",
          "service_count",
          "created_at",
          "updated_at"
        ],
        "type": "object"
      },
      "SteamBody": {
        "additionalProperties": false,
        "properties": {
          "is_default": {
            "type": "boolean"
          },
          "label": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "password": {
            "description": "Write-only; leave empty to keep the stored one",
            "maxLength": 128,
            "type": "string"
          },
          "username": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "label",
          "username"
        ],
        "type": "object"
      },
      "SvcBackupsBody": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/BackupView"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "targets": {
            "description": "Where the caller may back this service up to",
            "items": {
              "$ref": "#/components/schemas/TargetChoice"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items",
          "targets"
        ],
        "type": "object"
      },
      "SvcTasksBody": {
        "additionalProperties": false,
        "properties": {
          "global": {
            "description": "Global tasks that also apply (administrators manage them)",
            "items": {
              "$ref": "#/components/schemas/TaskView"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "items": {
            "description": "The service's own tasks",
            "items": {
              "$ref": "#/components/schemas/TaskView"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "items",
          "global"
        ],
        "type": "object"
      },
      "TOTPDisableInputBody": {
        "additionalProperties": false,
        "properties": {
          "code": {
            "maxLength": 10,
            "minLength": 6,
            "type": "string"
          },
          "password": {
            "maxLength": 1024,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "password",
          "code"
        ],
        "type": "object"
      },
      "TOTPSetupOutputBody": {
        "additionalProperties": false,
        "properties": {
          "otpauth_uri": {
            "description": "Render as a QR code",
            "type": "string"
          },
          "secret": {
            "type": "string"
          }
        },
        "required": [
          "secret",
          "otpauth_uri"
        ],
        "type": "object"
      },
      "TargetBody": {
        "additionalProperties": false,
        "properties": {
          "config": {
            "$ref": "#/components/schemas/TargetConfig"
          },
          "keep_days": {
            "description": "Delete backups older than this (0 = never)",
            "format": "int32",
            "maximum": 3650,
            "minimum": 0,
            "type": "integer"
          },
          "keep_last": {
            "description": "Keep at most this many backups per service (0 = all)",
            "format": "int32",
            "maximum": 1000,
            "minimum": 0,
            "type": "integer"
          },
          "kind": {
            "description": "Fixed after creation",
            "enum": [
              "local",
              "sftp",
              "s3"
            ],
            "type": "string"
          },
          "name": {
            "maxLength": 80,
            "minLength": 1,
            "type": "string"
          },
          "password": {
            "description": "sftp",
            "type": "string"
          },
          "private_key": {
            "description": "sftp: unencrypted OpenSSH / PEM key",
            "type": "string"
          },
          "secret_key": {
            "description": "s3",
            "type": "string"
          },
          "user_selectable": {
            "description": "Service owners may back up here",
            "type": "boolean"
          }
        },
        "required": [
          "name",
          "config",
          "keep_last",
          "keep_days",
          "user_selectable"
        ],
        "type": "object"
      },
      "TargetChoice": {
        "additionalProperties": false,
        "properties": {
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "kind": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "kind"
        ],
        "type": "object"
      },
      "TargetConfig": {
        "additionalProperties": false,
        "properties": {
          "access_key": {
            "description": "s3",
            "type": "string"
          },
          "bucket": {
            "description": "s3",
            "type": "string"
          },
          "endpoint": {
            "description": "s3: host[:port], e.g. s3.eu-central-1.amazonaws.com or minio.lan:9000",
            "type": "string"
          },
          "host": {
            "description": "sftp",
            "type": "string"
          },
          "host_key_fingerprint": {
            "description": "sftp: SHA256:... (strongly recommended)",
            "type": "string"
          },
          "path": {
            "description": "local: absolute folder on the node",
            "type": "string"
          },
          "port": {
            "description": "sftp (22)",
            "format": "int32",
            "type": "integer"
          },
          "prefix": {
            "description": "Folder / key prefix inside the target (default ngcp)",
            "type": "string"
          },
          "region": {
            "description": "s3",
            "type": "string"
          },
          "remote_path": {
            "description": "sftp: folder on the server",
            "type": "string"
          },
          "use_tls": {
            "description": "s3: https",
            "type": "boolean"
          },
          "user": {
            "description": "sftp",
            "type": "string"
          }
        },
        "required": [
          "use_tls"
        ],
        "type": "object"
      },
      "TargetView": {
        "additionalProperties": false,
        "properties": {
          "config": {
            "$ref": "#/components/schemas/TargetConfig"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "has_password": {
            "type": "boolean"
          },
          "has_private_key": {
            "type": "boolean"
          },
          "has_secret_key": {
            "type": "boolean"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "keep_days": {
            "format": "int32",
            "type": "integer"
          },
          "keep_last": {
            "format": "int32",
            "type": "integer"
          },
          "kind": {
            "enum": [
              "local",
              "sftp",
              "s3"
            ],
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          },
          "user_selectable": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "name",
          "kind",
          "config",
          "has_password",
          "has_private_key",
          "has_secret_key",
          "keep_last",
          "keep_days",
          "user_selectable",
          "created_at",
          "updated_at"
        ],
        "type": "object"
      },
      "TaskBody": {
        "additionalProperties": false,
        "properties": {
          "action": {
            "enum": [
              "restart",
              "stop",
              "start",
              "update",
              "backup",
              "rcon",
              "script",
              "notify"
            ],
            "type": "string"
          },
          "cron": {
            "description": "5 fields (minute hour day month weekday) or @hourly, @daily, @weekly, @monthly",
            "maxLength": 100,
            "minLength": 1,
            "type": "string"
          },
          "enabled": {
            "type": "boolean"
          },
          "name": {
            "maxLength": 80,
            "minLength": 1,
            "type": "string"
          },
          "params": {
            "$ref": "#/components/schemas/TaskParams"
          },
          "selector": {
            "$ref": "#/components/schemas/TaskSelector",
            "description": "Global tasks: the services they apply to (empty = all)"
          },
          "timezone": {
            "description": "IANA name, e.g. Europe/Stockholm (default UTC)",
            "maxLength": 64,
            "type": "string"
          }
        },
        "required": [
          "name",
          "cron",
          "action",
          "enabled"
        ],
        "type": "object"
      },
      "TaskParams": {
        "additionalProperties": false,
        "properties": {
          "backup_target_id": {
            "description": "backup: the target",
            "format": "int64",
            "type": "integer"
          },
          "message": {
            "description": "notify: the text; restart / stop / update: the warning players see",
            "type": "string"
          },
          "only_when_empty": {
            "description": "restart / stop / update: skip while players are online",
            "type": "boolean"
          },
          "rcon_command": {
            "description": "rcon: the command",
            "type": "string"
          },
          "script": {
            "description": "script (administrators): bash on Linux, PowerShell on Windows; runs as the service account",
            "type": "string"
          },
          "warn_minutes": {
            "description": "Warn players over RCON this many minutes ahead",
            "format": "int32",
            "maximum": 60,
            "minimum": 0,
            "type": "integer"
          }
        },
        "type": "object"
      },
      "TaskResult": {
        "additionalProperties": false,
        "properties": {
          "message": {
            "type": "string"
          },
          "ok": {
            "type": "boolean"
          },
          "service_id": {
            "format": "int64",
            "type": "integer"
          },
          "skipped": {
            "type": "boolean"
          }
        },
        "required": [
          "service_id",
          "ok",
          "skipped",
          "message"
        ],
        "type": "object"
      },
      "TaskSelector": {
        "additionalProperties": false,
        "properties": {
          "game_id": {
            "type": "string"
          },
          "node_id": {
            "format": "int64",
            "type": "integer"
          }
        },
        "type": "object"
      },
      "TaskView": {
        "additionalProperties": false,
        "properties": {
          "action": {
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "cron": {
            "type": "string"
          },
          "enabled": {
            "type": "boolean"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "last_result": {
            "$ref": "#/components/schemas/TaskResult"
          },
          "last_run_at": {
            "format": "date-time",
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "next": {
            "description": "The next three runs",
            "items": {
              "format": "date-time",
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "params": {
            "$ref": "#/components/schemas/TaskParams"
          },
          "scope": {
            "enum": [
              "global",
              "service"
            ],
            "type": "string"
          },
          "selector": {
            "$ref": "#/components/schemas/TaskSelector"
          },
          "service_id": {
            "format": "int64",
            "type": "integer"
          },
          "timezone": {
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "scope",
          "name",
          "cron",
          "timezone",
          "action",
          "params",
          "enabled",
          "next",
          "created_at",
          "updated_at"
        ],
        "type": "object"
      },
      "TemplateView": {
        "additionalProperties": false,
        "properties": {
          "default": {
            "type": "string"
          },
          "event": {
            "type": "string"
          },
          "template": {
            "description": "The administrator's text; empty = the default",
            "type": "string"
          }
        },
        "required": [
          "event",
          "default",
          "template"
        ],
        "type": "object"
      },
      "Update-configRequest": {
        "additionalProperties": false,
        "properties": {
          "hash": {
            "maxLength": 64,
            "type": "string"
          },
          "values": {
            "additionalProperties": {},
            "type": "object"
          }
        },
        "required": [
          "values"
        ],
        "type": "object"
      },
      "Update-node-agentRequest": {
        "additionalProperties": false,
        "properties": {
          "version": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "version"
        ],
        "type": "object"
      },
      "Update-node-agentResponse": {
        "additionalProperties": false,
        "properties": {
          "request_id": {
            "type": "string"
          }
        },
        "required": [
          "request_id"
        ],
        "type": "object"
      },
      "Update-nodeRequest": {
        "additionalProperties": false,
        "properties": {
          "datacenter_id": {
            "format": "int64",
            "type": "integer"
          },
          "firewall_managed": {
            "type": "boolean"
          },
          "mode": {
            "enum": [
              "active",
              "draining",
              "disabled"
            ],
            "type": "string"
          },
          "name": {
            "maxLength": 64,
            "type": "string"
          },
          "overcommit_percent": {
            "format": "int32",
            "maximum": 1000,
            "minimum": 1,
            "type": "integer"
          },
          "port_range_end": {
            "format": "int32",
            "maximum": 65535,
            "minimum": 1024,
            "type": "integer"
          },
          "port_range_start": {
            "format": "int32",
            "maximum": 65535,
            "minimum": 1024,
            "type": "integer"
          },
          "services_dir": {
            "maxLength": 260,
            "type": "string"
          },
          "steamcmd_dir": {
            "maxLength": 260,
            "type": "string"
          }
        },
        "type": "object"
      },
      "Update-notification-templatesRequest": {
        "additionalProperties": false,
        "properties": {
          "templates": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object"
          }
        },
        "required": [
          "templates"
        ],
        "type": "object"
      },
      "Update-serviceRequest": {
        "additionalProperties": false,
        "properties": {
          "disk_limit_bytes": {
            "description": "Administrators: file manager / SFTP / upload quota; 0 = unlimited",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "file_deny": {
            "description": "Administrators: deny globs for this service's file manager and SFTP (on top of the game's)",
            "items": {
              "type": "string"
            },
            "maxItems": 100,
            "type": "array"
          },
          "name": {
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "slots": {
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "steam_account_id": {
            "description": "Administrators; 0 = the vault's default",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "variables": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object"
          }
        },
        "type": "object"
      },
      "Update-smtp-settingsRequest": {
        "additionalProperties": false,
        "properties": {
          "from": {
            "maxLength": 200,
            "type": "string"
          },
          "host": {
            "maxLength": 253,
            "type": "string"
          },
          "password": {
            "description": "Write-only; leave out to keep, \"\" to clear",
            "maxLength": 500,
            "type": "string"
          },
          "port": {
            "format": "int64",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          },
          "security": {
            "enum": [
              "starttls",
              "tls",
              "none"
            ],
            "type": "string"
          },
          "username": {
            "maxLength": 200,
            "type": "string"
          }
        },
        "required": [
          "host"
        ],
        "type": "object"
      },
      "UpdateMeInputBody": {
        "additionalProperties": false,
        "properties": {
          "current_password": {
            "description": "Required when changing the email address",
            "maxLength": 1024,
            "type": "string"
          },
          "display_name": {
            "maxLength": 100,
            "type": "string"
          },
          "email": {
            "maxLength": 254,
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateOutBody": {
        "additionalProperties": false,
        "properties": {
          "cpu_limit_percent": {
            "description": "0 = unlimited; 100 = one core",
            "format": "int32",
            "type": "integer"
          },
          "cpu_percent": {
            "format": "float",
            "type": [
              "number",
              "null"
            ]
          },
          "crash_policy": {
            "$ref": "#/components/schemas/CrashPolicy"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "desired_state": {
            "enum": [
              "running",
              "stopped"
            ],
            "type": "string"
          },
          "disk_limit_bytes": {
            "description": "File manager / SFTP / upload quota; 0 = unlimited",
            "format": "int64",
            "type": "integer"
          },
          "external_id": {
            "description": "The billing system's reference",
            "type": [
              "string",
              "null"
            ]
          },
          "file_deny": {
            "description": "Deny globs added for this service (on top of the game definition's): matching paths are hidden from everyone except administrators",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "game_id": {
            "type": "string"
          },
          "has_rcon": {
            "description": "The game has a remote console (only on GET /services/{id})",
            "type": "boolean"
          },
          "has_workshop": {
            "description": "The game takes Steam Workshop mods (only on GET /services/{id})",
            "type": "boolean"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "install": {
            "$ref": "#/components/schemas/InstallProgress",
            "description": "While installing / updating"
          },
          "install_dir": {
            "type": "string"
          },
          "installed": {
            "description": "The game files are in place",
            "type": "boolean"
          },
          "ip": {
            "type": "string"
          },
          "last_error": {
            "description": "The last command the agent refused, and why",
            "type": "string"
          },
          "last_exit_code": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "max_players": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "memory_limit_bytes": {
            "description": "0 = unlimited",
            "format": "int64",
            "type": "integer"
          },
          "memory_used_bytes": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "metrics_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "mods": {
            "additionalProperties": {
              "items": {
                "$ref": "#/components/schemas/WorkshopItem"
              },
              "type": [
                "array",
                "null"
              ]
            },
            "description": "Workshop items per modlist variable",
            "type": "object"
          },
          "mods_changed": {
            "description": "Run the update action to download the new mods",
            "type": "boolean"
          },
          "name": {
            "type": "string"
          },
          "node_connected": {
            "description": "The node's agent link is up",
            "type": "boolean"
          },
          "node_id": {
            "format": "int64",
            "type": "integer"
          },
          "node_name": {
            "type": "string"
          },
          "node_os": {
            "enum": [
              "windows",
              "linux"
            ],
            "type": "string"
          },
          "observed_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "observed_message": {
            "type": "string"
          },
          "observed_status": {
            "description": "What the agent last reported",
            "type": "string"
          },
          "os_user": {
            "type": "string"
          },
          "owner_user_id": {
            "format": "int64",
            "type": "integer"
          },
          "owner_username": {
            "type": "string"
          },
          "package_id": {
            "description": "The package it was ordered with (null = none)",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "permissions": {
            "description": "What the caller may do on this service (absent on WebSocket events)",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "players": {
            "description": "From the game's status query while it runs (null = unknown)",
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "ports": {
            "description": "Only on GET /services/{id}",
            "items": {
              "$ref": "#/components/schemas/PortView"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "primary_port": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "process_count": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "processes": {
            "description": "Only on GET /services/{id}",
            "items": {
              "$ref": "#/components/schemas/ProcessView"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "query_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "query_map": {
            "type": "string"
          },
          "query_name": {
            "description": "Server name the game reports",
            "type": "string"
          },
          "restarts": {
            "description": "Crash restarts within the crash-policy window",
            "format": "int32",
            "type": "integer"
          },
          "secret_variables": {
            "description": "Password variables that have a value (values are never returned)",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "sftp": {
            "$ref": "#/components/schemas/SFTPInfo",
            "description": "How the caller connects with SFTP (only on GET /services/{id}, with the files permission)"
          },
          "slots": {
            "format": "int32",
            "type": "integer"
          },
          "status": {
            "enum": [
              "installing",
              "install_failed",
              "stopped",
              "starting",
              "running",
              "stopping",
              "crashed",
              "suspended",
              "moving",
              "deleting"
            ],
            "type": "string"
          },
          "steam_account_id": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "suspend_reason": {
            "description": "Why it was suspended (billing or an administrator)",
            "type": "string"
          },
          "suspended": {
            "type": "boolean"
          },
          "variables": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object"
          }
        },
        "required": [
          "mods_changed",
          "id",
          "name",
          "game_id",
          "node_id",
          "node_name",
          "node_os",
          "node_connected",
          "owner_user_id",
          "owner_username",
          "status",
          "desired_state",
          "observed_status",
          "observed_message",
          "observed_at",
          "last_error",
          "restarts",
          "last_exit_code",
          "install_dir",
          "os_user",
          "ip",
          "primary_port",
          "slots",
          "variables",
          "cpu_limit_percent",
          "memory_limit_bytes",
          "disk_limit_bytes",
          "file_deny",
          "crash_policy",
          "cpu_percent",
          "memory_used_bytes",
          "process_count",
          "metrics_at",
          "players",
          "max_players",
          "query_name",
          "query_map",
          "query_at",
          "suspended",
          "suspend_reason",
          "package_id",
          "external_id",
          "installed",
          "secret_variables",
          "mods",
          "steam_account_id",
          "created_at"
        ],
        "type": "object"
      },
      "UpdateUserInputBody": {
        "additionalProperties": false,
        "properties": {
          "denied_permissions": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "display_name": {
            "maxLength": 100,
            "type": "string"
          },
          "email": {
            "maxLength": 254,
            "type": "string"
          },
          "extra_permissions": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "role": {
            "enum": [
              "superadmin",
              "admin",
              "reseller",
              "user",
              "subuser"
            ],
            "type": "string"
          },
          "status": {
            "enum": [
              "active",
              "suspended",
              "disabled"
            ],
            "type": "string"
          },
          "username": {
            "maxLength": 32,
            "type": "string"
          }
        },
        "type": "object"
      },
      "Upload-chunkResponse": {
        "additionalProperties": false,
        "properties": {
          "received": {
            "description": "Bytes the node has now",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "received"
        ],
        "type": "object"
      },
      "UploadInfo": {
        "additionalProperties": false,
        "properties": {
          "chunk_bytes": {
            "format": "int64",
            "type": "integer"
          },
          "direct": {
            "$ref": "#/components/schemas/DirectTarget",
            "description": "Upload straight to the node (PUT {url}?offset=N with the token); fall back to the controller when it fails"
          },
          "id": {
            "type": "string"
          },
          "path": {
            "type": "string"
          },
          "received": {
            "format": "int64",
            "type": "integer"
          },
          "size": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "id",
          "chunk_bytes",
          "received",
          "size",
          "path"
        ],
        "type": "object"
      },
      "UsageReport": {
        "additionalProperties": false,
        "properties": {
          "cpu_avg_percent": {
            "description": "100 = one core",
            "format": "double",
            "type": "number"
          },
          "cpu_max_percent": {
            "format": "double",
            "type": "number"
          },
          "disk_limit_bytes": {
            "description": "0 = unlimited",
            "format": "int64",
            "type": "integer"
          },
          "disk_measured_at": {
            "description": "When the disk usage was measured (older when the node is offline)",
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "disk_used_bytes": {
            "description": "The service directory's size; null when never measured",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "mem_avg_bytes": {
            "format": "int64",
            "type": "integer"
          },
          "mem_limit_bytes": {
            "description": "0 = unlimited",
            "format": "int64",
            "type": "integer"
          },
          "mem_max_bytes": {
            "format": "int64",
            "type": "integer"
          },
          "net_measured": {
            "description": "Per-service network traffic is not measured yet (always false)",
            "type": "boolean"
          },
          "players_max": {
            "format": "int32",
            "type": "integer"
          },
          "samples": {
            "description": "Resource samples in the period (one per minute while running)",
            "format": "int64",
            "type": "integer"
          },
          "service_id": {
            "format": "int64",
            "type": "integer"
          },
          "since": {
            "format": "date-time",
            "type": "string"
          },
          "slots": {
            "format": "int32",
            "type": "integer"
          }
        },
        "required": [
          "service_id",
          "since",
          "disk_used_bytes",
          "disk_measured_at",
          "disk_limit_bytes",
          "cpu_avg_percent",
          "cpu_max_percent",
          "mem_avg_bytes",
          "mem_max_bytes",
          "mem_limit_bytes",
          "players_max",
          "slots",
          "samples",
          "net_measured"
        ],
        "type": "object"
      },
      "User": {
        "additionalProperties": false,
        "properties": {
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "denied_permissions": {
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "display_name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "extra_permissions": {
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "last_login_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "last_login_ip": {
            "type": [
              "string",
              "null"
            ]
          },
          "locked_until": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "must_change_password": {
            "type": "boolean"
          },
          "reseller_id": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "role": {
            "enum": [
              "superadmin",
              "admin",
              "reseller",
              "user",
              "subuser"
            ],
            "type": "string"
          },
          "status": {
            "enum": [
              "active",
              "suspended",
              "disabled"
            ],
            "type": "string"
          },
          "totp_enabled": {
            "type": "boolean"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          },
          "username": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "email",
          "username",
          "display_name",
          "role",
          "status",
          "reseller_id",
          "extra_permissions",
          "denied_permissions",
          "totp_enabled",
          "locked_until",
          "must_change_password",
          "last_login_at",
          "last_login_ip",
          "created_at",
          "updated_at"
        ],
        "type": "object"
      },
      "Validate-game-definitionResponse": {
        "additionalProperties": false,
        "properties": {
          "game": {
            "$ref": "#/components/schemas/Game"
          },
          "problems": {
            "items": {
              "$ref": "#/components/schemas/ValidationProblem"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "valid": {
            "type": "boolean"
          }
        },
        "required": [
          "valid",
          "problems"
        ],
        "type": "object"
      },
      "ValidationProblem": {
        "additionalProperties": false,
        "properties": {
          "message": {
            "type": "string"
          },
          "path": {
            "type": "string"
          }
        },
        "required": [
          "path",
          "message"
        ],
        "type": "object"
      },
      "View": {
        "additionalProperties": false,
        "properties": {
          "cpu_limit_percent": {
            "description": "0 = unlimited; 100 = one core",
            "format": "int32",
            "type": "integer"
          },
          "cpu_percent": {
            "format": "float",
            "type": [
              "number",
              "null"
            ]
          },
          "crash_policy": {
            "$ref": "#/components/schemas/CrashPolicy"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "desired_state": {
            "enum": [
              "running",
              "stopped"
            ],
            "type": "string"
          },
          "disk_limit_bytes": {
            "description": "File manager / SFTP / upload quota; 0 = unlimited",
            "format": "int64",
            "type": "integer"
          },
          "external_id": {
            "description": "The billing system's reference",
            "type": [
              "string",
              "null"
            ]
          },
          "file_deny": {
            "description": "Deny globs added for this service (on top of the game definition's): matching paths are hidden from everyone except administrators",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "game_id": {
            "type": "string"
          },
          "has_rcon": {
            "description": "The game has a remote console (only on GET /services/{id})",
            "type": "boolean"
          },
          "has_workshop": {
            "description": "The game takes Steam Workshop mods (only on GET /services/{id})",
            "type": "boolean"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "install": {
            "$ref": "#/components/schemas/InstallProgress",
            "description": "While installing / updating"
          },
          "install_dir": {
            "type": "string"
          },
          "installed": {
            "description": "The game files are in place",
            "type": "boolean"
          },
          "ip": {
            "type": "string"
          },
          "last_error": {
            "description": "The last command the agent refused, and why",
            "type": "string"
          },
          "last_exit_code": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "max_players": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "memory_limit_bytes": {
            "description": "0 = unlimited",
            "format": "int64",
            "type": "integer"
          },
          "memory_used_bytes": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "metrics_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "mods": {
            "additionalProperties": {
              "items": {
                "$ref": "#/components/schemas/WorkshopItem"
              },
              "type": [
                "array",
                "null"
              ]
            },
            "description": "Workshop items per modlist variable",
            "type": "object"
          },
          "name": {
            "type": "string"
          },
          "node_connected": {
            "description": "The node's agent link is up",
            "type": "boolean"
          },
          "node_id": {
            "format": "int64",
            "type": "integer"
          },
          "node_name": {
            "type": "string"
          },
          "node_os": {
            "enum": [
              "windows",
              "linux"
            ],
            "type": "string"
          },
          "observed_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "observed_message": {
            "type": "string"
          },
          "observed_status": {
            "description": "What the agent last reported",
            "type": "string"
          },
          "os_user": {
            "type": "string"
          },
          "owner_user_id": {
            "format": "int64",
            "type": "integer"
          },
          "owner_username": {
            "type": "string"
          },
          "package_id": {
            "description": "The package it was ordered with (null = none)",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "permissions": {
            "description": "What the caller may do on this service (absent on WebSocket events)",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "players": {
            "description": "From the game's status query while it runs (null = unknown)",
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "ports": {
            "description": "Only on GET /services/{id}",
            "items": {
              "$ref": "#/components/schemas/PortView"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "primary_port": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "process_count": {
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "processes": {
            "description": "Only on GET /services/{id}",
            "items": {
              "$ref": "#/components/schemas/ProcessView"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "query_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "query_map": {
            "type": "string"
          },
          "query_name": {
            "description": "Server name the game reports",
            "type": "string"
          },
          "restarts": {
            "description": "Crash restarts within the crash-policy window",
            "format": "int32",
            "type": "integer"
          },
          "secret_variables": {
            "description": "Password variables that have a value (values are never returned)",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "sftp": {
            "$ref": "#/components/schemas/SFTPInfo",
            "description": "How the caller connects with SFTP (only on GET /services/{id}, with the files permission)"
          },
          "slots": {
            "format": "int32",
            "type": "integer"
          },
          "status": {
            "enum": [
              "installing",
              "install_failed",
              "stopped",
              "starting",
              "running",
              "stopping",
              "crashed",
              "suspended",
              "moving",
              "deleting"
            ],
            "type": "string"
          },
          "steam_account_id": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "suspend_reason": {
            "description": "Why it was suspended (billing or an administrator)",
            "type": "string"
          },
          "suspended": {
            "type": "boolean"
          },
          "variables": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object"
          }
        },
        "required": [
          "id",
          "name",
          "game_id",
          "node_id",
          "node_name",
          "node_os",
          "node_connected",
          "owner_user_id",
          "owner_username",
          "status",
          "desired_state",
          "observed_status",
          "observed_message",
          "observed_at",
          "last_error",
          "restarts",
          "last_exit_code",
          "install_dir",
          "os_user",
          "ip",
          "primary_port",
          "slots",
          "variables",
          "cpu_limit_percent",
          "memory_limit_bytes",
          "disk_limit_bytes",
          "file_deny",
          "crash_policy",
          "cpu_percent",
          "memory_used_bytes",
          "process_count",
          "metrics_at",
          "players",
          "max_players",
          "query_name",
          "query_map",
          "query_at",
          "suspended",
          "suspend_reason",
          "package_id",
          "external_id",
          "installed",
          "secret_variables",
          "mods",
          "steam_account_id",
          "created_at"
        ],
        "type": "object"
      },
      "WebhookBody": {
        "additionalProperties": false,
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "events": {
            "description": "Empty = every event",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "kind": {
            "description": "Fixed after creation",
            "enum": [
              "generic",
              "discord",
              "email"
            ],
            "type": "string"
          },
          "name": {
            "maxLength": 80,
            "minLength": 1,
            "type": "string"
          },
          "secret": {
            "description": "generic: HMAC-SHA256 signing secret (write-only; \"\" removes it)",
            "maxLength": 200,
            "type": "string"
          },
          "url": {
            "description": "generic / discord: the URL; email: addresses. On update, empty keeps the stored one",
            "maxLength": 2000,
            "type": "string"
          }
        },
        "required": [
          "name",
          "enabled"
        ],
        "type": "object"
      },
      "WebhookView": {
        "additionalProperties": false,
        "properties": {
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "enabled": {
            "type": "boolean"
          },
          "events": {
            "description": "Empty = every event",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "has_secret": {
            "type": "boolean"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "kind": {
            "enum": [
              "generic",
              "discord",
              "email"
            ],
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          },
          "url": {
            "description": "Generic: the endpoint; Discord: masked; email: the addresses",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "kind",
          "url",
          "has_secret",
          "events",
          "enabled",
          "created_at",
          "updated_at"
        ],
        "type": "object"
      },
      "WorkshopItem": {
        "additionalProperties": false,
        "properties": {
          "folder": {
            "type": "string"
          },
          "id": {
            "format": "int64",
            "type": "integer"
          },
          "title": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "title",
          "folder"
        ],
        "type": "object"
      },
      "Write-fileRequest": {
        "additionalProperties": false,
        "properties": {
          "content": {
            "type": "string"
          },
          "expect": {
            "maxLength": 64,
            "type": "string"
          },
          "path": {
            "maxLength": 4096,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "path",
          "content"
        ],
        "type": "object"
      },
      "Write-fileResponse": {
        "additionalProperties": false,
        "properties": {
          "entry": {
            "$ref": "#/components/schemas/FileEntry"
          },
          "hash": {
            "type": "string"
          }
        },
        "required": [
          "entry",
          "hash"
        ],
        "type": "object"
      }
    },
    "securitySchemes": {
      "apiKey": {
        "description": "API key (ngcpk_...)",
        "scheme": "bearer",
        "type": "http"
      },
      "session": {
        "description": "Browser session; also send X-CSRF-Token on writes",
        "in": "cookie",
        "name": "ngcp_session",
        "type": "apiKey"
      }
    }
  },
  "info": {
    "description": "Control-panel API for NGCP. Browser clients authenticate with the session cookie and send the X-CSRF-Token header on every state-changing request; API clients send `Authorization: Bearer ngcpk_...`. Errors use the envelope `{\"error\": {\"code\", \"message\", \"details\"}}`.",
    "title": "NGCP API",
    "version": "1.0.0"
  },
  "openapi": "3.1.0",
  "paths": {
    "/api/v1/agent/ca": {
      "get": {
        "operationId": "get-agent-ca",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CAInfo"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "security": [],
        "summary": "The agent CA certificate (agents verify it against --ca-hash before enrolling)",
        "tags": [
          "Agent"
        ]
      }
    },
    "/api/v1/agent/enroll": {
      "post": {
        "description": "Consumes a one-time token, creates the node and signs the agent's certificate. The agent must verify ca_pem against the --ca-hash it was given.",
        "operationId": "agent-enroll",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Request"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Response"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "security": [],
        "summary": "Enroll a node (called by ngcp-agent enroll)",
        "tags": [
          "Agent"
        ]
      }
    },
    "/api/v1/agent/releases": {
      "get": {
        "operationId": "list-agent-releases",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List-agent-releasesResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Agent builds available for self-update",
        "tags": [
          "Agent"
        ]
      }
    },
    "/api/v1/api-keys": {
      "get": {
        "operationId": "list-api-keys",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIKeysOutputBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "List my API keys",
        "tags": [
          "API keys"
        ]
      },
      "post": {
        "operationId": "create-api-key",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAPIKeyInputBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateAPIKeyOutputBody"
                }
              }
            },
            "description": "Created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Create an API key",
        "tags": [
          "API keys"
        ]
      }
    },
    "/api/v1/api-keys/{id}": {
      "delete": {
        "operationId": "revoke-api-key",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Revoke one of my API keys",
        "tags": [
          "API keys"
        ]
      }
    },
    "/api/v1/audit-events": {
      "get": {
        "operationId": "list-audit-events",
        "parameters": [
          {
            "explode": false,
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "explode": false,
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "format": "int32",
              "maximum": 200,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Exact action or a prefix such as 'user' (matches user.*)",
            "explode": false,
            "in": "query",
            "name": "action",
            "schema": {
              "description": "Exact action or a prefix such as 'user' (matches user.*)",
              "maxLength": 100,
              "type": "string"
            }
          },
          {
            "explode": false,
            "in": "query",
            "name": "target_type",
            "schema": {
              "maxLength": 50,
              "type": "string"
            }
          },
          {
            "explode": false,
            "in": "query",
            "name": "target_id",
            "schema": {
              "maxLength": 100,
              "type": "string"
            }
          },
          {
            "explode": false,
            "in": "query",
            "name": "actor_user_id",
            "schema": {
              "format": "int64",
              "type": "integer"
            }
          },
          {
            "explode": false,
            "in": "query",
            "name": "outcome",
            "schema": {
              "enum": [
                "success",
                "failure",
                "denied"
              ],
              "type": "string"
            }
          },
          {
            "description": "RFC 3339",
            "explode": false,
            "in": "query",
            "name": "since",
            "schema": {
              "description": "RFC 3339",
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "RFC 3339",
            "explode": false,
            "in": "query",
            "name": "until",
            "schema": {
              "description": "RFC 3339",
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageAuditEvent"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Search the audit log",
        "tags": [
          "Audit"
        ]
      }
    },
    "/api/v1/auth/login": {
      "post": {
        "description": "On success without 2FA, sets the session cookie and returns the CSRF token. With 2FA on, returns status mfa_required and an mfa_token for POST /auth/login/mfa.",
        "operationId": "login",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginInputBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginBody"
                }
              }
            },
            "description": "OK",
            "headers": {
              "Set-Cookie": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "security": [],
        "summary": "Sign in with username/email and password",
        "tags": [
          "Authentication"
        ]
      }
    },
    "/api/v1/auth/login/mfa": {
      "post": {
        "operationId": "login-mfa",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MFAInputBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginBody"
                }
              }
            },
            "description": "OK",
            "headers": {
              "Set-Cookie": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "security": [],
        "summary": "Complete sign-in with a 2FA code or recovery code",
        "tags": [
          "Authentication"
        ]
      }
    },
    "/api/v1/auth/logout": {
      "post": {
        "operationId": "logout",
        "responses": {
          "204": {
            "description": "No Content",
            "headers": {
              "Set-Cookie": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Sign out of this session",
        "tags": [
          "Authentication"
        ]
      }
    },
    "/api/v1/auth/logout-all": {
      "post": {
        "operationId": "logout-all",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogoutAllOutputBody"
                }
              }
            },
            "description": "OK",
            "headers": {
              "Set-Cookie": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Sign out of every session, including this one",
        "tags": [
          "Authentication"
        ]
      }
    },
    "/api/v1/auth/me": {
      "get": {
        "operationId": "get-me",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Who am I",
        "tags": [
          "Authentication"
        ]
      },
      "patch": {
        "operationId": "update-me",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateMeInputBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Change my display name or email address",
        "tags": [
          "Authentication"
        ]
      }
    },
    "/api/v1/auth/me/ssh-keys": {
      "get": {
        "operationId": "list-ssh-keys",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List-ssh-keysResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Your SSH keys for SFTP",
        "tags": [
          "Account"
        ]
      },
      "post": {
        "operationId": "add-ssh-key",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Add-ssh-keyRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SSHKeyOut"
                }
              }
            },
            "description": "Created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Add an SSH public key for SFTP",
        "tags": [
          "Account"
        ]
      }
    },
    "/api/v1/auth/me/ssh-keys/{id}": {
      "delete": {
        "operationId": "delete-ssh-key",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Remove an SSH key",
        "tags": [
          "Account"
        ]
      }
    },
    "/api/v1/auth/password": {
      "post": {
        "operationId": "change-password",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PasswordInputBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Change my password (ends my other sessions)",
        "tags": [
          "Authentication"
        ]
      }
    },
    "/api/v1/auth/recovery-codes": {
      "post": {
        "operationId": "regenerate-recovery-codes",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReauthInputBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecoveryCodesOutputBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Replace my recovery codes",
        "tags": [
          "Authentication"
        ]
      }
    },
    "/api/v1/auth/sessions": {
      "get": {
        "operationId": "list-sessions",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionsOutputBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "List my active sessions",
        "tags": [
          "Authentication"
        ]
      }
    },
    "/api/v1/auth/sessions/{id}": {
      "delete": {
        "operationId": "revoke-session",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "End one of my sessions",
        "tags": [
          "Authentication"
        ]
      }
    },
    "/api/v1/auth/totp/disable": {
      "post": {
        "operationId": "totp-disable",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TOTPDisableInputBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Turn off two-factor authentication",
        "tags": [
          "Authentication"
        ]
      }
    },
    "/api/v1/auth/totp/enable": {
      "post": {
        "description": "Returns recovery codes. They are shown only once.",
        "operationId": "totp-enable",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CodeInputBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecoveryCodesOutputBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Confirm a code and turn on two-factor authentication",
        "tags": [
          "Authentication"
        ]
      }
    },
    "/api/v1/auth/totp/setup": {
      "post": {
        "operationId": "totp-setup",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReauthInputBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TOTPSetupOutputBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Start turning on two-factor authentication",
        "tags": [
          "Authentication"
        ]
      }
    },
    "/api/v1/backup-targets": {
      "get": {
        "operationId": "list-backup-targets",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemsTargetViewBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Backup targets (local folder, SFTP, S3-compatible)",
        "tags": [
          "Backups"
        ]
      },
      "post": {
        "operationId": "create-backup-target",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TargetBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TargetView"
                }
              }
            },
            "description": "Created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Add a backup target",
        "tags": [
          "Backups"
        ]
      }
    },
    "/api/v1/backup-targets/{id}": {
      "delete": {
        "operationId": "delete-backup-target",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Remove a backup target no task uses (its backups stay where they are)",
        "tags": [
          "Backups"
        ]
      },
      "put": {
        "operationId": "update-backup-target",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TargetBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TargetView"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Change a backup target (its kind stays)",
        "tags": [
          "Backups"
        ]
      }
    },
    "/api/v1/datacenters": {
      "get": {
        "operationId": "list-datacenters",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List-datacentersResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "List datacenters",
        "tags": [
          "Datacenters"
        ]
      },
      "post": {
        "operationId": "create-datacenter",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DcBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Datacenter"
                }
              }
            },
            "description": "Created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Create a datacenter",
        "tags": [
          "Datacenters"
        ]
      }
    },
    "/api/v1/datacenters/{id}": {
      "delete": {
        "operationId": "delete-datacenter",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Delete an empty datacenter",
        "tags": [
          "Datacenters"
        ]
      },
      "put": {
        "operationId": "update-datacenter",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DcBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Datacenter"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Rename or relocate a datacenter",
        "tags": [
          "Datacenters"
        ]
      }
    },
    "/api/v1/enrollment-tokens": {
      "get": {
        "operationId": "list-enrollment-tokens",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List-enrollment-tokensResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Pending (unused, unexpired) enrollment tokens",
        "tags": [
          "Nodes"
        ]
      },
      "post": {
        "operationId": "create-enrollment-token",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Create-enrollment-tokenRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NewTokenOutBody"
                }
              }
            },
            "description": "Created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Create a one-time token to add a node",
        "tags": [
          "Nodes"
        ]
      }
    },
    "/api/v1/enrollment-tokens/{id}": {
      "delete": {
        "operationId": "delete-enrollment-token",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Cancel an unused enrollment token",
        "tags": [
          "Nodes"
        ]
      }
    },
    "/api/v1/game-definitions": {
      "get": {
        "operationId": "list-game-definitions",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List-game-definitionsResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Every game definition, enabled or not, with its origin and use",
        "tags": [
          "Games"
        ]
      },
      "post": {
        "description": "The definition is validated first (422 with every problem). Its version must be higher than the stored one; a saved built-in becomes custom and is no longer refreshed by controller upgrades.",
        "operationId": "save-game-definition",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GameUpload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GameSource"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Upload a new or changed game definition",
        "tags": [
          "Games"
        ]
      }
    },
    "/api/v1/game-definitions/validate": {
      "post": {
        "description": "Always 200: valid is false with every problem (path or line + message) when the definition has errors.",
        "operationId": "validate-game-definition",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GameUpload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Validate-game-definitionResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Check a game.yaml without saving it",
        "tags": [
          "Games"
        ]
      }
    },
    "/api/v1/game-definitions/{game}": {
      "delete": {
        "operationId": "delete-game-definition",
        "parameters": [
          {
            "in": "path",
            "name": "game",
            "required": true,
            "schema": {
              "pattern": "^[a-z0-9][a-z0-9_]{0,63}$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Delete a custom definition that no service uses",
        "tags": [
          "Games"
        ]
      },
      "get": {
        "operationId": "get-game-definition",
        "parameters": [
          {
            "in": "path",
            "name": "game",
            "required": true,
            "schema": {
              "pattern": "^[a-z0-9][a-z0-9_]{0,63}$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GameSource"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "A game definition with its YAML, scripts and versions",
        "tags": [
          "Games"
        ]
      },
      "patch": {
        "operationId": "set-game-definition-enabled",
        "parameters": [
          {
            "in": "path",
            "name": "game",
            "required": true,
            "schema": {
              "pattern": "^[a-z0-9][a-z0-9_]{0,63}$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Set-game-definition-enabledRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Offer or hide a game for new services",
        "tags": [
          "Games"
        ]
      }
    },
    "/api/v1/game-definitions/{game}/mods": {
      "get": {
        "operationId": "list-game-mods",
        "parameters": [
          {
            "in": "path",
            "name": "game",
            "required": true,
            "schema": {
              "maxLength": 64,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemsCatalogModBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "A game's mod catalog",
        "tags": [
          "Mods"
        ]
      },
      "post": {
        "operationId": "create-game-mod",
        "parameters": [
          {
            "in": "path",
            "name": "game",
            "required": true,
            "schema": {
              "maxLength": 64,
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CatalogBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogMod"
                }
              }
            },
            "description": "Created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Add a Workshop item or collection to a game's mod catalog",
        "tags": [
          "Mods"
        ]
      }
    },
    "/api/v1/game-definitions/{game}/mods/{mod_id}": {
      "delete": {
        "operationId": "delete-game-mod",
        "parameters": [
          {
            "in": "path",
            "name": "game",
            "required": true,
            "schema": {
              "maxLength": 64,
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "mod_id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Remove a catalog entry (services keep their mods)",
        "tags": [
          "Mods"
        ]
      },
      "put": {
        "operationId": "update-game-mod",
        "parameters": [
          {
            "in": "path",
            "name": "game",
            "required": true,
            "schema": {
              "maxLength": 64,
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "mod_id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CatalogBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogMod"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Change a catalog entry",
        "tags": [
          "Mods"
        ]
      }
    },
    "/api/v1/game-definitions/{game}/versions/{version}": {
      "get": {
        "operationId": "get-game-definition-version",
        "parameters": [
          {
            "in": "path",
            "name": "game",
            "required": true,
            "schema": {
              "pattern": "^[a-z0-9][a-z0-9_]{0,63}$",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "version",
            "required": true,
            "schema": {
              "format": "int32",
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Get-game-definition-versionResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "The YAML of an earlier version (for a diff)",
        "tags": [
          "Games"
        ]
      }
    },
    "/api/v1/games": {
      "get": {
        "operationId": "list-games",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List-gamesResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Game definitions available for new services",
        "tags": [
          "Games"
        ]
      }
    },
    "/api/v1/meta/permissions": {
      "get": {
        "operationId": "get-catalog",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogOutputBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Roles and permission flags",
        "tags": [
          "Meta"
        ]
      }
    },
    "/api/v1/nodes": {
      "get": {
        "operationId": "list-nodes",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List-nodesResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "List nodes with live status and the latest metrics",
        "tags": [
          "Nodes"
        ]
      }
    },
    "/api/v1/nodes/{id}": {
      "delete": {
        "operationId": "remove-node",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Remove a node (revokes its certificate and disconnects it)",
        "tags": [
          "Nodes"
        ]
      },
      "get": {
        "operationId": "get-node",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Node"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Get a node",
        "tags": [
          "Nodes"
        ]
      },
      "patch": {
        "operationId": "update-node",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Update-nodeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Node"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Change node settings or mode (active, draining, disabled)",
        "tags": [
          "Nodes"
        ]
      }
    },
    "/api/v1/nodes/{id}/metrics": {
      "get": {
        "operationId": "get-node-metrics",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "explode": false,
            "in": "query",
            "name": "minutes",
            "schema": {
              "default": 60,
              "format": "int64",
              "maximum": 1440,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Get-node-metricsResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Node resource samples (up to 24 h)",
        "tags": [
          "Nodes"
        ]
      }
    },
    "/api/v1/nodes/{id}/update-agent": {
      "post": {
        "operationId": "update-node-agent",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Update-node-agentRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Update-node-agentResponse"
                }
              }
            },
            "description": "Accepted"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Send a signed self-update to a connected agent",
        "tags": [
          "Nodes"
        ]
      }
    },
    "/api/v1/notification-deliveries": {
      "get": {
        "operationId": "list-notification-deliveries",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemsDeliveryBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "The latest 200 deliveries with their status",
        "tags": [
          "Notifications"
        ]
      }
    },
    "/api/v1/notification-events": {
      "get": {
        "operationId": "list-notification-events",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemsStringBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Events a webhook can subscribe to",
        "tags": [
          "Notifications"
        ]
      }
    },
    "/api/v1/packages": {
      "get": {
        "operationId": "list-packages",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PackagesOutBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Packages (products): all for administrators, the global ones plus their own for resellers",
        "tags": [
          "Packages"
        ]
      },
      "post": {
        "operationId": "create-package",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PackageBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Package"
                }
              }
            },
            "description": "Created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Create a package",
        "tags": [
          "Packages"
        ]
      }
    },
    "/api/v1/packages/{id}": {
      "delete": {
        "operationId": "delete-package",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Delete a package no game server uses",
        "tags": [
          "Packages"
        ]
      },
      "get": {
        "operationId": "get-package",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Package"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "A package",
        "tags": [
          "Packages"
        ]
      },
      "put": {
        "description": "Existing game servers keep their limits until their package is applied again (PATCH /services/{id}/package).",
        "operationId": "update-package",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PackageBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Package"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Replace a package's settings (not its game or owner)",
        "tags": [
          "Packages"
        ]
      }
    },
    "/api/v1/public/branding": {
      "get": {
        "operationId": "get-branding",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandingOutputBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "security": [],
        "summary": "Branding for the sign-in page",
        "tags": [
          "Authentication"
        ]
      }
    },
    "/api/v1/resellers": {
      "get": {
        "operationId": "list-resellers",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResellersOutBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Resellers with their quotas and what their customers use",
        "tags": [
          "Resellers"
        ]
      },
      "post": {
        "description": "Its accounts are then created as users with role reseller and this reseller_id.",
        "operationId": "create-reseller",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResellerBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Reseller"
                }
              }
            },
            "description": "Created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Create a reseller",
        "tags": [
          "Resellers"
        ]
      }
    },
    "/api/v1/resellers/{id}": {
      "delete": {
        "operationId": "delete-reseller",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Delete a reseller that has no accounts left",
        "tags": [
          "Resellers"
        ]
      },
      "get": {
        "operationId": "get-reseller",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Reseller"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "A reseller (administrators any; a reseller account its own, with quotas and usage)",
        "tags": [
          "Resellers"
        ]
      },
      "put": {
        "description": "Lowering a quota below what is in use is allowed; it only stops further growth.",
        "operationId": "update-reseller",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResellerBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Reseller"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Replace a reseller's name, branding, quotas and allowed games / nodes",
        "tags": [
          "Resellers"
        ]
      }
    },
    "/api/v1/schedule-preview": {
      "get": {
        "operationId": "preview-schedule",
        "parameters": [
          {
            "explode": false,
            "in": "query",
            "name": "cron",
            "schema": {
              "maxLength": 100,
              "type": "string"
            }
          },
          {
            "explode": false,
            "in": "query",
            "name": "timezone",
            "schema": {
              "maxLength": 64,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemsTimeBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "The next runs of a cron expression (checks it too)",
        "tags": [
          "Schedules"
        ]
      }
    },
    "/api/v1/schedules": {
      "get": {
        "operationId": "list-global-schedules",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemsTaskViewBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Global scheduled tasks",
        "tags": [
          "Schedules"
        ]
      },
      "post": {
        "operationId": "create-global-schedule",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskView"
                }
              }
            },
            "description": "Created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Add a global scheduled task (every service matching the selector)",
        "tags": [
          "Schedules"
        ]
      }
    },
    "/api/v1/schedules/{id}": {
      "delete": {
        "operationId": "delete-global-schedule",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Remove a global scheduled task",
        "tags": [
          "Schedules"
        ]
      },
      "put": {
        "operationId": "update-global-schedule",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskView"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Change a global scheduled task",
        "tags": [
          "Schedules"
        ]
      }
    },
    "/api/v1/services": {
      "get": {
        "description": "With external_id (billing keys): only the game server provisioned with that billing reference, or none.",
        "operationId": "list-services",
        "parameters": [
          {
            "description": "Billing: find a game server by its billing reference",
            "explode": false,
            "in": "query",
            "name": "external_id",
            "schema": {
              "description": "Billing: find a game server by its billing reference",
              "maxLength": 100,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List-servicesResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Services the caller may see, with live status",
        "tags": [
          "Services"
        ]
      },
      "post": {
        "description": "Allocates a block of ports from the node's range, creates the service's OS user and directory on the node and, with start=true, starts it. With a package the game, slot range, limits and allowed datacenters come from it; without node_id the node is picked. Billing keys (ADR-0024) provision from a package for a customer (owner_user_id, or owner_email: found or created in the caller's tenancy) and are idempotent by external_id (a repeat answers 200 with existing=true).",
        "operationId": "create-service",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Create-serviceRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateOutBody"
                }
              }
            },
            "description": "Created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Create a service",
        "tags": [
          "Services"
        ]
      }
    },
    "/api/v1/services/{id}": {
      "delete": {
        "description": "The service shows status deleting until its node confirms; a node that is offline is cleaned up when it reconnects.",
        "operationId": "delete-service",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Delete a service with its files and OS user",
        "tags": [
          "Services"
        ]
      },
      "get": {
        "operationId": "get-service",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/View"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "A service with its ports, processes and the caller's permissions",
        "tags": [
          "Services"
        ]
      },
      "patch": {
        "description": "Variables are merged into the current values; password variables are write-only (an empty value clears one). When mods changed, mods_changed is true: run the update action to download them.",
        "operationId": "update-service",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Update-serviceRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateOutBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Change a service's name, slots, variables or mods",
        "tags": [
          "Services"
        ]
      }
    },
    "/api/v1/services/{id}/backups": {
      "get": {
        "operationId": "list-service-backups",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SvcBackupsBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "A service's backups",
        "tags": [
          "Backups"
        ]
      },
      "post": {
        "description": "The node streams a .tar.gz of the service's files to the target while the server keeps running; progress arrives as \"backups\" events on the WebSocket topic service:{id}.",
        "operationId": "create-service-backup",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Create-service-backupRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BackupView"
                }
              }
            },
            "description": "Accepted"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Back a service up now",
        "tags": [
          "Backups"
        ]
      }
    },
    "/api/v1/services/{id}/backups/{backup_id}": {
      "delete": {
        "operationId": "delete-service-backup",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "path",
            "name": "backup_id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Delete a backup from its target",
        "tags": [
          "Backups"
        ]
      }
    },
    "/api/v1/services/{id}/backups/{backup_id}/restore": {
      "post": {
        "description": "The node stops the service, downloads and unpacks the backup into a staging folder, replaces the backed-up files and starts the service again if it was running.",
        "operationId": "restore-service-backup",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "path",
            "name": "backup_id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Restore a backup",
        "tags": [
          "Backups"
        ]
      }
    },
    "/api/v1/services/{id}/configs": {
      "get": {
        "description": "Settings come from the game definition; bound settings follow a panel value (a variable or the slot count) and show it.",
        "operationId": "list-configs",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List-configsResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "The service's config files as forms",
        "tags": [
          "Configs"
        ]
      }
    },
    "/api/v1/services/{id}/configs/{index}": {
      "put": {
        "description": "values: the settings to change (others stay as they are). A bound setting changes its variable / the slot count instead; the file follows. A password left null is unchanged. hash: the form's version (409 when the file changed meanwhile).",
        "operationId": "update-config",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "path",
            "name": "index",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Update-configRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigFileView"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Save a config form",
        "tags": [
          "Configs"
        ]
      }
    },
    "/api/v1/services/{id}/console": {
      "post": {
        "operationId": "send-console-input",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Send-console-inputRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Send a line to the service's console (stdin of the main process)",
        "tags": [
          "Services"
        ]
      }
    },
    "/api/v1/services/{id}/files": {
      "get": {
        "description": "Directories first, then by name. Paths the game definition or an administrator denies are left out (administrators see them).",
        "operationId": "list-files",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Relative to the service directory, / separated; empty or / is the directory itself",
            "explode": false,
            "in": "query",
            "name": "path",
            "schema": {
              "description": "Relative to the service directory, / separated; empty or / is the directory itself",
              "maxLength": 4096,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List-filesResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "List a folder of the service",
        "tags": [
          "Files"
        ]
      }
    },
    "/api/v1/services/{id}/files/content": {
      "get": {
        "description": "Files up to 2 MiB; larger ones are downloaded.",
        "operationId": "read-file",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Relative to the service directory, / separated; empty or / is the directory itself",
            "explode": false,
            "in": "query",
            "name": "path",
            "schema": {
              "description": "Relative to the service directory, / separated; empty or / is the directory itself",
              "maxLength": 4096,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileContentOut"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Open a text file in the editor",
        "tags": [
          "Files"
        ]
      },
      "put": {
        "description": "expect: omit to overwrite or create, \"absent\" to only create, or the hash the editor read (409 conflict when the file changed meanwhile).",
        "operationId": "write-file",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Write-fileRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Write-fileResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Save a text file from the editor",
        "tags": [
          "Files"
        ]
      }
    },
    "/api/v1/services/{id}/files/direct-download": {
      "post": {
        "description": "null when the node has no direct file endpoint; then use GET .../files/download. The URL works for one hour.",
        "operationId": "direct-download",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Direct-downloadRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Direct-downloadResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "A signed URL to download straight from the node",
        "tags": [
          "Files"
        ]
      }
    },
    "/api/v1/services/{id}/files/download": {
      "get": {
        "description": "Streams from the node through the controller (constant memory). For a direct node URL use POST .../files/direct-download.",
        "operationId": "download-file",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Relative to the service directory, / separated; empty or / is the directory itself",
            "explode": false,
            "in": "query",
            "name": "path",
            "schema": {
              "description": "Relative to the service directory, / separated; empty or / is the directory itself",
              "maxLength": 4096,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/octet-stream": {
                "schema": {
                  "contentMediaType": "application/octet-stream",
                  "format": "binary",
                  "type": "string"
                }
              }
            },
            "description": "The file"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Download a file",
        "tags": [
          "Files"
        ]
      }
    },
    "/api/v1/services/{id}/files/ops": {
      "post": {
        "description": "mkdir: path. rename / copy: path -\u003e dest (rename with overwrite replaces a file). delete: paths. chmod: path + mode (octal bits as a number, Linux; Windows only toggles read-only). compress: paths -\u003e dest (.zip, .tar.gz, .tar). extract: path (an archive) -\u003e dest folder (overwrite replaces existing files).",
        "operationId": "file-operation",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/File-operationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/File-operationResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Create a folder, rename / move, copy, delete, change permissions, compress or extract",
        "tags": [
          "Files"
        ]
      }
    },
    "/api/v1/services/{id}/files/search": {
      "get": {
        "operationId": "search-files",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Relative to the service directory, / separated; empty or / is the directory itself",
            "explode": false,
            "in": "query",
            "name": "path",
            "schema": {
              "description": "Relative to the service directory, / separated; empty or / is the directory itself",
              "maxLength": 4096,
              "type": "string"
            }
          },
          {
            "description": "Part of the name, or a glob with * ? [ ]",
            "explode": false,
            "in": "query",
            "name": "q",
            "schema": {
              "description": "Part of the name, or a glob with * ? [ ]",
              "maxLength": 200,
              "minLength": 1,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Search-filesResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Find files and folders by name below a folder",
        "tags": [
          "Files"
        ]
      }
    },
    "/api/v1/services/{id}/files/stat": {
      "get": {
        "operationId": "stat-file",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Relative to the service directory, / separated; empty or / is the directory itself",
            "explode": false,
            "in": "query",
            "name": "path",
            "schema": {
              "description": "Relative to the service directory, / separated; empty or / is the directory itself",
              "maxLength": 4096,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileEntry"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Describe one file or folder",
        "tags": [
          "Files"
        ]
      }
    },
    "/api/v1/services/{id}/files/usage": {
      "get": {
        "operationId": "service-disk-usage",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceDiskUsage"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "The service directory's size and quota",
        "tags": [
          "Files"
        ]
      }
    },
    "/api/v1/services/{id}/metrics": {
      "get": {
        "operationId": "get-service-metrics",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Default: one hour ago",
            "explode": false,
            "in": "query",
            "name": "since",
            "schema": {
              "description": "Default: one hour ago",
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Get-service-metricsResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "The service's CPU and memory samples (at most the last 24 hours)",
        "tags": [
          "Services"
        ]
      }
    },
    "/api/v1/services/{id}/mods": {
      "get": {
        "operationId": "get-service-mods",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceModsView"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "A service's mod lists and its game's mod catalog",
        "tags": [
          "Mods"
        ]
      }
    },
    "/api/v1/services/{id}/mods/expand": {
      "post": {
        "operationId": "expand-workshop",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Expand-workshopRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemsWorkshopItemBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Resolve a Workshop id or link (a collection becomes its items, with titles)",
        "tags": [
          "Mods"
        ]
      }
    },
    "/api/v1/services/{id}/mods/{variable}": {
      "put": {
        "operationId": "set-service-mods",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "path",
            "name": "variable",
            "required": true,
            "schema": {
              "maxLength": 64,
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Set-service-modsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetModsOutBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Replace one mod list (Workshop ids in load order)",
        "tags": [
          "Mods"
        ]
      }
    },
    "/api/v1/services/{id}/package": {
      "patch": {
        "description": "Applies the package's limits; slots are clamped into the new range unless given. Administrators, the owner's reseller and billing keys.",
        "operationId": "change-service-package",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Change-service-packageRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/View"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Move a game server to another package of the same game (billing: upgrade / downgrade)",
        "tags": [
          "Billing"
        ]
      }
    },
    "/api/v1/services/{id}/rcon": {
      "post": {
        "description": "The node sends the command to the game on 127.0.0.1 (Source, BattlEye, Minecraft or TeamSpeak ServerQuery) and returns the answer. Audited.",
        "operationId": "service-rcon",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Service-rconRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RconReply"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Run a remote-console (RCON) command",
        "tags": [
          "Services"
        ]
      }
    },
    "/api/v1/services/{id}/schedule-runs": {
      "get": {
        "operationId": "list-service-schedule-runs",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemsScheduleRunViewBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "A service's latest scheduled-task runs (also those that ran while the controller was down)",
        "tags": [
          "Schedules"
        ]
      }
    },
    "/api/v1/services/{id}/schedules": {
      "get": {
        "operationId": "list-service-schedules",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SvcTasksBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "A service's scheduled tasks",
        "tags": [
          "Schedules"
        ]
      },
      "post": {
        "description": "The task goes to the service's node, which runs it even while the controller is unreachable. Scripts are for administrators.",
        "operationId": "create-service-schedule",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskView"
                }
              }
            },
            "description": "Created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Add a scheduled task to a service",
        "tags": [
          "Schedules"
        ]
      }
    },
    "/api/v1/services/{id}/schedules/{task_id}": {
      "delete": {
        "operationId": "delete-service-schedule",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "path",
            "name": "task_id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Remove a service's scheduled task",
        "tags": [
          "Schedules"
        ]
      },
      "put": {
        "operationId": "update-service-schedule",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "path",
            "name": "task_id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskView"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Change a service's scheduled task",
        "tags": [
          "Schedules"
        ]
      }
    },
    "/api/v1/services/{id}/subusers": {
      "get": {
        "operationId": "list-subusers",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GrantsOutBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Accounts that have access to this game server (sub-users)",
        "tags": [
          "Services"
        ]
      },
      "put": {
        "description": "view is always included. Nobody grants a permission they do not hold on this server. An unknown address creates a sub-user account in the owner's tenancy and returns its one-time password.",
        "operationId": "set-subuser",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Set-subuserRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GrantResult"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Give an account (by e-mail address) access to this game server, or change its access",
        "tags": [
          "Services"
        ]
      }
    },
    "/api/v1/services/{id}/subusers/{user_id}": {
      "delete": {
        "operationId": "remove-subuser",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "path",
            "name": "user_id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Take a sub-user's access to this game server away (the account stays)",
        "tags": [
          "Services"
        ]
      }
    },
    "/api/v1/services/{id}/uploads": {
      "post": {
        "description": "Then PUT each chunk (chunk_bytes at most, in order) to .../uploads/{upload}?offset=N, and POST .../complete. After a 409 conflict on a chunk (a gap or a retry from the wrong place), GET .../uploads/{upload} returns received: resume there. When direct is set, the chunks may go straight to the node instead (PUT {direct.url}?offset=N with header Authorization: Bearer {direct.token}).",
        "operationId": "begin-upload",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Begin-uploadRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadInfo"
                }
              }
            },
            "description": "Created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Start a chunked upload",
        "tags": [
          "Files"
        ]
      }
    },
    "/api/v1/services/{id}/uploads/{upload}": {
      "delete": {
        "operationId": "abort-upload",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "path",
            "name": "upload",
            "required": true,
            "schema": {
              "maxLength": 64,
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Cancel an upload and drop what was sent",
        "tags": [
          "Files"
        ]
      },
      "get": {
        "operationId": "get-upload",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "path",
            "name": "upload",
            "required": true,
            "schema": {
              "maxLength": 64,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadInfo"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "How much of an upload the node has (to resume)",
        "tags": [
          "Files"
        ]
      },
      "put": {
        "description": "The raw bytes (application/octet-stream), at most 64 MiB per request. They stream to the node; the controller keeps no copy.",
        "operationId": "upload-chunk",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "path",
            "name": "upload",
            "required": true,
            "schema": {
              "maxLength": 64,
              "type": "string"
            }
          },
          {
            "description": "Where this chunk starts in the file",
            "explode": false,
            "in": "query",
            "name": "offset",
            "schema": {
              "description": "Where this chunk starts in the file",
              "format": "int64",
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/octet-stream": {
              "schema": {
                "contentMediaType": "application/octet-stream",
                "format": "binary",
                "type": "string"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Upload-chunkResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Send one chunk of an upload",
        "tags": [
          "Files"
        ]
      }
    },
    "/api/v1/services/{id}/uploads/{upload}/complete": {
      "post": {
        "operationId": "complete-upload",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "path",
            "name": "upload",
            "required": true,
            "schema": {
              "maxLength": 64,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileEntry"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Finish an upload: the file appears at its path",
        "tags": [
          "Files"
        ]
      }
    },
    "/api/v1/services/{id}/usage": {
      "get": {
        "operationId": "get-service-usage",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Start of the period (RFC 3339); default 30 days ago, at most 90",
            "explode": false,
            "in": "query",
            "name": "since",
            "schema": {
              "description": "Start of the period (RFC 3339); default 30 days ago, at most 90",
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageReport"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Disk, CPU, memory and player usage of a game server (billing usage updates)",
        "tags": [
          "Billing"
        ]
      }
    },
    "/api/v1/services/{id}/{action}": {
      "post": {
        "description": "Returns at once with the transitional status (starting, stopping, installing, ...); the agent's report follows on the WebSocket topic service:{id}. update downloads new game files and mods (a running service is stopped and started again); reinstall removes everything except the game's preserve_on_reinstall files. Suspend (with an optional reason), unsuspend and reinstall are also open to billing keys; suspend stops the server gracefully and blocks start, console, files and SFTP, keeping everything (ADR-0024).",
        "operationId": "service-action",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "path",
            "name": "action",
            "required": true,
            "schema": {
              "enum": [
                "start",
                "stop",
                "restart",
                "kill",
                "update",
                "reinstall",
                "cancel_install",
                "suspend",
                "unsuspend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Service-actionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/View"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Start, stop, restart, kill, update, reinstall, cancel an install, suspend or unsuspend a service",
        "tags": [
          "Services"
        ]
      }
    },
    "/api/v1/settings": {
      "get": {
        "operationId": "get-settings",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Settings"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Read panel settings",
        "tags": [
          "Settings"
        ]
      },
      "put": {
        "operationId": "update-settings",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Settings"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Settings"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Replace panel settings (SuperAdmin)",
        "tags": [
          "Settings"
        ]
      }
    },
    "/api/v1/settings/notification-templates": {
      "get": {
        "operationId": "get-notification-templates",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemsTemplateViewBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Message templates per event (Go text/template over the event: .Service .Node .Message .Panel)",
        "tags": [
          "Notifications"
        ]
      },
      "put": {
        "operationId": "update-notification-templates",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Update-notification-templatesRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemsTemplateViewBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Replace the template overrides (an empty text uses the default)",
        "tags": [
          "Notifications"
        ]
      }
    },
    "/api/v1/settings/smtp": {
      "get": {
        "operationId": "get-smtp-settings",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SMTPView"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "The outgoing mail server for e-mail notifications",
        "tags": [
          "Notifications"
        ]
      },
      "put": {
        "operationId": "update-smtp-settings",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Update-smtp-settingsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SMTPView"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Change the mail server (an empty host turns e-mail off)",
        "tags": [
          "Notifications"
        ]
      }
    },
    "/api/v1/setup": {
      "get": {
        "operationId": "get-setup",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetupStatus"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "security": [],
        "summary": "Whether the first-run setup is open (and, with the token or from the server itself, its options)",
        "tags": [
          "Setup"
        ]
      },
      "post": {
        "description": "database_mode builtin creates the bundled database (Windows) or uses the package-prepared local one (Linux); external uses database_url. The controller switches to normal operation right after answering; sign in at login_url.",
        "operationId": "complete-setup",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetupCompleteInBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Result"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "security": [],
        "summary": "Finish the setup: database, first administrator, address, TLS",
        "tags": [
          "Setup"
        ]
      }
    },
    "/api/v1/setup/check": {
      "post": {
        "operationId": "check-setup",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetupToken"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetupStatus"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "security": [],
        "summary": "Check the setup token and get the setup's options",
        "tags": [
          "Setup"
        ]
      }
    },
    "/api/v1/setup/test-database": {
      "post": {
        "operationId": "test-setup-database",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetupDBInBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "security": [],
        "summary": "Try to connect to an existing PostgreSQL",
        "tags": [
          "Setup"
        ]
      }
    },
    "/api/v1/steam-accounts": {
      "get": {
        "operationId": "list-steam-accounts",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List-steam-accountsResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Steam accounts SteamCMD logs in with (passwords are never returned)",
        "tags": [
          "Steam accounts"
        ]
      },
      "post": {
        "description": "Bohemia and Valve recommend a separate account for servers. The first install with it may ask for a Steam Guard code: type the code into the service's console.",
        "operationId": "create-steam-account",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SteamBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SteamAccount"
                }
              }
            },
            "description": "Created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Add a Steam account",
        "tags": [
          "Steam accounts"
        ]
      }
    },
    "/api/v1/steam-accounts/{id}": {
      "delete": {
        "operationId": "delete-steam-account",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Remove a Steam account (its services use the default account)",
        "tags": [
          "Steam accounts"
        ]
      },
      "put": {
        "operationId": "update-steam-account",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SteamBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SteamAccount"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Change a Steam account",
        "tags": [
          "Steam accounts"
        ]
      }
    },
    "/api/v1/users": {
      "get": {
        "operationId": "list-users",
        "parameters": [
          {
            "explode": false,
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "explode": false,
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "format": "int32",
              "maximum": 200,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Matches username, email or display name",
            "explode": false,
            "in": "query",
            "name": "search",
            "schema": {
              "description": "Matches username, email or display name",
              "maxLength": 100,
              "type": "string"
            }
          },
          {
            "explode": false,
            "in": "query",
            "name": "role",
            "schema": {
              "enum": [
                "superadmin",
                "admin",
                "reseller",
                "user",
                "subuser"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageUser"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "List users",
        "tags": [
          "Users"
        ]
      },
      "post": {
        "operationId": "create-user",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateUserInputBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            },
            "description": "Created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Create a user",
        "tags": [
          "Users"
        ]
      }
    },
    "/api/v1/users/{id}": {
      "delete": {
        "operationId": "delete-user",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Delete a user (ends their sessions and API keys)",
        "tags": [
          "Users"
        ]
      },
      "get": {
        "operationId": "get-user",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Get a user",
        "tags": [
          "Users"
        ]
      },
      "patch": {
        "operationId": "update-user",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateUserInputBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Update a user",
        "tags": [
          "Users"
        ]
      }
    },
    "/api/v1/users/{id}/password": {
      "post": {
        "description": "Billing API keys may set the password of the customer accounts (user, sub-user) in their tenancy.",
        "operationId": "reset-user-password",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResetPasswordInputBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Set a user's password (ends their sessions)",
        "tags": [
          "Users"
        ]
      }
    },
    "/api/v1/users/{id}/sso-link": {
      "post": {
        "description": "Only for user and sub-user accounts in the caller's tenancy. With service_id the link opens that game server (the account must own it or have access).",
        "operationId": "create-sso-link",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Create-sso-linkRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SsoOutBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "A one-time sign-in link for a customer account (\"Log in to panel\")",
        "tags": [
          "Billing"
        ]
      }
    },
    "/api/v1/users/{id}/totp": {
      "delete": {
        "operationId": "reset-user-totp",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Turn off a user's two-factor authentication (lost device)",
        "tags": [
          "Users"
        ]
      }
    },
    "/api/v1/users/{id}/unlock": {
      "post": {
        "operationId": "unlock-user",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Clear a sign-in lockout",
        "tags": [
          "Users"
        ]
      }
    },
    "/api/v1/webhooks": {
      "get": {
        "operationId": "list-webhooks",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemsWebhookViewBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Webhooks: generic (HMAC-signed JSON), Discord and e-mail",
        "tags": [
          "Notifications"
        ]
      },
      "post": {
        "description": "Generic webhooks receive the event as JSON with X-NGCP-Event, X-NGCP-Timestamp and, with a secret, X-NGCP-Signature: sha256=hex(HMAC-SHA256(secret, timestamp + \".\" + body)).",
        "operationId": "create-webhook",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookView"
                }
              }
            },
            "description": "Created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Add a webhook",
        "tags": [
          "Notifications"
        ]
      }
    },
    "/api/v1/webhooks/{id}": {
      "delete": {
        "operationId": "delete-webhook",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Remove a webhook",
        "tags": [
          "Notifications"
        ]
      },
      "put": {
        "operationId": "update-webhook",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookView"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Change a webhook (its kind stays)",
        "tags": [
          "Notifications"
        ]
      }
    },
    "/api/v1/webhooks/{id}/test": {
      "post": {
        "operationId": "test-webhook",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "int64",
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Send a test message (see the delivery log)",
        "tags": [
          "Notifications"
        ]
      }
    }
  },
  "security": [
    {
      "session": []
    },
    {
      "apiKey": []
    }
  ]
}
