{ "openapi": "3.1.0", "info": { "title": "Arcfire API", "version": "0.0.0", "description": "Public and administrative endpoints exposed by the Arcfire media server.\nAll routes are served from the same origin as the web client. Runtime security\nis handled via bearer tokens (`Authorization: Bearer `) or the\n`auth_token` HTTP-only cookie set by the OpenID Connect login flow.\n", "license": { "name": "MIT", "url": "https://opensource.org/licenses/MIT" } }, "servers": [ { "url": "http://localhost:3000", "description": "Local development server" } ], "security": [ { "bearerAuth": [] }, { "cookieAuth": [] } ], "tags": [ { "name": "System", "description": "Service level endpoints that do not require authentication." }, { "name": "Auth" }, { "name": "Discover" }, { "name": "Requests" }, { "name": "Stream" }, { "name": "Admin" } ], "paths": { "/health": { "get": { "tags": [ "System" ], "summary": "Check service health", "description": "Lightweight readiness probe used by load balancers and monitoring.", "operationId": "getHealth", "security": [], "responses": { "200": { "description": "Service is healthy", "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "type": "string", "example": "ok" }, "uptime": { "type": "number", "format": "float" }, "version": { "type": "string" }, "node": { "type": "string" }, "time": { "type": "string", "format": "date-time" } } } } } }, "500": { "description": "Service is unhealthy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/auth/login": { "get": { "tags": [ "Auth" ], "summary": "Begin OIDC login", "description": "Initiates the OpenID Connect authorization code flow and redirects to the upstream identity provider.", "operationId": "beginLogin", "parameters": [ { "in": "query", "name": "remember", "schema": { "type": "string" }, "description": "Optional duration string that controls the session lifetime (e.g. `7d`)." }, { "in": "query", "name": "redirect", "schema": { "type": "string" }, "description": "Optional URL to redirect the user to once the login completes." } ], "security": [], "responses": { "302": { "description": "Redirect to the OIDC authorization endpoint" }, "500": { "description": "OIDC login cannot be started", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/auth/callback": { "get": { "tags": [ "Auth" ], "summary": "Complete OIDC callback", "description": "Handles the authorization code returned by the identity provider, issues a session cookie, and redirects back to the client.", "operationId": "completeLogin", "parameters": [ { "in": "query", "name": "code", "schema": { "type": "string" }, "required": true, "description": "Authorization code issued by the identity provider." }, { "in": "query", "name": "state", "schema": { "type": "string" }, "required": true, "description": "CSRF protection token that must match the stored cookie." } ], "security": [], "responses": { "302": { "description": "Redirect to the original destination or site root" }, "400": { "description": "Invalid state or authorization code", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Login could not be completed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/auth/me": { "get": { "tags": [ "Auth" ], "summary": "Get the current user profile", "operationId": "getCurrentUser", "responses": { "200": { "description": "Authenticated user details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } } }, "401": { "description": "No valid session", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/auth/logout": { "get": { "tags": [ "Auth" ], "summary": "Terminate the active session", "operationId": "logout", "responses": { "302": { "description": "Session cleared and browser redirected to the site root" }, "500": { "description": "Logout failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/auth/token": { "get": { "tags": [ "Auth" ], "summary": "Inspect the active API token", "operationId": "getToken", "responses": { "200": { "description": "Token retrieved successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuthTokenResponse" } } } }, "401": { "description": "Token is invalid or expired", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "No session token cookie was found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/discover": { "get": { "tags": [ "Discover" ], "summary": "List visible media", "operationId": "listMedia", "responses": { "200": { "description": "Media collection available to the user", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/MediaItem" } } } } } } } }, "/api/discover/{mediaId}": { "get": { "tags": [ "Discover" ], "summary": "Get media details", "operationId": "getMedia", "parameters": [ { "name": "mediaId", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Media record including seasons and movies", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MediaWithLibrary" } } } }, "404": { "description": "Media item not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/discover/{mediaId}/{libraryId}": { "get": { "tags": [ "Discover" ], "summary": "Get a library item", "operationId": "getLibraryItem", "parameters": [ { "name": "mediaId", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "libraryId", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Library item with optional episode metadata", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LibraryItemWithEpisodes" } } } }, "404": { "description": "Library item not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/requests": { "get": { "tags": [ "Requests" ], "summary": "Get cached trending content", "operationId": "getTrending", "responses": { "200": { "description": "Cached trending payload sourced from TMDB and Rotten Tomatoes.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TrendingResponse" } } } } } }, "post": { "tags": [ "Requests" ], "summary": "Submit a new media request", "operationId": "createRequest", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RequestCreate" } } } }, "responses": { "200": { "description": "Request accepted", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "Request received" }, "id": { "type": "string" } } } } } }, "400": { "description": "Invalid request payload", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "User is not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Server error when creating request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/requests/my": { "get": { "tags": [ "Requests" ], "summary": "List the caller's requests", "operationId": "listMyRequests", "parameters": [ { "in": "query", "name": "offset", "schema": { "type": "integer", "minimum": 0 }, "description": "Page offset (50 items per page)." } ], "responses": { "200": { "description": "Requests created by the current user", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Request" } } } } }, "401": { "description": "Caller is not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/requests/search": { "get": { "tags": [ "Requests" ], "summary": "Search TMDB for movies, shows, or people", "operationId": "searchTmdb", "parameters": [ { "in": "query", "name": "q", "required": true, "schema": { "type": "string" }, "description": "Free text search term forwarded to TMDB." } ], "responses": { "200": { "description": "TMDB search results filtered to exclude people", "content": { "application/json": { "schema": { "type": "object", "properties": { "results": { "type": "object", "description": "Raw TMDB search response.", "additionalProperties": true } } } } } }, "400": { "description": "Missing query parameter", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/requests/tv/{id}": { "get": { "tags": [ "Requests" ], "summary": "Fetch extended TV information", "operationId": "getTvDetails", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Combined TMDB data and local metadata", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TvDetailsResponse" } } } }, "400": { "description": "Missing TV id", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Failed to fetch details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/requests/movie/{id}": { "get": { "tags": [ "Requests" ], "summary": "Fetch extended movie information", "operationId": "getMovieDetails", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Combined TMDB data and local metadata", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MovieDetailsResponse" } } } }, "400": { "description": "Missing movie id", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Failed to fetch details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/requests/{id}": { "delete": { "tags": [ "Requests" ], "summary": "Cancel a pending request", "operationId": "deleteRequest", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Request cancelled", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "Request canceled" } } } } } }, "400": { "description": "Request cannot be cancelled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Caller is not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Attempt to cancel another user's request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Request not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Cancellation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/stream/{libraryId}": { "get": { "tags": [ "Stream" ], "summary": "Retrieve library metadata for playback", "operationId": "getStreamLibraryItem", "parameters": [ { "name": "libraryId", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Library item metadata", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LibraryItem" } } } }, "404": { "description": "Library item not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "Stream" ], "summary": "Start a new on-demand stream", "operationId": "startStream", "parameters": [ { "name": "libraryId", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StreamStartRequest" } } } }, "responses": { "200": { "description": "Stream initialized and encoder kicked off", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "$ref": "#/components/schemas/StreamSessionSummary" }, "streamId": { "type": "string" }, "playlist": { "type": "string", "description": "Relative URL to the generated HLS playlist" } } } } } }, "400": { "description": "Request body missing required properties", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Caller is not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Library item could not be located", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Stream initialization failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/stream/byStream/{streamId}/hls.m3u8": { "get": { "tags": [ "Stream" ], "summary": "Retrieve the generated HLS playlist", "operationId": "getHlsPlaylist", "parameters": [ { "name": "streamId", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "M3U8 playlist", "content": { "application/vnd.apple.mpegurl": { "schema": { "type": "string" } } } }, "401": { "description": "Caller is not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Playlist not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "Stream is not ready yet", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/stream/byStream/{streamId}/{segment}": { "get": { "tags": [ "Stream" ], "summary": "Retrieve an encoded HLS segment", "operationId": "getHlsSegment", "parameters": [ { "name": "streamId", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "segment", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Transport stream segment", "content": { "video/mp2t": { "schema": { "type": "string", "format": "binary" } } } }, "400": { "description": "Invalid segment name", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Caller is not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Segment not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/admin/requests": { "get": { "tags": [ "Admin" ], "summary": "List all requests (50 per page)", "operationId": "adminListRequests", "parameters": [ { "in": "query", "name": "page", "schema": { "type": "integer", "minimum": 0 }, "description": "Page index for pagination." } ], "responses": { "200": { "description": "Requests ordered by creation time", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Request" } } } } } } } }, "/api/admin/requests/deny/{id}": { "post": { "tags": [ "Admin" ], "summary": "Deny a request", "operationId": "adminDenyRequest", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Request marked as denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Request" } } } }, "404": { "description": "Request not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Update failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/admin/requests/approve/{id}": { "post": { "tags": [ "Admin" ], "summary": "Approve a request", "operationId": "adminApproveRequest", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Request marked as approved", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Request" } } } }, "404": { "description": "Request not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Update failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/admin/users": { "get": { "tags": [ "Admin" ], "summary": "List all users", "operationId": "adminListUsers", "responses": { "200": { "description": "User directory", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/User" } } } } } } } }, "/api/admin/tasks": { "get": { "tags": [ "Admin" ], "summary": "Inspect recurring task statuses", "operationId": "adminListTasks", "responses": { "200": { "description": "Current scheduler state", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/TaskStatus" } } } } } } } }, "/api/admin/tasks/{taskName}": { "post": { "tags": [ "Admin" ], "summary": "Control a scheduled task", "operationId": "adminControlTask", "parameters": [ { "name": "taskName", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TaskActionRequest" } } } }, "responses": { "200": { "description": "Command accepted", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string" } } } } } }, "400": { "description": "Invalid action or task state", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/admin/import/sonarr": { "post": { "tags": [ "Admin" ], "summary": "Trigger Sonarr import workflows", "operationId": "adminSonarrImport", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SonarrImportRequest" } } } }, "responses": { "200": { "description": "Import started", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GenericSuccess" } } } }, "400": { "description": "Invalid input parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Import command failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/admin/media": { "get": { "tags": [ "Admin" ], "summary": "List all media including hidden items", "operationId": "adminListMedia", "responses": { "200": { "description": "Full media catalog", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/MediaItem" } } } } } } } }, "/api/admin/media/{mediaId}/images": { "get": { "tags": [ "Admin" ], "summary": "Fetch TMDB imagery for a media item", "operationId": "adminGetMediaImages", "parameters": [ { "name": "mediaId", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "TMDB imagery payload", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "404": { "description": "Media not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "Admin" ], "summary": "Save media artwork", "operationId": "adminSaveMediaImage", "parameters": [ { "name": "mediaId", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MediaImageSelection" } } } }, "responses": { "200": { "description": "Image persisted to disk", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GenericSuccess" } } } }, "400": { "description": "Missing type or url", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Media not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Image download failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/admin/media/{mediaId}/season/{seasonNumber}/images": { "get": { "tags": [ "Admin" ], "summary": "Fetch TMDB season imagery", "operationId": "adminGetSeasonImages", "parameters": [ { "name": "mediaId", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "seasonNumber", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "TMDB season imagery payload", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "400": { "description": "Media is not a series", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Media not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "Admin" ], "summary": "Save season artwork", "operationId": "adminSaveSeasonImage", "parameters": [ { "name": "mediaId", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "seasonNumber", "in": "path", "required": true, "schema": { "type": "integer" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ImageUrlRequest" } } } }, "responses": { "200": { "description": "Season poster downloaded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GenericSuccess" } } } }, "400": { "description": "Missing URL or invalid parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Media or season not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Image download failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/admin/media/{mediaId}/season/{seasonNumber}/episode/{episodeNumber}/images": { "get": { "tags": [ "Admin" ], "summary": "Fetch TMDB episode imagery", "operationId": "adminGetEpisodeImages", "parameters": [ { "name": "mediaId", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "seasonNumber", "in": "path", "required": true, "schema": { "type": "integer" } }, { "name": "episodeNumber", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "TMDB episode imagery payload", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "400": { "description": "Media is not a series", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Media not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "Admin" ], "summary": "Save episode artwork", "operationId": "adminSaveEpisodeImage", "parameters": [ { "name": "mediaId", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "seasonNumber", "in": "path", "required": true, "schema": { "type": "integer" } }, { "name": "episodeNumber", "in": "path", "required": true, "schema": { "type": "integer" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ImageUrlRequest" } } } }, "responses": { "200": { "description": "Episode still downloaded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GenericSuccess" } } } }, "400": { "description": "Missing URL or invalid parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Media or season not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Image download failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/admin/database/stats": { "get": { "tags": [ "Admin" ], "summary": "Database statistics", "operationId": "adminDatabaseStats", "responses": { "200": { "description": "Aggregate metrics about the database", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DatabaseStats" } } } } } } }, "/api/admin/database/table": { "get": { "tags": [ "Admin" ], "summary": "List available tables", "operationId": "adminDatabaseTables", "responses": { "200": { "description": "Table names", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "string" } } } } } } } }, "/api/admin/database/table/{tableName}": { "get": { "tags": [ "Admin" ], "summary": "Describe a table", "operationId": "adminDescribeTable", "parameters": [ { "name": "tableName", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Column metadata", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "$ref": "#/components/schemas/TableColumn" } } } } }, "500": { "description": "Unable to describe table", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "Admin" ], "summary": "Insert a new row", "operationId": "adminInsertRow", "parameters": [ { "name": "tableName", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "responses": { "200": { "description": "Row inserted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GenericSuccess" } } } }, "500": { "description": "Insert failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/admin/database/table/{tableName}/data": { "get": { "tags": [ "Admin" ], "summary": "Read table data", "operationId": "adminGetTableData", "parameters": [ { "name": "tableName", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Rows stored in the table", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "additionalProperties": true } } } } }, "500": { "description": "Unable to fetch data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/admin/database/table/{tableName}/{id}": { "put": { "tags": [ "Admin" ], "summary": "Update a row", "operationId": "adminUpdateRow", "parameters": [ { "name": "tableName", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "responses": { "200": { "description": "Row updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GenericSuccess" } } } }, "500": { "description": "Update failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "Admin" ], "summary": "Delete a row", "operationId": "adminDeleteRow", "parameters": [ { "name": "tableName", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Row deleted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GenericSuccess" } } } }, "500": { "description": "Delete failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } } }, "components": { "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "UUID" }, "cookieAuth": { "type": "apiKey", "in": "cookie", "name": "auth_token" } }, "schemas": { "ErrorResponse": { "type": "object", "properties": { "error": { "type": "string" }, "message": { "type": "string" } }, "required": [ "error" ] }, "User": { "type": "object", "properties": { "id": { "type": "string" }, "username": { "type": "string" }, "display_name": { "type": [ "string", "null" ] }, "email": { "type": [ "string", "null" ] }, "role": { "type": "string", "description": "Either `user` or `admin`." } }, "required": [ "id", "username", "role" ] }, "AuthTokenResponse": { "type": "object", "properties": { "token": { "type": "string" }, "expires_at": { "type": [ "string", "null" ], "format": "date-time" } } }, "MediaItem": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "type": { "type": "string", "enum": [ "movie", "series" ] }, "sub_type": { "type": [ "string", "null" ] }, "overview": { "type": [ "string", "null" ] }, "genres": { "type": "array", "items": { "type": "string" } }, "parental_rating": { "type": [ "string", "null" ] }, "ratings": { "type": "object", "additionalProperties": true }, "metadata": { "type": "object", "additionalProperties": true }, "tmdb_id": { "type": "integer" }, "tvdb_id": { "type": [ "integer", "null" ] }, "imdb_id": { "type": [ "string", "null" ] }, "arr_id": { "type": [ "integer", "null" ] }, "hidden": { "type": "boolean" } }, "required": [ "id", "name", "type", "tmdb_id" ] }, "SeasonItem": { "type": "object", "properties": { "id": { "type": "string" }, "media_id": { "type": "string" }, "type": { "type": "string", "enum": [ "season" ] }, "name": { "type": "string" }, "season_number": { "type": "integer" }, "overview": { "type": [ "string", "null" ] }, "metadata": { "type": "object", "additionalProperties": true }, "hidden": { "type": "boolean" } }, "required": [ "id", "media_id", "type", "name", "season_number" ] }, "EpisodeItem": { "type": "object", "properties": { "id": { "type": "string" }, "media_id": { "type": "string" }, "season_id": { "type": "string" }, "type": { "type": "string", "enum": [ "episode" ] }, "name": { "type": "string" }, "season_number": { "type": "integer" }, "episode_number": { "type": "integer" }, "overview": { "type": [ "string", "null" ] }, "metadata": { "type": "object", "additionalProperties": true }, "hidden": { "type": "boolean" } }, "required": [ "id", "media_id", "season_id", "type", "name", "season_number", "episode_number" ] }, "LibraryItem": { "type": "object", "properties": { "id": { "type": "string" }, "media_id": { "type": "string" }, "season_id": { "type": [ "string", "null" ] }, "type": { "type": "string", "enum": [ "episode", "movie", "season" ] }, "name": { "type": "string" }, "season_number": { "type": [ "integer", "null" ] }, "episode_number": { "type": [ "integer", "null" ] }, "overview": { "type": [ "string", "null" ] }, "metadata": { "type": "object", "additionalProperties": true }, "hidden": { "type": "boolean" } }, "required": [ "id", "media_id", "type", "name" ] }, "LibraryItemWithEpisodes": { "allOf": [ { "$ref": "#/components/schemas/LibraryItem" }, { "type": "object", "properties": { "episodes": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/EpisodeItem" } } } } ] }, "MediaWithLibrary": { "allOf": [ { "$ref": "#/components/schemas/MediaItem" }, { "type": "object", "properties": { "seasons": { "type": "array", "items": { "$ref": "#/components/schemas/SeasonItem" } }, "movies": { "type": "array", "items": { "$ref": "#/components/schemas/LibraryItem" } } } } ] }, "Request": { "type": "object", "properties": { "id": { "type": "string" }, "tmdb_id": { "type": "integer" }, "type": { "type": "string", "enum": [ "movie", "series" ] }, "sub_type": { "type": [ "string", "null" ] }, "seasons": { "type": "array", "items": { "type": "integer" }, "default": [] }, "status": { "type": "string" }, "requester_id": { "type": "string" }, "media_data": { "type": "object", "properties": { "title": { "type": "string" }, "year": { "type": [ "integer", "null" ] }, "poster_path": { "type": [ "string", "null" ] }, "backdrop_path": { "type": [ "string", "null" ] }, "overview": { "type": [ "string", "null" ] } } } }, "required": [ "id", "tmdb_id", "type", "status", "requester_id", "media_data" ] }, "RequestCreate": { "type": "object", "additionalProperties": false, "properties": { "tmdb_id": { "type": "integer" }, "type": { "type": "string", "enum": [ "movie", "series" ] }, "sub_type": { "type": [ "string", "null" ] }, "seasons": { "type": "array", "items": { "type": "integer" }, "description": "Required when requesting a series." }, "image_paths": { "type": "object", "properties": { "poster_path": { "type": [ "string", "null" ] }, "backdrop_path": { "type": [ "string", "null" ] } } }, "title": { "type": "string" }, "overview": { "type": [ "string", "null" ] } }, "required": [ "tmdb_id", "type" ] }, "TrendingItem": { "type": "object", "properties": { "id": { "type": "integer" }, "title": { "type": [ "string", "null" ] }, "name": { "type": [ "string", "null" ] }, "media_type": { "type": "string" }, "overview": { "type": [ "string", "null" ] }, "poster_path": { "type": [ "string", "null" ] }, "backdrop_path": { "type": [ "string", "null" ] }, "vote_average": { "type": [ "number", "null" ], "format": "float" }, "vote_count": { "type": [ "integer", "null" ] }, "popularity": { "type": [ "number", "null" ], "format": "float" }, "release_date": { "type": [ "string", "null" ] }, "first_air_date": { "type": [ "string", "null" ] }, "genre_ids": { "type": "array", "items": { "type": "integer" } } }, "additionalProperties": true }, "TrendingResponse": { "type": "object", "properties": { "trendingShows": { "type": "array", "items": { "$ref": "#/components/schemas/TrendingItem" } }, "trendingMovies": { "type": "array", "items": { "$ref": "#/components/schemas/TrendingItem" } }, "trendingAnime": { "type": "array", "items": { "$ref": "#/components/schemas/TrendingItem" } } } }, "TvDetailsResponse": { "type": "object", "properties": { "details": { "type": "object", "additionalProperties": true }, "credits": { "type": [ "object", "null" ], "additionalProperties": true }, "recommendations": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "similar": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "score": { "type": [ "object", "null" ], "additionalProperties": true }, "localdata": { "type": [ "object", "null" ], "additionalProperties": true }, "keywords": { "type": "array", "items": { "type": "object", "additionalProperties": true } } } }, "MovieDetailsResponse": { "type": "object", "properties": { "details": { "type": "object", "additionalProperties": true }, "credits": { "type": [ "object", "null" ], "additionalProperties": true }, "recommendations": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "similar": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "score": { "type": [ "object", "null" ], "additionalProperties": true }, "localdata": { "type": [ "object", "null" ], "additionalProperties": true }, "keywords": { "type": "array", "items": { "type": "object", "additionalProperties": true } } } }, "StreamStartRequest": { "type": "object", "properties": { "options": { "type": "object", "description": "Playback capabilities and preferred qualities reported by the client player.", "additionalProperties": true }, "supportedCodecs": { "type": "array", "description": "Video/audio codec identifiers supported by the client.", "items": { "type": "string" } } }, "required": [ "options", "supportedCodecs" ] }, "StreamSessionSummary": { "type": "object", "properties": { "id": { "type": "string" }, "video_streams": { "type": "array", "items": { "type": "object", "additionalProperties": true } } } }, "TaskStatus": { "type": "object", "properties": { "name": { "type": "string" }, "interval": { "type": "string" }, "enabled": { "type": "boolean" }, "lastRun": { "type": [ "string", "null" ], "format": "date-time" }, "nextRun": { "type": [ "string", "null" ], "format": "date-time" }, "running": { "type": "boolean" } } }, "TaskActionRequest": { "type": "object", "properties": { "action": { "type": "string", "enum": [ "run", "enable", "disable" ] } }, "required": [ "action" ] }, "SonarrImportRequest": { "type": "object", "properties": { "seriesId": { "type": "integer" }, "seasonNumber": { "type": [ "integer", "null" ] }, "episodeNumber": { "type": [ "integer", "null" ] }, "type": { "type": "string", "enum": [ "season", "episode", "series", "all" ] } }, "required": [ "seriesId", "type" ] }, "MediaImageSelection": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "poster", "backdrop", "logo" ] }, "url": { "type": "string", "format": "uri" } }, "required": [ "type", "url" ] }, "ImageUrlRequest": { "type": "object", "properties": { "url": { "type": "string", "format": "uri" } }, "required": [ "url" ] }, "GenericSuccess": { "type": "object", "properties": { "ok": { "type": "boolean", "example": true }, "message": { "type": [ "string", "null" ] }, "result": { "type": [ "object", "null" ], "additionalProperties": true }, "path": { "type": [ "string", "null" ] } } }, "DatabaseStats": { "type": "object", "properties": { "userCount": { "type": [ "integer", "null" ] }, "mediaCount": { "type": [ "integer", "null" ] }, "requestCount": { "type": [ "integer", "null" ] }, "activeRequests": { "type": [ "integer", "null" ] }, "completedRequests": { "type": [ "integer", "null" ] }, "userTokens": { "type": [ "integer", "null" ] } } }, "TableColumn": { "type": "object", "properties": { "type": { "type": "string" }, "allowNull": { "type": "boolean" }, "defaultValue": { "type": [ "string", "number", "boolean", "object", "null" ] }, "primaryKey": { "type": "boolean" }, "autoIncrement": { "type": [ "boolean", "null" ] } }, "additionalProperties": true } } } }