1784 lines
48 KiB
YAML
1784 lines
48 KiB
YAML
|
|
openapi: 3.1.0
|
||
|
|
info:
|
||
|
|
title: Arcfire API
|
||
|
|
version: "0.0.0"
|
||
|
|
description: |
|
||
|
|
Public and administrative endpoints exposed by the Arcfire media server.
|
||
|
|
All routes are served from the same origin as the web client. Runtime security
|
||
|
|
is handled via bearer tokens (`Authorization: Bearer <token>`) or the
|
||
|
|
`auth_token` HTTP-only cookie set by the OpenID Connect login flow.
|
||
|
|
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'
|
||
|
|
/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}:
|
||
|
|
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}/{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
|
||
|
|
nullable: true
|
||
|
|
email:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
role:
|
||
|
|
type: string
|
||
|
|
description: Either `user` or `admin`.
|
||
|
|
required:
|
||
|
|
- id
|
||
|
|
- username
|
||
|
|
- role
|
||
|
|
AuthTokenResponse:
|
||
|
|
type: object
|
||
|
|
properties:
|
||
|
|
token:
|
||
|
|
type: string
|
||
|
|
expires_at:
|
||
|
|
type: string
|
||
|
|
format: date-time
|
||
|
|
nullable: true
|
||
|
|
MediaItem:
|
||
|
|
type: object
|
||
|
|
properties:
|
||
|
|
id:
|
||
|
|
type: string
|
||
|
|
name:
|
||
|
|
type: string
|
||
|
|
type:
|
||
|
|
type: string
|
||
|
|
enum: [movie, series]
|
||
|
|
sub_type:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
overview:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
genres:
|
||
|
|
type: array
|
||
|
|
items:
|
||
|
|
type: string
|
||
|
|
parental_rating:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
ratings:
|
||
|
|
type: object
|
||
|
|
additionalProperties: true
|
||
|
|
metadata:
|
||
|
|
type: object
|
||
|
|
additionalProperties: true
|
||
|
|
tmdb_id:
|
||
|
|
type: integer
|
||
|
|
tvdb_id:
|
||
|
|
type: integer
|
||
|
|
nullable: true
|
||
|
|
imdb_id:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
arr_id:
|
||
|
|
type: integer
|
||
|
|
nullable: true
|
||
|
|
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
|
||
|
|
nullable: true
|
||
|
|
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
|
||
|
|
nullable: true
|
||
|
|
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
|
||
|
|
nullable: true
|
||
|
|
type:
|
||
|
|
type: string
|
||
|
|
enum: [episode, movie, season]
|
||
|
|
name:
|
||
|
|
type: string
|
||
|
|
season_number:
|
||
|
|
type: integer
|
||
|
|
nullable: true
|
||
|
|
episode_number:
|
||
|
|
type: integer
|
||
|
|
nullable: true
|
||
|
|
overview:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
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
|
||
|
|
items:
|
||
|
|
$ref: '#/components/schemas/EpisodeItem'
|
||
|
|
nullable: true
|
||
|
|
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
|
||
|
|
nullable: true
|
||
|
|
seasons:
|
||
|
|
type: array
|
||
|
|
items:
|
||
|
|
type: integer
|
||
|
|
nullable: true
|
||
|
|
status:
|
||
|
|
type: string
|
||
|
|
requester_id:
|
||
|
|
type: string
|
||
|
|
media_data:
|
||
|
|
type: object
|
||
|
|
properties:
|
||
|
|
title:
|
||
|
|
type: string
|
||
|
|
year:
|
||
|
|
type: integer
|
||
|
|
nullable: true
|
||
|
|
poster_path:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
backdrop_path:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
overview:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
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
|
||
|
|
nullable: true
|
||
|
|
seasons:
|
||
|
|
type: array
|
||
|
|
items:
|
||
|
|
type: integer
|
||
|
|
description: Required when requesting a series.
|
||
|
|
image_paths:
|
||
|
|
type: object
|
||
|
|
properties:
|
||
|
|
poster_path:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
backdrop_path:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
title:
|
||
|
|
type: string
|
||
|
|
overview:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
required:
|
||
|
|
- tmdb_id
|
||
|
|
- type
|
||
|
|
TrendingItem:
|
||
|
|
type: object
|
||
|
|
properties:
|
||
|
|
id:
|
||
|
|
type: integer
|
||
|
|
title:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
name:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
media_type:
|
||
|
|
type: string
|
||
|
|
overview:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
poster_path:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
backdrop_path:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
vote_average:
|
||
|
|
type: number
|
||
|
|
format: float
|
||
|
|
nullable: true
|
||
|
|
vote_count:
|
||
|
|
type: integer
|
||
|
|
nullable: true
|
||
|
|
popularity:
|
||
|
|
type: number
|
||
|
|
format: float
|
||
|
|
nullable: true
|
||
|
|
release_date:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
first_air_date:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
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
|
||
|
|
nullable: true
|
||
|
|
additionalProperties: true
|
||
|
|
recommendations:
|
||
|
|
type: array
|
||
|
|
items:
|
||
|
|
type: object
|
||
|
|
additionalProperties: true
|
||
|
|
similar:
|
||
|
|
type: array
|
||
|
|
items:
|
||
|
|
type: object
|
||
|
|
additionalProperties: true
|
||
|
|
score:
|
||
|
|
type: object
|
||
|
|
nullable: true
|
||
|
|
additionalProperties: true
|
||
|
|
localdata:
|
||
|
|
type: object
|
||
|
|
nullable: true
|
||
|
|
additionalProperties: true
|
||
|
|
keywords:
|
||
|
|
type: array
|
||
|
|
items:
|
||
|
|
type: object
|
||
|
|
additionalProperties: true
|
||
|
|
MovieDetailsResponse:
|
||
|
|
type: object
|
||
|
|
properties:
|
||
|
|
details:
|
||
|
|
type: object
|
||
|
|
additionalProperties: true
|
||
|
|
credits:
|
||
|
|
type: object
|
||
|
|
nullable: true
|
||
|
|
additionalProperties: true
|
||
|
|
recommendations:
|
||
|
|
type: array
|
||
|
|
items:
|
||
|
|
type: object
|
||
|
|
additionalProperties: true
|
||
|
|
similar:
|
||
|
|
type: array
|
||
|
|
items:
|
||
|
|
type: object
|
||
|
|
additionalProperties: true
|
||
|
|
score:
|
||
|
|
type: object
|
||
|
|
nullable: true
|
||
|
|
additionalProperties: true
|
||
|
|
localdata:
|
||
|
|
type: object
|
||
|
|
nullable: true
|
||
|
|
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
|
||
|
|
format: date-time
|
||
|
|
nullable: true
|
||
|
|
nextRun:
|
||
|
|
type: string
|
||
|
|
format: date-time
|
||
|
|
nullable: true
|
||
|
|
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
|
||
|
|
nullable: true
|
||
|
|
episodeNumber:
|
||
|
|
type: integer
|
||
|
|
nullable: true
|
||
|
|
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
|
||
|
|
nullable: true
|
||
|
|
result:
|
||
|
|
type: object
|
||
|
|
nullable: true
|
||
|
|
additionalProperties: true
|
||
|
|
path:
|
||
|
|
type: string
|
||
|
|
nullable: true
|
||
|
|
DatabaseStats:
|
||
|
|
type: object
|
||
|
|
properties:
|
||
|
|
userCount:
|
||
|
|
type: integer
|
||
|
|
nullable: true
|
||
|
|
mediaCount:
|
||
|
|
type: integer
|
||
|
|
nullable: true
|
||
|
|
requestCount:
|
||
|
|
type: integer
|
||
|
|
nullable: true
|
||
|
|
activeRequests:
|
||
|
|
type: integer
|
||
|
|
nullable: true
|
||
|
|
completedRequests:
|
||
|
|
type: integer
|
||
|
|
nullable: true
|
||
|
|
userTokens:
|
||
|
|
type: integer
|
||
|
|
nullable: true
|
||
|
|
TableColumn:
|
||
|
|
type: object
|
||
|
|
properties:
|
||
|
|
type:
|
||
|
|
type: string
|
||
|
|
allowNull:
|
||
|
|
type: boolean
|
||
|
|
defaultValue:
|
||
|
|
nullable: true
|
||
|
|
primaryKey:
|
||
|
|
type: boolean
|
||
|
|
autoIncrement:
|
||
|
|
type: boolean
|
||
|
|
nullable: true
|
||
|
|
additionalProperties: true
|