arcfire/openapi.json

2999 lines
72 KiB
JSON
Raw Permalink Normal View History

2025-09-30 15:50:14 +00:00
{
"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 <token>`) 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
}
}
}
}