{ "openapi": "3.1.0", "info": { "title": "Homarr API documentation", "version": "1.1.0" }, "servers": [ { "url": "http://localhost:3000" } ], "externalDocs": { "url": "https://homarr.dev" }, "paths": { "/api/apps/paginated": { "get": { "operationId": "appRouter-getPaginated", "summary": "List apps with pagination", "description": "Return apps ordered by name with a total count. Supports a name filter and page controls. Requires app-modify-all permission.", "tags": [ "apps" ], "security": [ { "apikey": [] } ], "parameters": [ { "in": "query", "name": "search", "schema": { "type": "string" } }, { "in": "query", "name": "pageSize", "schema": { "default": 10, "type": "integer", "exclusiveMinimum": 0, "maximum": 100 } }, { "in": "query", "name": "page", "schema": { "default": 1, "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991 } } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "properties": { "items": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "iconUrl": { "type": "string" }, "href": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "pingUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] } }, "required": [ "id", "name", "description", "iconUrl", "href", "pingUrl" ], "additionalProperties": false } }, "totalCount": { "type": "number" } }, "required": [ "items", "totalCount" ], "additionalProperties": false } } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/apps": { "get": { "operationId": "appRouter-all", "summary": "List all apps", "description": "Return all apps ordered by name. Requires app-modify-all permission.", "tags": [ "apps" ], "security": [ { "apikey": [] } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "iconUrl": { "type": "string" }, "href": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "pingUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] } }, "required": [ "id", "name", "description", "iconUrl", "href", "pingUrl" ], "additionalProperties": false } } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } }, "post": { "operationId": "appRouter-create", "summary": "Create an app", "description": "Create an app bookmark. Requires app-create permission. Returns the app, including its ID and the legacy appId field. An empty pingUrl disables the custom ping URL.", "tags": [ "apps" ], "security": [ { "apikey": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 64 }, "description": { "anyOf": [ { "type": "string", "maxLength": 512 }, { "type": "null" } ] }, "iconUrl": { "type": "string", "minLength": 1 }, "href": { "anyOf": [ { "anyOf": [ { "type": "string" }, { "type": "string", "const": "" } ] }, { "type": "null" } ] }, "pingUrl": { "anyOf": [ { "anyOf": [ { "type": "string", "pattern": "^https?:\\/\\/" }, { "type": "string", "const": "" } ] }, { "type": "null" } ] } }, "required": [ "name", "description", "iconUrl", "href", "pingUrl" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "allOf": [ { "type": "object", "properties": { "appId": { "type": "string" } }, "required": [ "appId" ], "additionalProperties": false }, { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "iconUrl": { "type": "string" }, "href": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "pingUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] } }, "required": [ "id", "name", "description", "iconUrl", "href", "pingUrl" ], "additionalProperties": false } ] } } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/apps/search": { "get": { "operationId": "appRouter-search", "summary": "Search apps", "description": "Find apps whose names contain the query, ordered by name. Requires app-modify-all or board-modify-all permission; returns up to 100 results.", "tags": [ "apps" ], "security": [ { "apikey": [] } ], "parameters": [ { "in": "query", "name": "query", "schema": { "type": "string" }, "required": true }, { "in": "query", "name": "limit", "schema": { "default": 10, "type": "number", "minimum": 1, "maximum": 100 } } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "iconUrl": { "type": "string" }, "href": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "pingUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] } }, "required": [ "id", "name", "description", "iconUrl", "href", "pingUrl" ], "additionalProperties": false } } } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/apps/selectable": { "get": { "operationId": "appRouter-selectable", "summary": "List selectable apps", "description": "Return app IDs, names, icons, descriptions, destination URLs, and ping URLs for selection controls. Requires authentication.", "tags": [ "apps" ], "security": [ { "apikey": [] } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "iconUrl": { "type": "string" }, "href": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "pingUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ] } }, "required": [ "id", "name", "iconUrl", "href", "pingUrl", "description" ], "additionalProperties": false } } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/apps/{id}": { "get": { "operationId": "appRouter-byId", "summary": "Get an app", "description": "Return an app by ID. Signed-in users can access all apps; anonymous access is limited to apps placed on public boards. Missing or inaccessible apps return not found.", "tags": [ "apps" ], "security": [ {}, { "apikey": [] } ], "parameters": [ { "in": "path", "name": "id", "schema": { "type": "string" }, "required": true } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "iconUrl": { "type": "string" }, "href": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "pingUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] } }, "required": [ "id", "name", "description", "iconUrl", "href", "pingUrl" ], "additionalProperties": false } } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } }, "patch": { "operationId": "appRouter-update", "summary": "Update an app", "description": "Update an app by ID. Requires app-modify-all permission. Supply all required app fields; an empty pingUrl clears the custom ping URL. Changing href invalidates linked integration caches.", "tags": [ "apps" ], "security": [ { "apikey": [] } ], "parameters": [ { "in": "path", "name": "id", "schema": { "type": "string" }, "required": true } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 64 }, "description": { "anyOf": [ { "type": "string", "maxLength": 512 }, { "type": "null" } ] }, "iconUrl": { "type": "string", "minLength": 1 }, "href": { "anyOf": [ { "anyOf": [ { "type": "string" }, { "type": "string", "const": "" } ] }, { "type": "null" } ] }, "pingUrl": { "anyOf": [ { "anyOf": [ { "type": "string", "pattern": "^https?:\\/\\/" }, { "type": "string", "const": "" } ] }, { "type": "null" } ] } }, "required": [ "name", "description", "iconUrl", "href", "pingUrl" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } }, "delete": { "operationId": "appRouter-delete", "summary": "Delete an app", "description": "Delete an app by ID and invalidate linked integration caches. Requires app-full-all permission.", "tags": [ "apps" ], "security": [ { "apikey": [] } ], "parameters": [ { "in": "path", "name": "id", "schema": { "type": "string" }, "required": true } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/boards": { "get": { "operationId": "boardRouter-getAllBoards", "summary": "List accessible boards", "description": "Return accessible boards with creator details, visibility, and the current user's desktop and mobile home flags. Anonymous callers can see public boards.", "tags": [ "boards" ], "security": [ {}, { "apikey": [] } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "logoImageUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "isPublic": { "type": "boolean" }, "creator": { "anyOf": [ { "type": "object", "properties": { "id": { "type": "string" }, "name": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "image": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "email": { "anyOf": [ { "type": "string" }, { "type": "null" } ] } }, "required": [ "id", "name", "image", "email" ], "additionalProperties": false }, { "type": "null" } ] }, "isHome": { "type": "boolean" }, "isMobileHome": { "type": "boolean" }, "userPermissions": { "type": "array", "items": { "type": "object", "properties": { "permission": { "type": "string", "enum": [ "view", "modify", "full" ] } }, "required": [ "permission" ], "additionalProperties": false } }, "groupPermissions": { "type": "array", "items": { "type": "object", "properties": { "permission": { "type": "string", "enum": [ "view", "modify", "full" ] } }, "required": [ "permission" ], "additionalProperties": false } } }, "required": [ "id", "name", "logoImageUrl", "isPublic", "creator", "isHome", "isMobileHome", "userPermissions", "groupPermissions" ], "additionalProperties": false } } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } }, "post": { "operationId": "boardRouter-createBoard", "summary": "Create a board", "description": "Create a board with base and mobile layouts. Requires board-create permission. Returns the board ID, name, and base layout ID; sets the creator's home board if none is selected.", "tags": [ "boards" ], "security": [ { "apikey": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 255, "pattern": "^[A-Za-z0-9-_]*$" }, "columnCount": { "type": "number", "minimum": 1, "maximum": 24 }, "isPublic": { "type": "boolean" } }, "required": [ "name", "columnCount", "isPublic" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "properties": { "boardId": { "type": "string" }, "name": { "type": "string" }, "layoutId": { "type": "string" } }, "required": [ "boardId", "name", "layoutId" ], "additionalProperties": false } } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/boards/{id}/duplicate": { "post": { "operationId": "boardRouter-duplicateBoard", "summary": "Duplicate a board", "description": "Copy a board under a unique name and return its new ID. Requires board-create permission, view access to the source, and use access to its linked integrations. Widget configurations must be valid; boards containing Custom Widgets require admin permission.", "tags": [ "boards" ], "security": [ { "apikey": [] } ], "parameters": [ { "in": "path", "name": "id", "schema": { "type": "string" }, "required": true } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 255, "pattern": "^[A-Za-z0-9-_]*$" } }, "required": [ "name" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "properties": { "boardId": { "type": "string" } }, "required": [ "boardId" ], "additionalProperties": false } } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/boards/{id}/name": { "patch": { "operationId": "boardRouter-renameBoard", "summary": "Rename a board", "description": "Change a board's name to a unique name. Requires full access to the board.", "tags": [ "boards" ], "security": [ { "apikey": [] } ], "parameters": [ { "in": "path", "name": "id", "schema": { "type": "string" }, "required": true } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 255, "pattern": "^[A-Za-z0-9-_]*$" } }, "required": [ "name" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/boards/{id}/visibility": { "patch": { "operationId": "boardRouter-changeBoardVisibility", "summary": "Change board visibility", "description": "Make a board public or private. Requires full access to the board. A board selected as an instance desktop or mobile home board cannot be made private.", "tags": [ "boards" ], "security": [ { "apikey": [] } ], "parameters": [ { "in": "path", "name": "id", "schema": { "type": "string" }, "required": true } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "visibility": { "type": "string", "enum": [ "public", "private" ] } }, "required": [ "visibility" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/boards/{id}": { "delete": { "operationId": "boardRouter-deleteBoard", "summary": "Delete a board", "description": "Delete a board by ID. Requires full access to the board.", "tags": [ "boards" ], "security": [ { "apikey": [] } ], "parameters": [ { "in": "path", "name": "id", "schema": { "type": "string" }, "required": true } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/boards/{id}/home": { "patch": { "operationId": "boardRouter-setHomeBoard", "summary": "Set your desktop home board", "description": "Select the current user's desktop home board. Requires view access to the board.", "tags": [ "boards" ], "security": [ { "apikey": [] } ], "parameters": [ { "in": "path", "name": "id", "schema": { "type": "string" }, "required": true } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/boards/{id}/mobile-home": { "patch": { "operationId": "boardRouter-setMobileHomeBoard", "summary": "Set your mobile home board", "description": "Select the current user's mobile home board. Requires view access to the board.", "tags": [ "boards" ], "security": [ { "apikey": [] } ], "parameters": [ { "in": "path", "name": "id", "schema": { "type": "string" }, "required": true } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/boards/{id}/settings": { "patch": { "operationId": "boardRouter-savePartialBoardSettings", "summary": "Update board settings", "description": "Update the supplied appearance, metadata, background, custom CSS, or status settings. Omitted settings remain unchanged. Requires modify access to the board.", "tags": [ "boards" ], "security": [ { "apikey": [] } ], "parameters": [ { "in": "path", "name": "id", "schema": { "type": "string" }, "required": true } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "pageTitle": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "metaTitle": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "logoImageUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "faviconImageUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "backgroundImageUrl": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "backgroundImageAttachment": { "type": "string", "enum": [ "fixed", "scroll" ] }, "backgroundImageRepeat": { "type": "string", "enum": [ "repeat", "repeat-x", "repeat-y", "no-repeat" ] }, "backgroundImageSize": { "type": "string", "enum": [ "cover", "contain" ] }, "primaryColor": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" }, "secondaryColor": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" }, "opacity": { "type": "number", "minimum": 0, "maximum": 100 }, "customCss": { "type": "string", "maxLength": 16384 }, "iconColor": { "anyOf": [ { "anyOf": [ { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" }, { "type": "string", "const": "" } ] }, { "type": "null" } ] }, "itemRadius": { "anyOf": [ { "type": "string", "const": "xs" }, { "type": "string", "const": "sm" }, { "type": "string", "const": "md" }, { "type": "string", "const": "lg" }, { "type": "string", "const": "xl" } ] }, "disableStatus": { "type": "boolean" } } } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/boards/items": { "post": { "operationId": "boardRouter-addItem", "summary": "Add an item to a board", "description": "Add a widget or app to the first available position in the main canvas of each layout and return its item ID. Requires modify access to the board and use access to linked integrations. Widget configurations must be valid; placing Custom Widgets requires admin permission.", "tags": [ "boards" ], "security": [ { "apikey": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "boardId": { "type": "string" }, "kind": { "type": "string", "enum": [ "stats", "clock", "weather", "airQuality", "countdown", "timer", "app", "iframe", "video", "notebook", "anchorNote", "dnsHoleSummary", "dnsHoleControls", "smartHome-entityState", "smartHome-executeAutomation", "stockPrice", "mediaServer", "calendar", "downloads", "mediaRequests-requestList", "mediaRequests-requestStats", "mediaTranscoding", "mediaMissing", "minecraftServerStatus", "networkControllerSummary", "networkControllerStatus", "rssFeed", "bookmarks", "indexerManager", "healthMonitoring", "releases", "mediaReleases", "dockerContainers", "firewall", "notifications", "systemResources", "coolify", "systemDisks", "timetable", "immich-serverStats", "immich-albumCarousel", "paperlessNgx", "patchmon", "bazarr", "tracearr", "speedtestTracker", "uptimeKuma", "audioStats", "umami", "vpn", "archiveTeamWarrior", "ups", "beszelSystemTable", "beszelSystemGrid", "beszelAlerts", "beszelSystemStats", "traefik", "customApi", "assistant", "wud", "llamacpp", "wazuhAgents", "wazuhAlerts", "wazuhSummary", "wazuhTimeline", "wazuhTopList", "wazuhVulnerabilities", "wazuhFim", "wazuhAuthFailures" ] }, "options": { "default": {}, "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": {} }, "size": { "type": "object", "properties": { "width": { "type": "integer", "minimum": 1, "maximum": 24 }, "height": { "type": "integer", "minimum": 1, "maximum": 24 } }, "required": [ "width", "height" ] }, "integrationIds": { "default": [], "maxItems": 32, "type": "array", "items": { "type": "string" } } }, "required": [ "boardId", "kind" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "properties": { "itemId": { "type": "string" } }, "required": [ "itemId" ], "additionalProperties": false } } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/boards/{boardId}/items/{itemId}/layouts/{layoutId}": { "patch": { "operationId": "boardRouter-updateItemLayout", "summary": "Move or resize one board item", "description": "Update one item's position and size in one existing layout without replacing the board. Requires modify access. The item stays in its current section; out-of-bounds and overlapping placements are rejected.", "tags": [ "boards" ], "security": [ { "apikey": [] } ], "parameters": [ { "in": "path", "name": "boardId", "schema": { "type": "string" }, "required": true }, { "in": "path", "name": "itemId", "schema": { "type": "string" }, "required": true }, { "in": "path", "name": "layoutId", "schema": { "type": "string" }, "required": true } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "xOffset": { "type": "integer", "minimum": 0, "maximum": 32767 }, "yOffset": { "type": "integer", "minimum": 0, "maximum": 32767 }, "width": { "type": "integer", "minimum": 1, "maximum": 24 }, "height": { "type": "integer", "minimum": 1, "maximum": 24 } }, "required": [ "xOffset", "yOffset", "width", "height" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "properties": { "boardId": { "type": "string" }, "itemId": { "type": "string" }, "layoutId": { "type": "string" }, "xOffset": { "type": "integer", "minimum": 0, "maximum": 32767 }, "yOffset": { "type": "integer", "minimum": 0, "maximum": 32767 }, "width": { "type": "integer", "minimum": 1, "maximum": 24 }, "height": { "type": "integer", "minimum": 1, "maximum": 24 } }, "required": [ "boardId", "itemId", "layoutId", "xOffset", "yOffset", "width", "height" ], "additionalProperties": false } } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/info": { "get": { "operationId": "infoRouter-getInfo", "summary": "Get server information", "description": "Return the Homarr server version. Requires authentication.", "tags": [ "info" ], "security": [ { "apikey": [] } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "properties": { "version": { "type": "string" } }, "required": [ "version" ], "additionalProperties": false } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/invites": { "get": { "operationId": "inviteRouter-getAll", "summary": "List user invitations", "description": "Return invitations with their expiration dates and creators, ordered by expiration. Invite tokens are excluded. Requires admin permission and credentials authentication to be enabled.", "tags": [ "invites" ], "security": [ { "apikey": [] } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "expirationDate": { "type": "string" }, "creator": { "type": "object", "properties": { "name": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "id": { "type": "string" } }, "required": [ "name", "id" ], "additionalProperties": false } }, "required": [ "id", "expirationDate", "creator" ], "additionalProperties": false } } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } }, "post": { "operationId": "inviteRouter-createInvite", "summary": "Create a user invitation", "description": "Create a single-use invitation with the supplied expiration date and return its ID and registration token. Requires admin permission and credentials authentication to be enabled.", "tags": [ "invites" ], "security": [ { "apikey": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "expirationDate": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$" } }, "required": [ "expirationDate" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string" }, "token": { "type": "string" } }, "required": [ "id", "token" ], "additionalProperties": false } } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/invites/{id}": { "delete": { "operationId": "inviteRouter-deleteInvite", "summary": "Delete a user invitation", "description": "Revoke an invitation by ID. Requires admin permission and credentials authentication to be enabled. Returns not found if the invitation does not exist.", "tags": [ "invites" ], "security": [ { "apikey": [] } ], "parameters": [ { "in": "path", "name": "id", "schema": { "type": "string" }, "required": true } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "not": {} } } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/settings/board": { "get": { "operationId": "serverSettingsRouter-getBoardSettings", "summary": "Get global board settings", "description": "Return instance desktop and mobile home board IDs and default status behavior. Requires admin permission.", "tags": [ "settings" ], "security": [ { "apikey": [] } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "properties": { "homeBoardId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "mobileHomeBoardId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "enableStatusByDefault": { "type": "boolean" }, "forceDisableStatus": { "type": "boolean" } }, "required": [ "homeBoardId", "mobileHomeBoardId", "enableStatusByDefault", "forceDisableStatus" ], "additionalProperties": false } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } }, "patch": { "operationId": "serverSettingsRouter-updateBoardSettings", "summary": "Update global board settings", "description": "Update supplied instance board defaults and return the resulting settings. Home board IDs must reference public boards, or be null to clear the default. Requires admin permission.", "tags": [ "settings" ], "security": [ { "apikey": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "homeBoardId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "mobileHomeBoardId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "enableStatusByDefault": { "type": "boolean" }, "forceDisableStatus": { "type": "boolean" } } } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "properties": { "homeBoardId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "mobileHomeBoardId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "enableStatusByDefault": { "type": "boolean" }, "forceDisableStatus": { "type": "boolean" } }, "required": [ "homeBoardId", "mobileHomeBoardId", "enableStatusByDefault", "forceDisableStatus" ], "additionalProperties": false } } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/users": { "post": { "operationId": "userRouter-create", "summary": "Create a user", "description": "Create a credentials account and assign the supplied groups. Requires admin permission and credentials authentication to be enabled. The username must be unique and password confirmation must match.", "tags": [ "users" ], "security": [ { "apikey": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "username": { "type": "string", "minLength": 3, "maxLength": 255 }, "password": { "type": "string", "minLength": 8, "maxLength": 255 }, "confirmPassword": { "type": "string" }, "email": { "anyOf": [ { "type": "string", "format": "email", "pattern": "^[^\\s@\"]{1,64}@[^\\s@]{1,255}$" }, { "type": "string", "minLength": 0, "maxLength": 0 } ] }, "groupIds": { "type": "array", "items": { "type": "string" } } }, "required": [ "username", "password", "confirmPassword", "groupIds" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } }, "get": { "operationId": "userRouter-getAll", "summary": "List all users", "description": "Return user IDs, names, email addresses, verification dates, and profile images. Requires admin permission.", "tags": [ "users" ], "security": [ { "apikey": [] } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "email": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "emailVerified": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "image": { "anyOf": [ { "type": "string" }, { "type": "null" } ] } }, "required": [ "id", "name", "email", "emailVerified", "image" ], "additionalProperties": false } } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/users/profileImage": { "put": { "operationId": "userRouter-setProfileImage", "summary": "Set a profile image", "description": "Set a user's image to a base64 PNG, JPEG, GIF, or WebP data URL, or null to clear it. The data URL is limited to 350,000 characters. Users can update themselves; updating another user requires admin permission.", "tags": [ "users" ], "security": [ { "apikey": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "userId": { "type": "string" }, "image": { "anyOf": [ { "type": "string", "maxLength": 350000, "pattern": "^data:image\\/(png|jpeg|gif|webp);base64,[A-Za-z0-9/+]+=*$" }, { "type": "null" } ] } }, "required": [ "userId", "image" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/users/selectable": { "get": { "operationId": "userRouter-selectable", "summary": "List selectable users", "description": "Return user IDs, names, profile images, and email addresses for selection controls, optionally filtered by authentication provider. Requires authentication.", "tags": [ "users" ], "security": [ { "apikey": [] } ], "parameters": [ { "in": "query", "name": "providers", "schema": { "type": "array", "items": { "type": "string", "enum": [ "credentials", "oidc", "ldap" ] } } } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "image": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "email": { "anyOf": [ { "type": "string" }, { "type": "null" } ] } }, "required": [ "id", "name", "image", "email" ], "additionalProperties": false } } } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/users/search": { "post": { "operationId": "userRouter-search", "summary": "Search users", "description": "Find users whose names contain the query. Returns IDs, names, profile images, and email addresses, with up to 100 results. Requires admin permission.", "tags": [ "users" ], "security": [ { "apikey": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "query": { "type": "string" }, "limit": { "default": 10, "type": "number", "minimum": 1, "maximum": 100 } }, "required": [ "query" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "image": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "email": { "anyOf": [ { "type": "string" }, { "type": "null" } ] } }, "required": [ "id", "name", "image", "email" ], "additionalProperties": false } } } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/users/{userId}": { "get": { "operationId": "userRouter-getById", "summary": "Get a user", "description": "Return a user's profile, authentication provider, and preferences. Users can read themselves; reading another user requires admin permission.", "tags": [ "users" ], "security": [ { "apikey": [] } ], "parameters": [ { "in": "path", "name": "userId", "schema": { "type": "string" }, "required": true } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "email": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "emailVerified": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "image": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "provider": { "type": "string" }, "homeBoardId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "mobileHomeBoardId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "byteUnitSystem": { "type": "string", "enum": [ "binary", "decimal" ] }, "firstDayOfWeek": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, "pingIconsEnabled": { "type": "boolean" }, "enableRightClickOnWidgets": { "type": "boolean" }, "headerPreferences": { "type": "string" }, "defaultSearchEngineId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "openSearchInNewTab": { "type": "boolean" }, "ddgBangs": { "type": "boolean" }, "completedManageTour": { "type": "boolean" }, "completedBoardTour": { "type": "boolean" } }, "required": [ "id", "name", "email", "emailVerified", "image", "provider", "homeBoardId", "mobileHomeBoardId", "byteUnitSystem", "firstDayOfWeek", "pingIconsEnabled", "enableRightClickOnWidgets", "headerPreferences", "defaultSearchEngineId", "openSearchInNewTab", "ddgBangs", "completedManageTour", "completedBoardTour" ], "additionalProperties": false } } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } }, "delete": { "operationId": "userRouter-delete", "summary": "Delete a user", "description": "Delete a user account. Users can delete themselves; deleting another user requires admin permission. Disabled in demo mode.", "tags": [ "users" ], "security": [ { "apikey": [] } ], "parameters": [ { "in": "path", "name": "userId", "schema": { "type": "string" }, "required": true } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/users/profile": { "put": { "operationId": "userRouter-editProfile", "summary": "Update a user profile", "description": "Update a credentials account's username and email. Users can update themselves; updating another user requires admin permission. External-provider profiles cannot be edited, and username changes are disabled in demo mode.", "tags": [ "users" ], "security": [ { "apikey": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string", "minLength": 3, "maxLength": 255 }, "email": { "anyOf": [ { "anyOf": [ { "type": "string", "format": "email", "pattern": "^[^\\s@\"]{1,64}@[^\\s@]{1,255}$" }, { "type": "string", "const": "" } ] }, { "type": "null" } ] } }, "required": [ "id", "name" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/users/{userId}/changePassword": { "patch": { "operationId": "userRouter-changePassword", "summary": "Change a user password", "description": "Change a credentials account's password. Changing your own password requires the previous password, including for admins. Admins can reset another user's password without verifying their previous password. Disabled in demo mode.", "tags": [ "users" ], "security": [ { "apikey": [] } ], "parameters": [ { "in": "path", "name": "userId", "schema": { "type": "string" }, "required": true } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "previousPassword": { "type": "string", "minLength": 1 }, "password": { "type": "string", "minLength": 8, "maxLength": 255 }, "confirmPassword": { "type": "string" } }, "required": [ "previousPassword", "password", "confirmPassword" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/users/changeHome": { "patch": { "operationId": "userRouter-changeHomeBoards", "summary": "Change user home boards", "description": "Set or clear a user's desktop and mobile home boards. The caller must be able to view each selected board. Users can update themselves; updating another user requires admin permission.", "tags": [ "users" ], "security": [ { "apikey": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "homeBoardId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "mobileHomeBoardId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }, "userId": { "type": "string" } }, "required": [ "homeBoardId", "mobileHomeBoardId", "userId" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/users/changeSearchEngine": { "patch": { "operationId": "userRouter-changeDefaultSearchEngine", "summary": "Change the default search engine", "description": "Deprecated: use PATCH /api/users/search-preferences instead. Updates the default search engine and supplied DuckDuckGo bang preference while preserving the new-tab preference. Users can update themselves; updating another user requires admin permission.", "tags": [ "users" ], "security": [ { "apikey": [] } ], "deprecated": true, "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "defaultSearchEngineId": { "anyOf": [ { "type": "string", "minLength": 1 }, { "type": "null" } ] }, "ddgBangsEnabled": { "type": "boolean" }, "userId": { "type": "string" } }, "required": [ "defaultSearchEngineId", "ddgBangsEnabled", "userId" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/users/search-preferences": { "patch": { "operationId": "userRouter-changeSearchPreferences", "summary": "Update search preferences", "description": "Set a user's default search engine, new-tab behavior, and DuckDuckGo bang preference. Users can update themselves; updating another user requires admin permission.", "tags": [ "users" ], "security": [ { "apikey": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "defaultSearchEngineId": { "anyOf": [ { "type": "string", "minLength": 1 }, { "type": "null" } ] }, "openInNewTab": { "type": "boolean" }, "ddgBangsEnabled": { "type": "boolean" }, "userId": { "type": "string" } }, "required": [ "defaultSearchEngineId", "openInNewTab", "ddgBangsEnabled", "userId" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/users/changeScheme": { "patch": { "operationId": "userRouter-changeColorScheme", "summary": "Change your color scheme", "description": "Set the current user's preferred color scheme. Requires authentication.", "tags": [ "users" ], "security": [ { "apikey": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "colorScheme": { "type": "string", "enum": [ "auto", "light", "dark" ] } }, "required": [ "colorScheme" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/users/right-click-widgets": { "patch": { "operationId": "userRouter-changeEnableRightClickOnWidgets", "summary": "Change widget context menu behavior", "description": "Enable or disable opening widget context menus with a right click for a user. Users can update themselves; updating another user requires admin permission.", "tags": [ "users" ], "security": [ { "apikey": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "enableRightClickOnWidgets": { "type": "boolean" }, "id": { "type": "string" } }, "required": [ "enableRightClickOnWidgets", "id" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/users/header-preferences": { "patch": { "operationId": "userRouter-changeHeaderPreferences", "summary": "Update header preferences", "description": "Replace a user's header layout and display preferences. New board shortcuts must reference boards the target user can view; existing shortcuts may be retained. Users can update themselves; updating another user requires admin permission.", "tags": [ "users" ], "security": [ { "apikey": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string" }, "headerPreferences": { "oneOf": [ { "type": "object", "properties": { "version": { "type": "number", "const": 3 }, "visible": { "type": "boolean" }, "searchDisplay": { "type": "string", "enum": [ "input", "icon" ] }, "logoDisplay": { "default": "logoAndText", "type": "string", "enum": [ "logo", "logoAndText" ] }, "zones": { "type": "object", "properties": { "left": { "maxItems": 100, "type": "array", "items": { "oneOf": [ { "type": "object", "properties": { "type": { "type": "string", "const": "builtin" }, "id": { "type": "string", "enum": [ "logo", "search", "home", "boardSwitcher", "assistant", "docker", "boardEdit", "boardSettings", "settings", "themeToggle", "user" ] } }, "required": [ "type", "id" ], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "board" }, "boardId": { "type": "string", "minLength": 1, "maxLength": 255 } }, "required": [ "type", "boardId" ], "additionalProperties": false } ], "type": "object" } }, "center": { "maxItems": 100, "type": "array", "items": { "oneOf": [ { "type": "object", "properties": { "type": { "type": "string", "const": "builtin" }, "id": { "type": "string", "enum": [ "logo", "search", "home", "boardSwitcher", "assistant", "docker", "boardEdit", "boardSettings", "settings", "themeToggle", "user" ] } }, "required": [ "type", "id" ], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "board" }, "boardId": { "type": "string", "minLength": 1, "maxLength": 255 } }, "required": [ "type", "boardId" ], "additionalProperties": false } ], "type": "object" } }, "right": { "maxItems": 100, "type": "array", "items": { "oneOf": [ { "type": "object", "properties": { "type": { "type": "string", "const": "builtin" }, "id": { "type": "string", "enum": [ "logo", "search", "home", "boardSwitcher", "assistant", "docker", "boardEdit", "boardSettings", "settings", "themeToggle", "user" ] } }, "required": [ "type", "id" ], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "board" }, "boardId": { "type": "string", "minLength": 1, "maxLength": 255 } }, "required": [ "type", "boardId" ], "additionalProperties": false } ], "type": "object" } } }, "required": [ "left", "center", "right" ], "additionalProperties": false } }, "required": [ "version", "visible", "searchDisplay", "zones" ], "additionalProperties": false }, { "type": "object", "properties": { "version": { "type": "number", "const": 1 }, "visible": { "type": "boolean" }, "items": { "minItems": 1, "maxItems": 6, "type": "array", "items": { "type": "string", "enum": [ "logo", "search", "boardSwitcher", "assistant", "docker", "user" ] } } }, "required": [ "version", "visible", "items" ], "additionalProperties": false }, { "type": "object", "properties": { "version": { "type": "number", "const": 2 }, "visible": { "type": "boolean" }, "zones": { "type": "object", "properties": { "left": { "maxItems": 6, "type": "array", "items": { "type": "string", "enum": [ "logo", "search", "boardSwitcher", "assistant", "docker", "user" ] } }, "center": { "maxItems": 6, "type": "array", "items": { "type": "string", "enum": [ "logo", "search", "boardSwitcher", "assistant", "docker", "user" ] } }, "right": { "maxItems": 6, "type": "array", "items": { "type": "string", "enum": [ "logo", "search", "boardSwitcher", "assistant", "docker", "user" ] } } }, "required": [ "left", "center", "right" ], "additionalProperties": false } }, "required": [ "version", "visible", "zones" ], "additionalProperties": false } ], "type": "object" } }, "required": [ "id", "headerPreferences" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/users/ddg-bangs": { "patch": { "operationId": "userRouter-changeDdgBangs", "summary": "Change DuckDuckGo bang behavior", "description": "Deprecated: use PATCH /api/users/search-preferences instead. Enable or disable DuckDuckGo bangs for a user. Users can update themselves; updating another user requires admin permission.", "tags": [ "users" ], "security": [ { "apikey": [] } ], "deprecated": true, "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "ddgBangs": { "type": "boolean" }, "id": { "type": "string" } }, "required": [ "ddgBangs", "id" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/users/firstDayOfWeek": { "patch": { "operationId": "userRouter-changeFirstDayOfWeek", "summary": "Change the first day of the week", "description": "Set a user's preferred first day of the week. Users can update themselves; updating another user requires admin permission.", "tags": [ "users" ], "security": [ { "apikey": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "firstDayOfWeek": { "type": "number", "minimum": 0, "maximum": 6 }, "id": { "type": "string" } }, "required": [ "firstDayOfWeek", "id" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": {} } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/certificates/{fileName}": { "get": { "operationId": "certificates-getCertificate", "summary": "Inspect a named custom root CA certificate", "description": "Return public metadata or null when absent. Requires admin permission. Does not return PEM contents.", "tags": [ "certificates" ], "security": [ { "apikey": [] } ], "parameters": [ { "in": "path", "name": "fileName", "schema": { "type": "string", "maxLength": 128, "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]*\\.(crt|pem)$" }, "required": true } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "anyOf": [ { "type": "object", "properties": { "fileName": { "type": "string", "maxLength": 128, "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]*\\.(crt|pem)$" }, "sha256": { "type": "string" }, "fingerprint256": { "type": "string" }, "ca": { "type": "boolean", "const": true }, "validFrom": { "type": "string" }, "validTo": { "type": "string" } }, "required": [ "fileName", "sha256", "fingerprint256", "ca", "validFrom", "validTo" ], "additionalProperties": false }, { "type": "null" } ] } } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/certificates/root": { "post": { "operationId": "certificates-ensureRootCertificate", "summary": "Ensure a named custom root CA certificate without overwriting", "description": "Accept one currently valid self-signed PEM root CA (64 KiB maximum). Identical bytes are idempotent; different existing bytes return CONFLICT. Requires admin permission.", "tags": [ "certificates" ], "security": [ { "apikey": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "fileName": { "type": "string", "maxLength": 128, "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]*\\.(crt|pem)$" }, "certificate": { "type": "string", "minLength": 1, "maxLength": 65536 } }, "required": [ "fileName", "certificate" ] } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "properties": { "created": { "type": "boolean" }, "certificate": { "type": "object", "properties": { "fileName": { "type": "string", "maxLength": 128, "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]*\\.(crt|pem)$" }, "sha256": { "type": "string" }, "fingerprint256": { "type": "string" }, "ca": { "type": "boolean", "const": true }, "validFrom": { "type": "string" }, "validTo": { "type": "string" } }, "required": [ "fileName", "sha256", "fingerprint256", "ca", "validFrom", "validTo" ], "additionalProperties": false } }, "required": [ "created", "certificate" ], "additionalProperties": false } } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/integrations/request": { "post": { "operationId": "integration-request", "summary": "Proxy an integration API request using saved credentials", "description": "REST access to integration_request, Homarr's most powerful MCP tool. Call any API endpoint on a supported saved integration using its authentication and trusted certificates. Features not implemented in Homarr can still be used through this API or MCP if the upstream API supports them. Supply exactly one selector: integrationId, integrationName or integrationKind. Requires full integration access; DELETE also requires confirmed=true after user confirmation. Paths append to the saved URL. HTTP 200 can contain upstream errors: inspect ok, status and data. Limits: 10 KiB body, 16 KiB headers, 1 MiB response, 15 seconds. See https://homarr.dev/docs/management/api#call-any-integration-api-endpoint for the full contract.", "tags": [ "integrations" ], "security": [ { "apikey": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "integrationId": { "description": "Saved integration ID from integration_all; supply exactly one selector", "type": "string", "minLength": 1, "maxLength": 128 }, "integrationName": { "description": "Exact saved name; first full-access match ordered by name then ID", "type": "string", "minLength": 1, "maxLength": 256 }, "integrationKind": { "description": "Integration type from integration_getKinds; first full-access match ordered by name then ID", "type": "string", "enum": [ "autobrr", "jellystat", "scrutiny", "tubearchivist", "frigate", "komga", "netalertx", "jackett", "yourSpotify", "romm", "homebox", "mealie", "xteve", "unmanic", "syncthingRelay", "stash", "prometheus", "plantit", "netdata", "fileflows", "trilium", "tandoor", "spoolman", "miniflux", "maintainerr", "linkwarden", "karakeep", "healthchecks", "gatus", "changedetection", "caddy", "sabNzbd", "nzbGet", "deluge", "transmission", "qBittorrent", "aria2", "slskd", "sonarr", "radarr", "lidarr", "readarr", "bindery", "prowlarr", "bazarr", "jellyfin", "emby", "plex", "jellyseerr", "seerr", "overseerr", "piHole", "adGuardHome", "technitiumDns", "homeAssistant", "openmediavault", "dashDot", "glances", "tdarr", "proxmox", "nextcloud", "unifiController", "opnsense", "ntfy", "gotify", "ical", "anchor", "truenas", "synology", "unraid", "coolify", "immich", "paperlessNgx", "patchmon", "tracearr", "speedtestTracker", "uptimeKuma", "audiobookshelf", "navidrome", "umami", "peaNut", "beszel", "gluetun", "traefik", "archiveTeamWarrior", "wazuh", "wud", "llamacpp", "mock" ] }, "method": { "default": "GET", "type": "string", "enum": [ "GET", "HEAD", "OPTIONS", "POST", "PUT", "PATCH", "DELETE" ] }, "path": { "type": "string", "minLength": 1, "maxLength": 8192, "description": "API endpoint appended to the saved integration URL, including query parameters" }, "body": { "description": "JSON value by default; a string when bodyEncoding is raw", "$ref": "#/components/schemas/__schema0" }, "bodyEncoding": { "default": "json", "description": "Use raw with a Content-Type header for form-encoded, XML or text bodies", "type": "string", "enum": [ "json", "raw" ] }, "headers": { "description": "Optional non-authentication headers; stored authentication takes precedence", "type": "object", "propertyNames": { "type": "string", "minLength": 1, "maxLength": 128, "pattern": "^[!#$%&'*+.^_`|~0-9A-Za-z-]+$" }, "additionalProperties": { "type": "string", "maxLength": 8192, "pattern": "^[\\t\\x20-\\x7e]*$" } }, "confirmed": { "description": "Required for DELETE after the user confirms the deletion and its effects", "type": "boolean" } }, "required": [ "path" ] }, "example": { "integrationKind": "sonarr", "method": "GET", "path": "/api/v3/system/status" } } } }, "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "properties": { "integration": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "kind": { "type": "string", "enum": [ "autobrr", "jellystat", "scrutiny", "tubearchivist", "frigate", "komga", "netalertx", "jackett", "yourSpotify", "romm", "homebox", "mealie", "xteve", "unmanic", "syncthingRelay", "stash", "prometheus", "plantit", "netdata", "fileflows", "trilium", "tandoor", "spoolman", "miniflux", "maintainerr", "linkwarden", "karakeep", "healthchecks", "gatus", "changedetection", "caddy", "sabNzbd", "nzbGet", "deluge", "transmission", "qBittorrent", "aria2", "slskd", "sonarr", "radarr", "lidarr", "readarr", "bindery", "prowlarr", "bazarr", "jellyfin", "emby", "plex", "jellyseerr", "seerr", "overseerr", "piHole", "adGuardHome", "technitiumDns", "homeAssistant", "openmediavault", "dashDot", "glances", "tdarr", "proxmox", "nextcloud", "unifiController", "opnsense", "ntfy", "gotify", "ical", "anchor", "truenas", "synology", "unraid", "coolify", "immich", "paperlessNgx", "patchmon", "tracearr", "speedtestTracker", "uptimeKuma", "audiobookshelf", "navidrome", "umami", "peaNut", "beszel", "gluetun", "traefik", "archiveTeamWarrior", "wazuh", "wud", "llamacpp", "mock" ] } }, "required": [ "id", "name", "kind" ], "additionalProperties": false }, "ok": { "type": "boolean" }, "status": { "type": "number" }, "statusText": { "type": "string" }, "data": { "$ref": "#/components/schemas/__schema1" } }, "required": [ "integration", "ok", "status", "statusText", "data" ], "additionalProperties": false } } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } }, "/api/integrations/{id}/test-connection": { "get": { "operationId": "integration-testConnection", "summary": "Test a saved integration using stored credentials", "description": "Requires full integration access. Runs the native connection check without changing saved configuration. Upstream authentication may establish a session. Success is a connection check, not widget or service acceptance. Failures expose only a safe category, not upstream errors or credentials.", "tags": [ "integrations" ], "security": [ { "apikey": [] } ], "parameters": [ { "in": "path", "name": "id", "schema": { "type": "string" }, "required": true } ], "responses": { "200": { "description": "Successful response", "content": { "application/json": { "schema": { "oneOf": [ { "type": "object", "properties": { "success": { "type": "boolean", "const": true } }, "required": [ "success" ], "additionalProperties": false }, { "type": "object", "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "string", "enum": [ "missingSecret", "authorization", "certificate", "request", "statusCode", "parse", "unknown" ] } }, "required": [ "success", "error" ], "additionalProperties": false } ], "type": "object" } } } }, "400": { "description": "Invalid input data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.BAD_REQUEST" } } } }, "401": { "description": "Authorization not provided", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.UNAUTHORIZED" } } } }, "403": { "description": "Insufficient access", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.FORBIDDEN" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.NOT_FOUND" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/error.INTERNAL_SERVER_ERROR" } } } } } } } }, "components": { "schemas": { "__schema0": { "anyOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" }, { "type": "array", "items": { "$ref": "#/components/schemas/__schema0" } }, { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": { "$ref": "#/components/schemas/__schema0" } } ] }, "error.BAD_REQUEST": { "type": "object", "properties": { "message": { "type": "string", "description": "The error message", "example": "Invalid input data" }, "code": { "type": "string", "description": "The error code", "example": "BAD_REQUEST" }, "issues": { "description": "An array of issues that were responsible for the error", "example": [], "type": "array", "items": { "type": "object", "properties": { "message": { "type": "string" } }, "required": [ "message" ], "additionalProperties": false } } }, "required": [ "message", "code" ], "additionalProperties": false, "title": "Invalid input data error (400)", "description": "The error information", "example": { "code": "BAD_REQUEST", "message": "Invalid input data", "issues": [] } }, "error.UNAUTHORIZED": { "type": "object", "properties": { "message": { "type": "string", "description": "The error message", "example": "Authorization not provided" }, "code": { "type": "string", "description": "The error code", "example": "UNAUTHORIZED" }, "issues": { "description": "An array of issues that were responsible for the error", "example": [], "type": "array", "items": { "type": "object", "properties": { "message": { "type": "string" } }, "required": [ "message" ], "additionalProperties": false } } }, "required": [ "message", "code" ], "additionalProperties": false, "title": "Authorization not provided error (401)", "description": "The error information", "example": { "code": "UNAUTHORIZED", "message": "Authorization not provided", "issues": [] } }, "error.FORBIDDEN": { "type": "object", "properties": { "message": { "type": "string", "description": "The error message", "example": "Insufficient access" }, "code": { "type": "string", "description": "The error code", "example": "FORBIDDEN" }, "issues": { "description": "An array of issues that were responsible for the error", "example": [], "type": "array", "items": { "type": "object", "properties": { "message": { "type": "string" } }, "required": [ "message" ], "additionalProperties": false } } }, "required": [ "message", "code" ], "additionalProperties": false, "title": "Insufficient access error (403)", "description": "The error information", "example": { "code": "FORBIDDEN", "message": "Insufficient access", "issues": [] } }, "error.NOT_FOUND": { "type": "object", "properties": { "message": { "type": "string", "description": "The error message", "example": "Not found" }, "code": { "type": "string", "description": "The error code", "example": "NOT_FOUND" }, "issues": { "description": "An array of issues that were responsible for the error", "example": [], "type": "array", "items": { "type": "object", "properties": { "message": { "type": "string" } }, "required": [ "message" ], "additionalProperties": false } } }, "required": [ "message", "code" ], "additionalProperties": false, "title": "Not found error (404)", "description": "The error information", "example": { "code": "NOT_FOUND", "message": "Not found", "issues": [] } }, "error.INTERNAL_SERVER_ERROR": { "type": "object", "properties": { "message": { "type": "string", "description": "The error message", "example": "Internal server error" }, "code": { "type": "string", "description": "The error code", "example": "INTERNAL_SERVER_ERROR" }, "issues": { "description": "An array of issues that were responsible for the error", "example": [], "type": "array", "items": { "type": "object", "properties": { "message": { "type": "string" } }, "required": [ "message" ], "additionalProperties": false } } }, "required": [ "message", "code" ], "additionalProperties": false, "title": "Internal server error error (500)", "description": "The error information", "example": { "code": "INTERNAL_SERVER_ERROR", "message": "Internal server error", "issues": [] } }, "__schema1": { "anyOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" }, { "type": "array", "items": { "$ref": "#/components/schemas/__schema1" } }, { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": { "$ref": "#/components/schemas/__schema1" } } ] } }, "securitySchemes": { "apikey": { "type": "apiKey", "name": "ApiKey", "description": "API key which can be obtained in the Homarr administration dashboard", "in": "header" } } } }