{ "openapi": "3.1.0", "info": { "title": "MikroTik Backup System", "version": "0.0.1", "description": "Documentation for the live API. Use Authorize with your username and password or provide a Bearer token. Try it out performs real operations on the current instance. Registration is disabled by default. Accounts can access their own devices and backups; settings and logs are shared by operators." }, "servers": [ { "url": "/api", "description": "Current instance" } ], "tags": [ { "name": "Account" }, { "name": "Devices" }, { "name": "Backups" }, { "name": "Settings" }, { "name": "Logs" }, { "name": "System" } ], "security": [ { "BearerAuth": [] }, { "OAuth2PasswordBearer": [] } ], "paths": { "/auth/login": { "post": { "tags": [ "Account" ], "operationId": "login", "summary": "Log in", "description": "Accepts JSON and x-www-form-urlencoded forms. Login attempts are rate-limited per username.", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Token" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "security": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Login" }, "example": { "username": "admin", "password": "your-password" } }, "application/x-www-form-urlencoded": { "schema": { "$ref": "#/components/schemas/Login" } } } } } }, "/auth/register": { "post": { "tags": [ "Account" ], "operationId": "register", "summary": "Create an account", "description": "Requires ALLOW_REGISTRATION=true; returns 403 by default.", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "security": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Registration" } } } } } }, "/auth/me": { "get": { "tags": [ "Account" ], "operationId": "currentUser", "summary": "Current account", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/auth/preferences": { "put": { "tags": [ "Account" ], "operationId": "updatePreferences", "summary": "Update language and font", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Preferences" } } } } } }, "/auth/change-password": { "post": { "tags": [ "Account" ], "operationId": "changePassword", "summary": "Change password", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Message" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PasswordChange" } } } } } }, "/dashboard": { "get": { "tags": [ "System" ], "operationId": "dashboard", "summary": "Dashboard statistics", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Dashboard" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/health": { "get": { "tags": [ "System" ], "operationId": "health", "summary": "Application health", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Health" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "security": [] } }, "/routers": { "get": { "tags": [ "Devices" ], "operationId": "listDevices", "summary": "List your devices", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Device" } } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } }, "post": { "tags": [ "Devices" ], "operationId": "createDevice", "summary": "Add a device", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Device" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeviceCreate" }, "example": { "name": "switch-01", "device_type": "switchos", "host": "192.0.2.10", "port": 80, "use_global_switchos_credentials": true } } } } } }, "/routers/ping-statuses": { "get": { "tags": [ "Devices" ], "operationId": "pingDevices", "summary": "ICMP statuses", "description": "Missing host permissions for ICMP are reported as a per-device error, independently of SSH/HTTP connectivity.", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PingResults" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/routers/{id}": { "get": { "tags": [ "Devices" ], "operationId": "getDevice", "summary": "Device details", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Device" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 1 }, "description": "" } ] }, "put": { "tags": [ "Devices" ], "operationId": "updateDevice", "summary": "Update a device", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Device" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 1 }, "description": "" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeviceUpdate" }, "example": { "name": "switch-office" } } } } }, "delete": { "tags": [ "Devices" ], "operationId": "deleteDevice", "summary": "Delete a device and its backups", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Message" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 1 }, "description": "" } ] } }, "/routers/{id}/test-connection": { "get": { "tags": [ "Devices" ], "operationId": "testDevice", "summary": "Test the connection", "description": "RouterOS uses SSH. SwitchOS uses HTTP(S); backup_available includes validation of the downloaded file contents.", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConnectionResult" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 1 }, "description": "" } ] } }, "/backups": { "get": { "tags": [ "Backups" ], "operationId": "listBackups", "summary": "List backups", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Backup" } } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "parameters": [ { "name": "search", "in": "query", "required": false, "schema": { "type": "string" }, "description": "" }, { "name": "backup_type", "in": "query", "required": false, "schema": { "type": "string", "enum": [ "export", "binary" ] }, "description": "" }, { "name": "router_id", "in": "query", "required": false, "schema": { "type": "integer", "format": "int64", "minimum": 1 }, "description": "" }, { "name": "created_on", "in": "query", "required": false, "schema": { "type": "string", "format": "date" }, "description": "" }, { "name": "sort_by", "in": "query", "required": false, "schema": { "type": "string", "enum": [ "created_at", "file_name", "backup_type", "router_name" ], "default": "created_at" }, "description": "" }, { "name": "order", "in": "query", "required": false, "schema": { "type": "string", "enum": [ "asc", "desc" ], "default": "desc" }, "description": "" } ] } }, "/backups/router/{id}": { "get": { "tags": [ "Backups" ], "operationId": "deviceBackups", "summary": "Device backups", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Backup" } } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 1 }, "description": "" } ] } }, "/backups/router/{id}/export": { "post": { "tags": [ "Backups" ], "operationId": "createExport", "summary": "Create: RSC text export", "description": "Respects backup disable flags and the device lock. RSC exports are available only for RouterOS. The file and record are published after a successful transfer.", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Backup" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 1 }, "description": "" } ] } }, "/backups/routers/export-all": { "post": { "tags": [ "Backups" ], "operationId": "batchExport", "summary": "Batch operation: RSC text export", "description": "Returns a separate result for each device: ok, error, or skipped. Check each result for partial failures.", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/BatchResult" } } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/backups/router/{id}/binary": { "post": { "tags": [ "Backups" ], "operationId": "createBinary", "summary": "Create: RouterOS / SwitchOS binary backup", "description": "Respects backup disable flags and the device lock. RSC exports are available only for RouterOS. The file and record are published after a successful transfer.", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Backup" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 1 }, "description": "" } ] } }, "/backups/routers/binary-all": { "post": { "tags": [ "Backups" ], "operationId": "batchBinary", "summary": "Batch operation: RouterOS / SwitchOS binary backup", "description": "Returns a separate result for each device: ok, error, or skipped. Check each result for partial failures.", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/BatchResult" } } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/backups/router/{id}/upload/{backup_id}": { "post": { "tags": [ "Backups" ], "operationId": "uploadBackup", "summary": "Upload a binary backup to RouterOS", "description": "Transfers an existing file to the device. It does not restore the backup, run /system backup load, or reboot the device. Unavailable for SwitchOS.", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Message" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 1 }, "description": "" }, { "name": "backup_id", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 1 }, "description": "" } ] } }, "/backups/{id}": { "delete": { "tags": [ "Backups" ], "operationId": "deleteBackup", "summary": "Delete a backup", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Message" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 1 }, "description": "" } ] } }, "/backups/{id}/download": { "get": { "tags": [ "Backups" ], "operationId": "downloadBackup", "summary": "Download a file", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/octet-stream": { "schema": { "type": "string", "format": "binary" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 1 }, "description": "" } ] } }, "/backups/{id}/view": { "get": { "tags": [ "Backups" ], "operationId": "previewExport", "summary": "Preview an RSC export", "description": "Binary backups are rejected.", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BackupPreview" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 1 }, "description": "" } ] } }, "/backups/{id}/email": { "post": { "tags": [ "Backups" ], "operationId": "emailBackup", "summary": "Email a backup", "description": "Uses global SMTP settings. The recipient and sender must be configured.", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Message" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 1 }, "description": "" } ] } }, "/backups/{left}/diff/{right}": { "get": { "tags": [ "Backups" ], "operationId": "compareExports", "summary": "Compare two RSC exports", "description": "Both files must be text exports accessible to the current account. Limits: 100000 lines and 5 seconds of computation.", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Diff" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "parameters": [ { "name": "left", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 1 }, "description": "" }, { "name": "right", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 1 }, "description": "" } ] } }, "/backups/{left}/diff/{right}/html": { "get": { "tags": [ "Backups" ], "operationId": "compareExportsHtml", "summary": "Download an HTML comparison", "description": "", "responses": { "200": { "description": "Successful response", "content": { "text/html": { "schema": { "type": "string" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "parameters": [ { "name": "left", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 1 }, "description": "" }, { "name": "right", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 1 }, "description": "" } ] } }, "/backups/bulk": { "post": { "tags": [ "Backups" ], "operationId": "bulkBackups", "summary": "Download a ZIP or delete selected backups", "description": "1–1000 IDs; at most 2 GiB in total for a ZIP. Duplicate IDs are removed.", "responses": { "200": { "description": "download returns a ZIP; delete returns a JSON message. The entire list is authorized before execution.", "content": { "application/zip": { "schema": { "type": "string", "format": "binary" } }, "application/json": { "schema": { "$ref": "#/components/schemas/Message" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BulkRequest" }, "example": { "action": "download", "backup_ids": [ 1, 2 ] } } } } } }, "/settings": { "get": { "tags": [ "Settings" ], "operationId": "getSettings", "summary": "Get settings", "description": "Secrets remain masked; has_* fields indicate whether they are stored.", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Settings" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } }, "put": { "tags": [ "Settings" ], "operationId": "updateSettings", "summary": "Save settings", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Settings" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SettingsUpdate" }, "example": { "backup_retention_days": 7, "binary_cron": "0 2 * * *" } } } } } }, "/settings/scheduler-status": { "get": { "tags": [ "Settings" ], "operationId": "schedulerStatus", "summary": "Schedule and upcoming runs", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SchedulerStatus" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/settings/reveal-ssh-key": { "post": { "tags": [ "Settings" ], "operationId": "revealSshKey", "summary": "Reveal the global SSH key", "description": "Requires the current account password to be entered again.", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RevealedKey" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RevealKeyRequest" } } } } } }, "/settings/test-email": { "post": { "tags": [ "Settings" ], "operationId": "testEmail", "summary": "Send a test email", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Message" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/settings/test-pushover": { "post": { "tags": [ "Settings" ], "operationId": "testPushover", "summary": "Send a Pushover test", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Message" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/logs": { "get": { "tags": [ "Logs" ], "operationId": "listLogs", "summary": "Operation history", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Log" } } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "parameters": [ { "name": "limit", "in": "query", "required": false, "schema": { "type": "integer", "format": "int64", "minimum": 1, "maximum": 500, "default": 100 }, "description": "" } ] } }, "/logs/older-than/{days}": { "delete": { "tags": [ "Logs" ], "operationId": "deleteLogs", "summary": "Delete logs older than the specified number of days", "description": "", "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeletedLogs" } } } }, "400": { "description": "Invalid operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "401": { "description": "Missing or invalid token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Operation disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Resource unavailable to this account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "409": { "description": "Conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "413": { "description": "Size limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "422": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }, "text/plain": { "schema": { "type": "string", "description": "JSON, path/query parameter, or request content type error returned by the HTTP layer." } } } }, "429": { "description": "Attempt limit reached or resources busy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "500": { "description": "Internal error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "502": { "description": "Device or provider operation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "parameters": [ { "name": "days", "in": "path", "required": true, "schema": { "type": "integer", "format": "int64", "minimum": 1, "maximum": 36500 }, "description": "" } ] } } }, "components": { "schemas": { "Error": { "type": "object", "properties": { "detail": { "type": "string" } }, "required": [ "detail" ] }, "Message": { "type": "object", "properties": { "message": { "type": "string" } }, "required": [ "message" ] }, "User": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "username": { "type": "string" }, "preferred_language": { "type": "string", "enum": [ "pl", "en", "es", "no" ] }, "preferred_font": { "type": "string", "enum": [ "default", "adwaita_mono", "hack" ] } }, "required": [ "id", "username", "preferred_language", "preferred_font" ] }, "Login": { "type": "object", "properties": { "username": { "type": "string", "minLength": 1 }, "password": { "type": "string", "format": "password", "writeOnly": true, "minLength": 1 } }, "required": [ "username", "password" ] }, "Registration": { "type": "object", "properties": { "username": { "type": "string", "minLength": 3, "maxLength": 120 }, "password": { "type": "string", "format": "password", "writeOnly": true, "minLength": 4, "maxLength": 128 } }, "required": [ "username", "password" ] }, "Token": { "type": "object", "properties": { "access_token": { "type": "string" }, "token_type": { "type": "string", "enum": [ "bearer" ] }, "user": { "$ref": "#/components/schemas/User" } }, "required": [ "access_token", "token_type", "user" ] }, "Preferences": { "type": "object", "properties": { "preferred_language": { "type": "string", "enum": [ "pl", "en", "es", "no" ], "default": "pl" }, "preferred_font": { "type": "string", "enum": [ "default", "adwaita_mono", "hack" ], "default": "default" } } }, "PasswordChange": { "type": "object", "properties": { "current_password": { "type": "string", "format": "password", "writeOnly": true }, "new_password": { "type": "string", "format": "password", "writeOnly": true, "minLength": 4, "maxLength": 128 } }, "required": [ "current_password", "new_password" ] }, "DeviceCreate": { "type": "object", "properties": { "name": { "type": "string", "pattern": "^[A-Za-z0-9_-]{1,120}$", "description": "Technical device name." }, "device_type": { "type": "string", "enum": [ "routeros", "switchos" ], "default": "routeros" }, "host": { "type": "string", "maxLength": 255, "description": "IP address or hostname. SwitchOS also accepts an HTTP(S) origin without a path or credentials." }, "port": { "type": "integer", "format": "int64", "minimum": 1, "maximum": 65535, "description": "Defaults to 22 for RouterOS and 80 for SwitchOS. An explicit port in a SwitchOS URL takes precedence." }, "ssh_user": { "type": "string", "maxLength": 120, "description": "Device-specific username. Defaults to admin for RouterOS." }, "ssh_key": { "type": [ "string", "null" ], "writeOnly": true, "maxLength": 65536, "description": "RouterOS private key. An empty value preserves the stored secret." }, "ssh_password": { "type": [ "string", "null" ], "writeOnly": true, "maxLength": 1024, "description": "Device-specific password. An empty value preserves the stored secret." }, "use_global_switchos_credentials": { "type": [ "boolean", "null" ], "description": "SwitchOS: true uses only the global username/password pair; false uses only the device-specific pair. Omitted or null preserves the current mode on PUT and retains legacy per-field inheritance on POST. Switching modes preserves device-specific secrets." }, "clear_ssh_key": { "type": "boolean", "default": false }, "clear_ssh_password": { "type": "boolean", "default": false }, "disable_all_backups": { "type": "boolean", "default": false }, "disable_export_backups": { "type": "boolean", "default": false }, "disable_binary_backups": { "type": "boolean", "default": false }, "disable_ping": { "type": "boolean", "default": false } }, "required": [ "name", "host" ] }, "DeviceUpdate": { "type": "object", "properties": { "name": { "type": "string", "pattern": "^[A-Za-z0-9_-]{1,120}$", "description": "Technical device name." }, "device_type": { "type": "string", "enum": [ "routeros", "switchos" ] }, "host": { "type": "string", "maxLength": 255, "description": "IP address or hostname. SwitchOS also accepts an HTTP(S) origin without a path or credentials." }, "port": { "type": "integer", "format": "int64", "minimum": 1, "maximum": 65535, "description": "Defaults to 22 for RouterOS and 80 for SwitchOS. An explicit port in a SwitchOS URL takes precedence." }, "ssh_user": { "type": "string", "maxLength": 120, "description": "Device-specific username. Defaults to admin for RouterOS." }, "ssh_key": { "type": [ "string", "null" ], "writeOnly": true, "maxLength": 65536, "description": "RouterOS private key. An empty value preserves the stored secret." }, "ssh_password": { "type": [ "string", "null" ], "writeOnly": true, "maxLength": 1024, "description": "Device-specific password. An empty value preserves the stored secret." }, "use_global_switchos_credentials": { "type": [ "boolean", "null" ], "description": "SwitchOS: true uses only the global username/password pair; false uses only the device-specific pair. Omitted or null preserves the current mode on PUT and retains legacy per-field inheritance on POST. Switching modes preserves device-specific secrets." }, "clear_ssh_key": { "type": "boolean" }, "clear_ssh_password": { "type": "boolean" }, "disable_all_backups": { "type": "boolean" }, "disable_export_backups": { "type": "boolean" }, "disable_binary_backups": { "type": "boolean" }, "disable_ping": { "type": "boolean" } }, "description": "Partial update: omitted fields remain unchanged. Use the corresponding clear_* flag to remove a secret." }, "Device": { "type": "object", "properties": { "name": { "type": "string", "pattern": "^[A-Za-z0-9_-]{1,120}$", "description": "Technical device name." }, "device_type": { "type": "string", "enum": [ "routeros", "switchos" ], "default": "routeros" }, "host": { "type": "string", "maxLength": 255, "description": "IP address or hostname. SwitchOS also accepts an HTTP(S) origin without a path or credentials." }, "port": { "type": "integer", "format": "int64", "minimum": 1, "maximum": 65535, "description": "Defaults to 22 for RouterOS and 80 for SwitchOS. An explicit port in a SwitchOS URL takes precedence." }, "ssh_user": { "type": "string", "maxLength": 120, "description": "Device-specific username. Defaults to admin for RouterOS." }, "ssh_key": { "type": "null", "description": "Always null in public responses." }, "ssh_password": { "type": "null", "description": "Always null in public responses." }, "use_global_switchos_credentials": { "type": [ "boolean", "null" ], "description": "SwitchOS: true uses only the global username/password pair; false uses only the device-specific pair. Omitted or null preserves the current mode on PUT and retains legacy per-field inheritance on POST. Switching modes preserves device-specific secrets." }, "disable_all_backups": { "type": "boolean", "default": false }, "disable_export_backups": { "type": "boolean", "default": false }, "disable_binary_backups": { "type": "boolean", "default": false }, "disable_ping": { "type": "boolean", "default": false }, "id": { "type": "integer", "format": "int64" }, "owner_id": { "type": "integer", "format": "int64" }, "created_at": { "type": "string", "format": "date-time" }, "effective_username": { "type": [ "string", "null" ] }, "last_connection_status": { "type": [ "boolean", "null" ] }, "last_connection_backup_available": { "type": [ "boolean", "null" ] }, "last_connection_tested_at": { "type": [ "string", "null" ] }, "last_connection_error": { "type": [ "string", "null" ] }, "last_connection_hostname": { "type": [ "string", "null" ] }, "last_connection_model": { "type": [ "string", "null" ] }, "last_connection_version": { "type": [ "string", "null" ] }, "last_connection_uptime": { "type": [ "string", "null" ] }, "last_connection_transport": { "type": [ "string", "null" ] }, "last_connection_server": { "type": [ "string", "null" ] }, "last_connection_auth_mode": { "type": [ "string", "null" ] }, "last_connection_http_status": { "type": [ "string", "null" ] }, "has_own_password": { "type": "boolean" }, "uses_global_ssh_key": { "type": "boolean" }, "has_effective_ssh_key": { "type": "boolean" }, "uses_global_switchos_credentials": { "type": "boolean" }, "has_effective_password": { "type": "boolean" }, "supports_export": { "type": "boolean" }, "supports_restore_upload": { "type": "boolean" } }, "required": [ "id", "owner_id", "name", "device_type", "host", "port", "ssh_user" ] }, "ConnectionResult": { "type": "object", "properties": { "success": { "type": "boolean" }, "model": { "type": [ "string", "null" ] }, "hostname": { "type": [ "string", "null" ] }, "version": { "type": [ "string", "null" ] }, "uptime": { "type": [ "string", "null" ] }, "transport": { "type": "string", "enum": [ "ssh", "http" ] }, "auth_mode": { "type": [ "string", "null" ] }, "http_status": { "type": [ "string", "null" ] }, "server": { "type": [ "string", "null" ] }, "backup_available": { "type": [ "boolean", "null" ] }, "tested_at": { "type": "string", "format": "date-time" }, "error": { "type": [ "string", "null" ] } }, "required": [ "success" ] }, "PingStatus": { "type": "object", "properties": { "router_id": { "type": "integer", "format": "int64" }, "reachable": { "type": "boolean" }, "latency_ms": { "type": [ "number", "null" ] }, "disabled": { "type": "boolean" }, "error": { "type": "string" } }, "required": [ "router_id", "reachable", "disabled" ] }, "PingResults": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/PingStatus" } } }, "required": [ "items" ] }, "Backup": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "router_id": { "type": "integer", "format": "int64" }, "router_name": { "type": [ "string", "null" ] }, "device_type": { "type": "string", "enum": [ "routeros", "switchos" ] }, "file_path": { "type": "string", "description": "File path managed by the server. Operations do not accept it as input." }, "file_name": { "type": "string" }, "backup_type": { "type": "string", "enum": [ "export", "binary" ] }, "checksum": { "type": [ "string", "null" ], "description": "SHA-256 checksum of the file." }, "file_size": { "type": [ "integer", "null" ] }, "created_at": { "type": "string", "format": "date-time" } }, "required": [ "id", "router_id", "file_name", "backup_type", "created_at" ] }, "BackupPreview": { "type": "object", "properties": { "backup": { "$ref": "#/components/schemas/Backup" }, "content": { "type": "string" } }, "required": [ "backup", "content" ] }, "BatchResult": { "type": "object", "properties": { "router": { "type": "string" }, "status": { "type": "string", "enum": [ "ok", "error", "skipped" ] }, "backup_id": { "type": "integer", "format": "int64" }, "message": { "type": "string" } }, "required": [ "router", "status" ] }, "BulkRequest": { "type": "object", "properties": { "action": { "type": "string", "enum": [ "download", "delete" ] }, "backup_ids": { "type": "array", "minItems": 1, "maxItems": 1000, "items": { "type": "integer", "format": "int64", "minimum": 1 } } }, "required": [ "action", "backup_ids" ] }, "DiffLine": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "context", "added", "removed", "modified" ] }, "left_number": { "type": [ "integer", "null" ] }, "right_number": { "type": [ "integer", "null" ] }, "left_text": { "type": [ "string", "null" ] }, "right_text": { "type": [ "string", "null" ] } } }, "Diff": { "type": "object", "properties": { "left_backup_id": { "type": "integer", "format": "int64" }, "right_backup_id": { "type": "integer", "format": "int64" }, "left_file_name": { "type": "string" }, "right_file_name": { "type": "string" }, "diff_text": { "type": "string" }, "stats": { "type": "object", "properties": { "added": { "type": "integer", "format": "int64" }, "removed": { "type": "integer", "format": "int64" }, "modified": { "type": "integer", "format": "int64" }, "context": { "type": "integer", "format": "int64" } } }, "lines": { "type": "array", "items": { "$ref": "#/components/schemas/DiffLine" } } } }, "SettingsUpdate": { "type": "object", "properties": { "backup_retention_days": { "type": "integer", "format": "int64", "minimum": 0, "maximum": 36500, "description": "0 sets the retention age threshold to zero days; retention remains enabled." }, "log_retention_days": { "type": "integer", "format": "int64", "minimum": 0, "maximum": 36500 }, "export_cron": { "type": "string", "description": "Five-field cron expression; an empty string disables the job. 0=Monday, 6=Sunday; mon–sun names are recommended." }, "binary_cron": { "type": "string", "description": "Five-field cron expression or an empty string." }, "retention_cron": { "type": "string", "description": "Five-field cron expression or an empty string." }, "enable_auto_export": { "type": "boolean" }, "connection_test_interval_minutes": { "type": "integer", "format": "int64", "minimum": 0, "maximum": 1440 }, "global_ssh_key": { "type": [ "string", "null" ], "writeOnly": true }, "default_switchos_username": { "type": [ "string", "null" ], "maxLength": 120 }, "default_switchos_password": { "type": [ "string", "null" ], "writeOnly": true }, "pushover_token": { "type": [ "string", "null" ], "writeOnly": true }, "pushover_userkey": { "type": [ "string", "null" ], "writeOnly": true }, "notify_failures_only": { "type": "boolean" }, "smtp_host": { "type": [ "string", "null" ] }, "smtp_port": { "type": "integer", "format": "int64", "minimum": 1, "maximum": 65535 }, "smtp_login": { "type": [ "string", "null" ] }, "smtp_password": { "type": [ "string", "null" ], "writeOnly": true }, "smtp_notifications_enabled": { "type": "boolean" }, "recipient_email": { "type": [ "string", "null" ] }, "clear_global_ssh_key": { "type": "boolean" }, "clear_default_switchos_password": { "type": "boolean" }, "clear_pushover_token": { "type": "boolean" }, "clear_pushover_userkey": { "type": "boolean" }, "clear_smtp_password": { "type": "boolean" } }, "description": "Omitted fields remain unchanged. An empty or null secret preserves its value; clear_=true removes it. Schedule changes take effect without a restart." }, "Settings": { "type": "object", "properties": { "backup_retention_days": { "type": "integer", "format": "int64", "minimum": 0, "maximum": 36500, "default": 7, "description": "0 sets the retention age threshold to zero days; retention remains enabled." }, "log_retention_days": { "type": "integer", "format": "int64", "minimum": 0, "maximum": 36500, "default": 7 }, "export_cron": { "type": "string", "description": "Five-field cron expression; an empty string disables the job. 0=Monday, 6=Sunday; mon–sun names are recommended." }, "binary_cron": { "type": "string", "description": "Five-field cron expression or an empty string." }, "retention_cron": { "type": "string", "description": "Five-field cron expression or an empty string." }, "enable_auto_export": { "type": "boolean", "default": false }, "connection_test_interval_minutes": { "type": "integer", "format": "int64", "minimum": 0, "maximum": 1440, "default": 0 }, "global_ssh_key": { "type": "null", "description": "The stored secret is not returned." }, "default_switchos_username": { "type": [ "string", "null" ], "maxLength": 120 }, "default_switchos_password": { "type": "null", "description": "The stored secret is not returned." }, "pushover_token": { "type": "null", "description": "The stored secret is not returned." }, "pushover_userkey": { "type": "null", "description": "The stored secret is not returned." }, "notify_failures_only": { "type": "boolean", "default": true }, "smtp_host": { "type": [ "string", "null" ] }, "smtp_port": { "type": "integer", "format": "int64", "minimum": 1, "maximum": 65535, "default": 587 }, "smtp_login": { "type": [ "string", "null" ] }, "smtp_password": { "type": "null", "description": "The stored secret is not returned." }, "smtp_notifications_enabled": { "type": "boolean", "default": false }, "recipient_email": { "type": [ "string", "null" ] }, "has_global_ssh_key": { "type": "boolean" }, "has_default_switchos_password": { "type": "boolean" }, "has_pushover_token": { "type": "boolean" }, "has_pushover_userkey": { "type": "boolean" }, "has_smtp_password": { "type": "boolean" }, "id": { "type": "integer", "format": "int64" }, "has_default_switchos_credentials": { "type": "boolean" } } }, "RevealKeyRequest": { "type": "object", "properties": { "password": { "type": "string", "format": "password", "writeOnly": true } }, "required": [ "password" ] }, "RevealedKey": { "type": "object", "properties": { "global_ssh_key": { "type": [ "string", "null" ] } }, "required": [ "global_ssh_key" ] }, "SchedulerJob": { "type": "object", "properties": { "key": { "type": "string" }, "label": { "type": "string" }, "enabled": { "type": "boolean" }, "cron": { "type": [ "string", "null" ] }, "description": { "type": "string" }, "description_params": { "type": [ "object", "null" ] }, "valid": { "type": "boolean" }, "next_runs": { "type": "array", "items": { "type": "string", "format": "date-time" } }, "error": { "type": [ "string", "null" ] } } }, "SchedulerStatus": { "type": "object", "properties": { "timezone": { "type": "string" }, "running": { "type": "boolean" }, "jobs": { "type": "array", "items": { "$ref": "#/components/schemas/SchedulerJob" } } }, "required": [ "timezone", "running", "jobs" ] }, "Log": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "message": { "type": "string" }, "timestamp": { "type": "string", "format": "date-time" } }, "required": [ "id", "message", "timestamp" ] }, "DeletedLogs": { "type": "object", "properties": { "message": { "type": "string" }, "deleted": { "type": "integer", "format": "int64" } }, "required": [ "message", "deleted" ] }, "Health": { "type": "object", "properties": { "status": { "type": "string", "enum": [ "ok" ] }, "version": { "type": "string" }, "timestamp": { "type": "string", "format": "date-time" } }, "required": [ "status", "version", "timestamp" ] }, "Storage": { "type": "object", "properties": { "total": { "type": "integer", "format": "int64" }, "used": { "type": "integer", "format": "int64" }, "free": { "type": "integer", "format": "int64" }, "folder_used": { "type": "integer", "format": "int64" }, "usage_percent": { "type": "number" } }, "required": [ "total", "used", "free", "folder_used", "usage_percent" ] }, "Dashboard": { "type": "object", "properties": { "routers_count": { "type": "integer", "format": "int64" }, "export_count": { "type": "integer", "format": "int64" }, "binary_count": { "type": "integer", "format": "int64" }, "total_backups": { "type": "integer", "format": "int64" }, "storage": { "$ref": "#/components/schemas/Storage" }, "recent_logs": { "type": "array", "items": { "$ref": "#/components/schemas/Log" } } } } }, "securitySchemes": { "BearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT", "description": "The access_token returned by /auth/login." }, "OAuth2PasswordBearer": { "type": "oauth2", "flows": { "password": { "tokenUrl": "/api/auth/login", "scopes": {} } }, "description": "Sign in with the username and password of an existing account." } } } }