mirror of
https://github.com/agregarr/agregarr.git
synced 2026-05-08 03:41:02 -05:00
7535 lines
224 KiB
YAML
7535 lines
224 KiB
YAML
openapi: '3.0.2'
|
|
info:
|
|
title: 'Agregarr API'
|
|
version: '1.0.0'
|
|
description: |
|
|
This is the documentation for the Agregarr API backend.
|
|
|
|
Two primary authentication methods are supported:
|
|
|
|
- **Cookie Authentication**: A valid sign-in to the `/auth/plex` or `/auth/local` will generate a valid authentication cookie.
|
|
- **API Key Authentication**: Sign-in is also possible by passing an `X-Api-Key` header along with a valid API Key generated by Agregarr.
|
|
tags:
|
|
- name: public
|
|
description: Public API endpoints requiring no authentication.
|
|
- name: settings
|
|
description: Endpoints related to Agregarr's settings and configuration.
|
|
- name: auth
|
|
description: Endpoints related to logging in or out, and the currently authenticated user.
|
|
- name: users
|
|
description: Endpoints related to user management.
|
|
- name: search
|
|
description: Endpoints related to search and discovery.
|
|
- name: request
|
|
description: Endpoints related to request management.
|
|
- name: movies
|
|
description: Endpoints related to retrieving movies and their details.
|
|
- name: tv
|
|
description: Endpoints related to retrieving TV series and their details.
|
|
- name: other
|
|
description: Endpoints related to other TMDB data
|
|
- name: person
|
|
description: Endpoints related to retrieving person details.
|
|
- name: media
|
|
description: Endpoints related to media management.
|
|
- name: collection
|
|
description: Endpoints related to retrieving collection details.
|
|
- name: service
|
|
description: Endpoints related to getting service (Radarr/Sonarr) details.
|
|
- name: missing-items
|
|
description: Endpoints related to missing item request tracking and management.
|
|
- name: dashboard
|
|
description: Endpoints related to dashboard statistics and analytics.
|
|
servers:
|
|
- url: '{server}/api/v1'
|
|
variables:
|
|
server:
|
|
default: http://localhost:7171
|
|
|
|
components:
|
|
schemas:
|
|
User:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
example: 1
|
|
readOnly: true
|
|
email:
|
|
type: string
|
|
example: 'hey@itsme.com'
|
|
readOnly: true
|
|
username:
|
|
type: string
|
|
plexToken:
|
|
type: string
|
|
readOnly: true
|
|
plexUsername:
|
|
type: string
|
|
readOnly: true
|
|
userType:
|
|
type: integer
|
|
example: 1
|
|
readOnly: true
|
|
permissions:
|
|
type: number
|
|
example: 0
|
|
avatar:
|
|
type: string
|
|
readOnly: true
|
|
createdAt:
|
|
type: string
|
|
example: '2020-09-02T05:02:23.000Z'
|
|
readOnly: true
|
|
updatedAt:
|
|
type: string
|
|
example: '2020-09-02T05:02:23.000Z'
|
|
readOnly: true
|
|
requestCount:
|
|
type: number
|
|
example: 5
|
|
readOnly: true
|
|
required:
|
|
- id
|
|
- email
|
|
- createdAt
|
|
- updatedAt
|
|
UserSettings:
|
|
type: object
|
|
properties:
|
|
locale:
|
|
type: string
|
|
region:
|
|
type: string
|
|
originalLanguage:
|
|
type: string
|
|
MainSettings:
|
|
type: object
|
|
properties:
|
|
apiKey:
|
|
type: string
|
|
readOnly: true
|
|
appLanguage:
|
|
type: string
|
|
example: en
|
|
applicationTitle:
|
|
type: string
|
|
example: Agregarr
|
|
applicationUrl:
|
|
type: string
|
|
example: https://os.example.com
|
|
trustProxy:
|
|
type: boolean
|
|
example: true
|
|
csrfProtection:
|
|
type: boolean
|
|
example: false
|
|
hideAvailable:
|
|
type: boolean
|
|
example: false
|
|
partialRequestsEnabled:
|
|
type: boolean
|
|
example: false
|
|
localLogin:
|
|
type: boolean
|
|
example: true
|
|
newPlexLogin:
|
|
type: boolean
|
|
example: true
|
|
PlexLibrary:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
name:
|
|
type: string
|
|
example: Movies
|
|
enabled:
|
|
type: boolean
|
|
example: false
|
|
required:
|
|
- id
|
|
- name
|
|
- enabled
|
|
PlexSettings:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
example: 'Main Server'
|
|
readOnly: true
|
|
machineId:
|
|
type: string
|
|
example: '1234123412341234'
|
|
readOnly: true
|
|
ip:
|
|
type: string
|
|
example: '127.0.0.1'
|
|
port:
|
|
type: number
|
|
example: 32400
|
|
useSsl:
|
|
type: boolean
|
|
nullable: true
|
|
libraries:
|
|
type: array
|
|
readOnly: true
|
|
items:
|
|
$ref: '#/components/schemas/PlexLibrary'
|
|
webAppUrl:
|
|
type: string
|
|
nullable: true
|
|
example: 'https://app.plex.tv/desktop'
|
|
required:
|
|
- name
|
|
- machineId
|
|
- ip
|
|
- port
|
|
CollectionConfig:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: "Unique collection identifier (sequential number starting from 10000)"
|
|
example: "10000"
|
|
name:
|
|
type: string
|
|
example: "User Requests"
|
|
type:
|
|
type: string
|
|
enum: ['overseerr', 'tautulli', 'trakt', 'tmdb', 'imdb', 'letterboxd', 'networks']
|
|
example: 'overseerr'
|
|
subtype:
|
|
type: string
|
|
example: 'users'
|
|
template:
|
|
type: string
|
|
example: "{nickname}'s Requests"
|
|
customMovieTemplate:
|
|
type: string
|
|
description: "Custom template for movie collections when mediaType is 'both'"
|
|
example: "{nickname}'s Movie Requests"
|
|
nullable: true
|
|
customTVTemplate:
|
|
type: string
|
|
description: "Custom template for TV collections when mediaType is 'both'"
|
|
example: "{nickname}'s TV Requests"
|
|
nullable: true
|
|
customPoster:
|
|
oneOf:
|
|
- type: string
|
|
description: "Filename of custom poster image (legacy format)"
|
|
example: "f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
- type: object
|
|
description: "Per-library poster mapping (libraryId -> filename)"
|
|
additionalProperties:
|
|
type: string
|
|
example:
|
|
lib1: "f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
lib2: "a12bc34d-58cc-4372-a567-0e02b2c3d480.jpg"
|
|
nullable: true
|
|
autoPoster:
|
|
type: boolean
|
|
description: "Auto-generate poster during sync"
|
|
example: true
|
|
nullable: true
|
|
visibilityConfig:
|
|
type: object
|
|
properties:
|
|
usersHome:
|
|
type: boolean
|
|
description: "Show on shared users' home screens"
|
|
example: true
|
|
serverOwnerHome:
|
|
type: boolean
|
|
description: "Show on server owner's home screen"
|
|
example: false
|
|
libraryRecommended:
|
|
type: boolean
|
|
description: "Show in library recommended section"
|
|
example: false
|
|
required:
|
|
- usersHome
|
|
- serverOwnerHome
|
|
- libraryRecommended
|
|
maxItems:
|
|
type: integer
|
|
example: 20
|
|
mediaType:
|
|
type: string
|
|
enum: ['movie', 'tv', 'both']
|
|
example: 'both'
|
|
libraryIds:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: "Array of selected library IDs (['all'] for all libraries)"
|
|
example: ["1", "2"]
|
|
nullable: true
|
|
libraryName:
|
|
type: string
|
|
description: "Selected library name for display"
|
|
example: "Movies"
|
|
nullable: true
|
|
sortOrderHome:
|
|
type: integer
|
|
description: "Order for Plex home screen (creation time based)"
|
|
example: 0
|
|
nullable: true
|
|
sortOrderLibrary:
|
|
type: integer
|
|
description: "Position in library (0 for A-Z section, 1+ for promoted section)"
|
|
example: 0
|
|
nullable: true
|
|
isLibraryPromoted:
|
|
type: boolean
|
|
description: "true = promoted section (uses exclamation marks), false = A-Z section"
|
|
example: true
|
|
parentConfigId:
|
|
type: integer
|
|
description: "Reference to original config when expanded from 'all' libraries"
|
|
example: 1
|
|
nullable: true
|
|
isExpandedConfig:
|
|
type: boolean
|
|
description: "True if this config was auto-generated from a parent 'all' config"
|
|
example: false
|
|
nullable: true
|
|
customDays:
|
|
type: integer
|
|
description: "Number of days for Tautulli collections (required for Tautulli type)"
|
|
example: 30
|
|
nullable: true
|
|
minimumPlays:
|
|
type: integer
|
|
description: "Minimum play count for Tautulli collections (defaults to 3 if not set, 1-100)"
|
|
example: 3
|
|
nullable: true
|
|
tautulliStatType:
|
|
type: string
|
|
enum: ['plays', 'duration']
|
|
description: "Tautulli statistic type: plays (play count) or duration (watch time)"
|
|
example: 'plays'
|
|
nullable: true
|
|
searchMissingMovies:
|
|
type: boolean
|
|
description: "Auto-request missing movies"
|
|
example: false
|
|
nullable: true
|
|
searchMissingTV:
|
|
type: boolean
|
|
description: "Auto-request missing TV shows"
|
|
example: false
|
|
nullable: true
|
|
autoApproveMovies:
|
|
type: boolean
|
|
description: "Auto-approve movie requests"
|
|
example: false
|
|
nullable: true
|
|
autoApproveTV:
|
|
type: boolean
|
|
description: "Auto-approve TV show requests"
|
|
example: false
|
|
nullable: true
|
|
maxSeasonsToRequest:
|
|
type: integer
|
|
description: "Max seasons for auto-approval (TV shows with more seasons require manual approval)"
|
|
example: 5
|
|
nullable: true
|
|
seasonsPerShowLimit:
|
|
type: integer
|
|
description: "Limit each TV show to only the first X seasons (0 = all seasons)"
|
|
example: 2
|
|
nullable: true
|
|
traktCustomListUrl:
|
|
type: string
|
|
description: "Custom Trakt list URL (e.g., https://trakt.tv/users/username/lists/list-name or https://trakt.tv/lists/official/collection-name)"
|
|
example: "https://trakt.tv/users/username/lists/my-list"
|
|
nullable: true
|
|
tmdbCustomListUrl:
|
|
type: string
|
|
description: "Custom TMDb list/collection URL (e.g., https://www.themoviedb.org/list/123456)"
|
|
example: "https://www.themoviedb.org/collection/123456"
|
|
nullable: true
|
|
imdbCustomListUrl:
|
|
type: string
|
|
description: "Custom IMDb list URL (e.g., https://www.imdb.com/list/ls123456789/)"
|
|
example: "https://www.imdb.com/list/ls123456789/"
|
|
nullable: true
|
|
reverseOrder:
|
|
type: boolean
|
|
description: "Reverse the order of items from the source"
|
|
example: false
|
|
nullable: true
|
|
randomizeOrder:
|
|
type: boolean
|
|
description: "Randomize the order of items (mutually exclusive with reverseOrder)"
|
|
example: false
|
|
nullable: true
|
|
timeRestriction:
|
|
type: object
|
|
description: "Time restriction settings for the collection"
|
|
properties:
|
|
alwaysActive:
|
|
type: boolean
|
|
description: "If true, collection is always active (default)"
|
|
example: true
|
|
removeFromPlexWhenInactive:
|
|
type: boolean
|
|
description: "If true, completely remove from Plex when inactive (old behavior)"
|
|
example: false
|
|
nullable: true
|
|
inactiveVisibilityConfig:
|
|
type: object
|
|
description: "Visibility settings to use when collection is inactive (only used if removeFromPlexWhenInactive is false)"
|
|
properties:
|
|
usersHome:
|
|
type: boolean
|
|
description: "Show on shared users' home screens when inactive"
|
|
example: false
|
|
serverOwnerHome:
|
|
type: boolean
|
|
description: "Show on server owner's home screen when inactive"
|
|
example: false
|
|
libraryRecommended:
|
|
type: boolean
|
|
description: "Show in library recommended section when inactive"
|
|
example: true
|
|
required:
|
|
- usersHome
|
|
- serverOwnerHome
|
|
- libraryRecommended
|
|
nullable: true
|
|
dateRanges:
|
|
type: array
|
|
description: "Date ranges when collection should be active (repeated annually)"
|
|
items:
|
|
type: object
|
|
properties:
|
|
startDate:
|
|
type: string
|
|
description: "DD-MM format (e.g., '05-12' for 5th December)"
|
|
example: "05-12"
|
|
endDate:
|
|
type: string
|
|
description: "DD-MM format (e.g., '26-12' for 26th December)"
|
|
example: "26-12"
|
|
required:
|
|
- startDate
|
|
- endDate
|
|
nullable: true
|
|
weeklySchedule:
|
|
type: object
|
|
description: "Days of the week when collection should be active"
|
|
properties:
|
|
monday:
|
|
type: boolean
|
|
example: true
|
|
tuesday:
|
|
type: boolean
|
|
example: true
|
|
wednesday:
|
|
type: boolean
|
|
example: true
|
|
thursday:
|
|
type: boolean
|
|
example: true
|
|
friday:
|
|
type: boolean
|
|
example: true
|
|
saturday:
|
|
type: boolean
|
|
example: false
|
|
sunday:
|
|
type: boolean
|
|
example: false
|
|
nullable: true
|
|
nullable: true
|
|
isActive:
|
|
type: boolean
|
|
description: "Whether collection is currently active (time restrictions met)"
|
|
example: true
|
|
readOnly: true
|
|
collectionType:
|
|
type: string
|
|
enum: ['default_plex_hub', 'agregarr_created', 'pre_existing']
|
|
description: "Backend categorization system for different collection types"
|
|
example: 'agregarr_created'
|
|
nullable: true
|
|
isLinked:
|
|
type: boolean
|
|
description: "Whether collection is actively linked to other collections"
|
|
example: true
|
|
nullable: true
|
|
isUnlinked:
|
|
type: boolean
|
|
description: "True if this collection was deliberately unlinked and should not be grouped with siblings"
|
|
example: false
|
|
nullable: true
|
|
missing:
|
|
type: boolean
|
|
description: "True if collection no longer exists in Plex"
|
|
example: false
|
|
lastSyncedAt:
|
|
type: string
|
|
format: date-time
|
|
description: "ISO timestamp of last successful sync to Plex"
|
|
example: "2024-01-15T10:30:00.000Z"
|
|
nullable: true
|
|
lastModifiedAt:
|
|
type: string
|
|
format: date-time
|
|
description: "ISO timestamp when config was last modified"
|
|
example: "2024-01-15T09:15:00.000Z"
|
|
nullable: true
|
|
needsSync:
|
|
type: boolean
|
|
description: "True if collection has been modified and needs to be synced to Plex"
|
|
example: false
|
|
nullable: true
|
|
required:
|
|
- id
|
|
- name
|
|
- type
|
|
- subtype
|
|
- template
|
|
- visibilityConfig
|
|
- maxItems
|
|
CollectionConfigCreate:
|
|
type: object
|
|
description: "Schema for creating a new collection configuration"
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: "Empty string for new collections (will be assigned sequential number by backend)"
|
|
example: ""
|
|
name:
|
|
type: string
|
|
example: "User Requests"
|
|
type:
|
|
type: string
|
|
enum: ['overseerr', 'tautulli', 'trakt', 'tmdb', 'imdb', 'letterboxd', 'networks']
|
|
example: 'overseerr'
|
|
subtype:
|
|
type: string
|
|
example: 'users'
|
|
template:
|
|
type: string
|
|
example: "{nickname}'s Requests"
|
|
customMovieTemplate:
|
|
type: string
|
|
description: "Custom template for movie collections when mediaType is 'both'"
|
|
example: "{nickname}'s Movie Requests"
|
|
nullable: true
|
|
customTVTemplate:
|
|
type: string
|
|
description: "Custom template for TV collections when mediaType is 'both'"
|
|
example: "{nickname}'s TV Requests"
|
|
nullable: true
|
|
customPoster:
|
|
oneOf:
|
|
- type: string
|
|
description: "Filename of custom poster image (legacy format)"
|
|
example: "f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
- type: object
|
|
description: "Per-library poster mapping (libraryId -> filename)"
|
|
additionalProperties:
|
|
type: string
|
|
example:
|
|
lib1: "f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
lib2: "a12bc34d-58cc-4372-a567-0e02b2c3d480.jpg"
|
|
nullable: true
|
|
autoPoster:
|
|
type: boolean
|
|
description: "Auto-generate poster during sync"
|
|
example: true
|
|
nullable: true
|
|
visibilityConfig:
|
|
type: object
|
|
properties:
|
|
usersHome:
|
|
type: boolean
|
|
description: "Show on shared users' home screens"
|
|
example: true
|
|
serverOwnerHome:
|
|
type: boolean
|
|
description: "Show on server owner's home screen"
|
|
example: false
|
|
libraryRecommended:
|
|
type: boolean
|
|
description: "Show in library recommended section"
|
|
example: false
|
|
required:
|
|
- usersHome
|
|
- serverOwnerHome
|
|
- libraryRecommended
|
|
maxItems:
|
|
type: integer
|
|
example: 20
|
|
mediaType:
|
|
type: string
|
|
enum: ['movie', 'tv', 'both']
|
|
example: 'both'
|
|
libraryId:
|
|
type: string
|
|
description: "Selected library ID - each config is for exactly one library (optional when mediaType is 'both')"
|
|
example: "1"
|
|
libraryName:
|
|
type: string
|
|
description: "Selected library name for display (optional when mediaType is 'both')"
|
|
example: "Movies"
|
|
libraryIds:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: "Array of library IDs when mediaType is 'both' (backend expands into individual configs)"
|
|
example: ["1", "2"]
|
|
libraryNames:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: "Array of library names when mediaType is 'both' (backend expands into individual configs)"
|
|
example: ["Movies", "TV Shows"]
|
|
sortOrderHome:
|
|
type: integer
|
|
description: "Order for Plex home screen (creation time based)"
|
|
example: 0
|
|
nullable: true
|
|
sortOrderLibrary:
|
|
type: integer
|
|
description: "Order for Plex library tab (sortTitle based)"
|
|
example: 0
|
|
nullable: true
|
|
customDays:
|
|
type: integer
|
|
description: "Number of days for Tautulli collections (required for Tautulli type)"
|
|
example: 30
|
|
nullable: true
|
|
minimumPlays:
|
|
type: integer
|
|
description: "Minimum play count for Tautulli collections (defaults to 3 if not set, 1-100)"
|
|
example: 3
|
|
nullable: true
|
|
tautulliStatType:
|
|
type: string
|
|
enum: ['plays', 'duration']
|
|
description: "Tautulli statistic type: plays (play count) or duration (watch time)"
|
|
example: 'plays'
|
|
nullable: true
|
|
searchMissingMovies:
|
|
type: boolean
|
|
description: "Auto-request missing movies"
|
|
example: false
|
|
nullable: true
|
|
searchMissingTV:
|
|
type: boolean
|
|
description: "Auto-request missing TV shows"
|
|
example: false
|
|
nullable: true
|
|
autoApproveMovies:
|
|
type: boolean
|
|
description: "Auto-approve movie requests"
|
|
example: false
|
|
nullable: true
|
|
autoApproveTV:
|
|
type: boolean
|
|
description: "Auto-approve TV show requests"
|
|
example: false
|
|
nullable: true
|
|
maxSeasonsToRequest:
|
|
type: integer
|
|
description: "Max seasons for auto-approval (TV shows with more seasons require manual approval)"
|
|
example: 5
|
|
nullable: true
|
|
seasonsPerShowLimit:
|
|
type: integer
|
|
description: "Limit each TV show to only the first X seasons (0 = all seasons)"
|
|
example: 2
|
|
nullable: true
|
|
traktCustomListUrl:
|
|
type: string
|
|
description: "Custom Trakt list URL (e.g., https://trakt.tv/users/username/lists/list-name or https://trakt.tv/lists/official/collection-name)"
|
|
example: "https://trakt.tv/users/username/lists/my-list"
|
|
nullable: true
|
|
tmdbCustomListUrl:
|
|
type: string
|
|
description: "Custom TMDb list/collection URL (e.g., https://www.themoviedb.org/list/123456)"
|
|
example: "https://www.themoviedb.org/collection/123456"
|
|
nullable: true
|
|
imdbCustomListUrl:
|
|
type: string
|
|
description: "Custom IMDb list URL (e.g., https://www.imdb.com/list/ls123456789/)"
|
|
example: "https://www.imdb.com/list/ls123456789/"
|
|
nullable: true
|
|
reverseOrder:
|
|
type: boolean
|
|
description: "Reverse the order of items from the source"
|
|
example: false
|
|
nullable: true
|
|
randomizeOrder:
|
|
type: boolean
|
|
description: "Randomize the order of items (mutually exclusive with reverseOrder)"
|
|
example: false
|
|
nullable: true
|
|
timeRestriction:
|
|
type: object
|
|
description: "Time restriction settings for the collection"
|
|
properties:
|
|
alwaysActive:
|
|
type: boolean
|
|
description: "If true, collection is always active (default)"
|
|
example: true
|
|
removeFromPlexWhenInactive:
|
|
type: boolean
|
|
description: "If true, completely remove from Plex when inactive (old behavior)"
|
|
example: false
|
|
nullable: true
|
|
inactiveVisibilityConfig:
|
|
type: object
|
|
description: "Visibility settings to use when collection is inactive (only used if removeFromPlexWhenInactive is false)"
|
|
properties:
|
|
usersHome:
|
|
type: boolean
|
|
description: "Show on shared users' home screens when inactive"
|
|
example: false
|
|
serverOwnerHome:
|
|
type: boolean
|
|
description: "Show on server owner's home screen when inactive"
|
|
example: false
|
|
libraryRecommended:
|
|
type: boolean
|
|
description: "Show in library recommended section when inactive"
|
|
example: true
|
|
required:
|
|
- usersHome
|
|
- serverOwnerHome
|
|
- libraryRecommended
|
|
nullable: true
|
|
dateRanges:
|
|
type: array
|
|
description: "Date ranges when collection should be active (repeated annually)"
|
|
items:
|
|
type: object
|
|
properties:
|
|
startDate:
|
|
type: string
|
|
description: "DD-MM format (e.g., '05-12' for 5th December)"
|
|
example: "05-12"
|
|
endDate:
|
|
type: string
|
|
description: "DD-MM format (e.g., '26-12' for 26th December)"
|
|
example: "26-12"
|
|
required:
|
|
- startDate
|
|
- endDate
|
|
nullable: true
|
|
weeklySchedule:
|
|
type: object
|
|
description: "Days of the week when collection should be active"
|
|
properties:
|
|
monday:
|
|
type: boolean
|
|
example: true
|
|
tuesday:
|
|
type: boolean
|
|
example: true
|
|
wednesday:
|
|
type: boolean
|
|
example: true
|
|
thursday:
|
|
type: boolean
|
|
example: true
|
|
friday:
|
|
type: boolean
|
|
example: true
|
|
saturday:
|
|
type: boolean
|
|
example: false
|
|
sunday:
|
|
type: boolean
|
|
example: false
|
|
nullable: true
|
|
nullable: true
|
|
required:
|
|
- id
|
|
- name
|
|
- visibilityConfig
|
|
- maxItems
|
|
|
|
CollectionConfigUpdate:
|
|
type: object
|
|
description: "Schema for updating collection configuration settings (excludes computed fields)"
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: "Unique collection identifier (sequential number starting from 10000)"
|
|
example: "10000"
|
|
name:
|
|
type: string
|
|
example: "User Requests"
|
|
type:
|
|
type: string
|
|
enum: ['overseerr', 'tautulli', 'trakt', 'tmdb', 'imdb', 'letterboxd', 'networks']
|
|
example: 'overseerr'
|
|
subtype:
|
|
type: string
|
|
example: 'users'
|
|
template:
|
|
type: string
|
|
example: "{nickname}'s Requests"
|
|
customMovieTemplate:
|
|
type: string
|
|
description: "Custom template for movie collections when mediaType is 'both'"
|
|
example: "{nickname}'s Movie Requests"
|
|
nullable: true
|
|
customTVTemplate:
|
|
type: string
|
|
description: "Custom template for TV collections when mediaType is 'both'"
|
|
example: "{nickname}'s TV Requests"
|
|
nullable: true
|
|
customPoster:
|
|
oneOf:
|
|
- type: string
|
|
description: "Filename of custom poster image (legacy format)"
|
|
example: "f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
- type: object
|
|
description: "Per-library poster mapping (libraryId -> filename)"
|
|
additionalProperties:
|
|
type: string
|
|
example:
|
|
lib1: "f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
lib2: "a12bc34d-58cc-4372-a567-0e02b2c3d480.jpg"
|
|
nullable: true
|
|
autoPoster:
|
|
type: boolean
|
|
description: "Auto-generate poster during sync"
|
|
example: true
|
|
nullable: true
|
|
visibilityConfig:
|
|
type: object
|
|
properties:
|
|
usersHome:
|
|
type: boolean
|
|
description: "Show on shared users' home screens"
|
|
example: true
|
|
serverOwnerHome:
|
|
type: boolean
|
|
description: "Show on server owner's home screen"
|
|
example: false
|
|
libraryRecommended:
|
|
type: boolean
|
|
description: "Show in library recommended section"
|
|
example: false
|
|
required:
|
|
- usersHome
|
|
- serverOwnerHome
|
|
- libraryRecommended
|
|
maxItems:
|
|
type: integer
|
|
example: 20
|
|
mediaType:
|
|
type: string
|
|
enum: ['movie', 'tv', 'both']
|
|
example: 'both'
|
|
libraryIds:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: "Array of selected library IDs (['all'] for all libraries)"
|
|
example: ["1", "2"]
|
|
nullable: true
|
|
libraryName:
|
|
type: string
|
|
description: "Selected library name for display"
|
|
example: "Movies"
|
|
nullable: true
|
|
sortOrderHome:
|
|
type: integer
|
|
description: "Order for Plex home screen (creation time based)"
|
|
example: 0
|
|
nullable: true
|
|
sortOrderLibrary:
|
|
type: integer
|
|
description: "Position in library (0 for A-Z section, 1+ for promoted section)"
|
|
example: 0
|
|
nullable: true
|
|
isLibraryPromoted:
|
|
type: boolean
|
|
description: "true = promoted section (uses exclamation marks), false = A-Z section"
|
|
example: true
|
|
parentConfigId:
|
|
type: integer
|
|
description: "Reference to original config when expanded from 'all' libraries"
|
|
example: 1
|
|
nullable: true
|
|
isExpandedConfig:
|
|
type: boolean
|
|
description: "True if this config was auto-generated from a parent 'all' config"
|
|
example: false
|
|
nullable: true
|
|
customDays:
|
|
type: integer
|
|
description: "Number of days for Tautulli collections (required for Tautulli type)"
|
|
example: 30
|
|
nullable: true
|
|
minimumPlays:
|
|
type: integer
|
|
description: "Minimum play count for Tautulli collections (defaults to 3 if not set, 1-100)"
|
|
example: 3
|
|
nullable: true
|
|
tautulliStatType:
|
|
type: string
|
|
enum: ['plays', 'duration']
|
|
example: 'plays'
|
|
nullable: true
|
|
libraryNames:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: "Array of selected library names for display"
|
|
example: ["Movies", "TV Shows"]
|
|
nullable: true
|
|
searchMissingMovies:
|
|
type: boolean
|
|
description: "Automatically search for missing movies"
|
|
example: false
|
|
nullable: true
|
|
searchMissingTV:
|
|
type: boolean
|
|
description: "Automatically search for missing TV shows"
|
|
example: false
|
|
nullable: true
|
|
autoApproveMovies:
|
|
type: boolean
|
|
description: "Auto-approve movie requests"
|
|
example: false
|
|
nullable: true
|
|
autoApproveTV:
|
|
type: boolean
|
|
description: "Auto-approve TV show requests"
|
|
example: false
|
|
nullable: true
|
|
maxSeasonsToRequest:
|
|
type: integer
|
|
description: "Max seasons for auto-approval (TV shows with more seasons require manual approval)"
|
|
example: 5
|
|
nullable: true
|
|
seasonsPerShowLimit:
|
|
type: integer
|
|
description: "Limit each TV show to only the first X seasons (0 = all seasons)"
|
|
example: 2
|
|
nullable: true
|
|
traktCustomListUrl:
|
|
type: string
|
|
description: "Custom Trakt list URL (e.g., https://trakt.tv/users/username/lists/list-name or https://trakt.tv/lists/official/collection-name)"
|
|
example: "https://trakt.tv/users/username/lists/my-list"
|
|
nullable: true
|
|
tmdbCustomListUrl:
|
|
type: string
|
|
description: "Custom TMDb list/collection URL (e.g., https://www.themoviedb.org/list/123456)"
|
|
example: "https://www.themoviedb.org/collection/123456"
|
|
nullable: true
|
|
imdbCustomListUrl:
|
|
type: string
|
|
description: "Custom IMDb list URL (e.g., https://www.imdb.com/list/ls123456789/)"
|
|
example: "https://www.imdb.com/list/ls123456789/"
|
|
nullable: true
|
|
letterboxdCustomListUrl:
|
|
type: string
|
|
description: "Custom Letterboxd list URL (e.g., https://letterboxd.com/user/list/list-name/)"
|
|
example: "https://letterboxd.com/user/list/my-list/"
|
|
nullable: true
|
|
networksCountry:
|
|
type: string
|
|
description: "Selected country for Networks collections (e.g., 'united-states', 'world')"
|
|
example: "united-states"
|
|
nullable: true
|
|
reverseOrder:
|
|
type: boolean
|
|
description: "Reverse the order of items from the source"
|
|
example: false
|
|
nullable: true
|
|
randomizeOrder:
|
|
type: boolean
|
|
description: "Randomize the order of items (mutually exclusive with reverseOrder)"
|
|
example: false
|
|
nullable: true
|
|
timeRestriction:
|
|
type: object
|
|
description: "Time restriction settings for the collection"
|
|
properties:
|
|
alwaysActive:
|
|
type: boolean
|
|
description: "If true, collection is always active (default)"
|
|
example: true
|
|
removeFromPlexWhenInactive:
|
|
type: boolean
|
|
description: "If true, remove collection from Plex when inactive"
|
|
example: false
|
|
timeSlots:
|
|
type: array
|
|
description: "Array of time slot objects"
|
|
items:
|
|
type: object
|
|
properties:
|
|
startTime:
|
|
type: string
|
|
description: "HH:MM format"
|
|
example: "09:00"
|
|
endTime:
|
|
type: string
|
|
description: "HH:MM format"
|
|
example: "17:00"
|
|
nullable: true
|
|
dateRanges:
|
|
type: array
|
|
description: "Array of date range objects"
|
|
items:
|
|
type: object
|
|
properties:
|
|
startDate:
|
|
type: string
|
|
description: "DD-MM format"
|
|
example: "05-12"
|
|
endDate:
|
|
type: string
|
|
description: "DD-MM format"
|
|
example: "26-12"
|
|
nullable: true
|
|
weeklySchedule:
|
|
type: object
|
|
description: "Days of the week when collection should be active"
|
|
properties:
|
|
monday:
|
|
type: boolean
|
|
example: true
|
|
tuesday:
|
|
type: boolean
|
|
example: true
|
|
wednesday:
|
|
type: boolean
|
|
example: true
|
|
thursday:
|
|
type: boolean
|
|
example: true
|
|
friday:
|
|
type: boolean
|
|
example: true
|
|
saturday:
|
|
type: boolean
|
|
example: false
|
|
sunday:
|
|
type: boolean
|
|
example: false
|
|
nullable: true
|
|
nullable: true
|
|
collectionType:
|
|
type: string
|
|
enum: ['default_plex_hub', 'agregarr_created', 'pre_existing']
|
|
description: "Backend categorization system for different collection types"
|
|
example: 'agregarr_created'
|
|
nullable: true
|
|
isLinked:
|
|
type: boolean
|
|
description: "Whether collection is actively linked to other collections"
|
|
example: true
|
|
nullable: true
|
|
isUnlinked:
|
|
type: boolean
|
|
description: "True if this collection was deliberately unlinked and should not be grouped with siblings"
|
|
example: false
|
|
nullable: true
|
|
missing:
|
|
type: boolean
|
|
description: "True if collection no longer exists in Plex"
|
|
example: false
|
|
required:
|
|
- id
|
|
- name
|
|
- type
|
|
- subtype
|
|
- template
|
|
- visibilityConfig
|
|
- maxItems
|
|
|
|
PlexHubConfig:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: "Unique hub identifier (libraryId-hubIdentifier)"
|
|
example: "1-movie.recentlyadded"
|
|
hubIdentifier:
|
|
type: string
|
|
description: "Plex built-in hub identifier"
|
|
example: "movie.recentlyadded"
|
|
name:
|
|
type: string
|
|
description: "Display name for the hub"
|
|
example: "Recently Added Movies"
|
|
libraryId:
|
|
type: string
|
|
description: "Plex library ID"
|
|
example: "1"
|
|
libraryName:
|
|
type: string
|
|
description: "Plex library display name"
|
|
example: "Films"
|
|
mediaType:
|
|
type: string
|
|
enum: ['movie', 'tv', 'both']
|
|
description: "Media type of the hub"
|
|
example: 'movie'
|
|
sortOrderLibrary:
|
|
type: integer
|
|
description: "Position/order within the library"
|
|
example: 0
|
|
visibilityConfig:
|
|
type: object
|
|
properties:
|
|
usersHome:
|
|
type: boolean
|
|
description: "Show on shared users' home screens"
|
|
example: true
|
|
serverOwnerHome:
|
|
type: boolean
|
|
description: "Show on server owner's home screen"
|
|
example: false
|
|
libraryRecommended:
|
|
type: boolean
|
|
description: "Show in library recommended section"
|
|
example: false
|
|
required:
|
|
- usersHome
|
|
- serverOwnerHome
|
|
- libraryRecommended
|
|
isActive:
|
|
type: boolean
|
|
description: "Whether hub is currently active (always true for built-in hubs, time restrictions for collections)"
|
|
example: true
|
|
readOnly: true
|
|
isLinked:
|
|
type: boolean
|
|
description: "True if hub is actively linked to other hubs"
|
|
example: false
|
|
linkId:
|
|
type: integer
|
|
description: "Group ID for linked hubs (preserved even when isLinked=false)"
|
|
example: 1
|
|
isUnlinked:
|
|
type: boolean
|
|
description: "True if this hub was deliberately unlinked and should not be grouped with siblings"
|
|
example: false
|
|
missing:
|
|
type: boolean
|
|
description: "True if hub no longer exists in Plex"
|
|
example: false
|
|
lastSyncedAt:
|
|
type: string
|
|
format: date-time
|
|
description: "ISO timestamp of last successful sync to Plex"
|
|
example: "2024-01-15T10:30:00.000Z"
|
|
nullable: true
|
|
lastModifiedAt:
|
|
type: string
|
|
format: date-time
|
|
description: "ISO timestamp when config was last modified"
|
|
example: "2024-01-15T09:15:00.000Z"
|
|
nullable: true
|
|
needsSync:
|
|
type: boolean
|
|
description: "True if hub has been modified and needs to be synced to Plex"
|
|
example: false
|
|
nullable: true
|
|
required:
|
|
- id
|
|
- hubIdentifier
|
|
- name
|
|
- libraryId
|
|
- libraryName
|
|
- mediaType
|
|
- sortOrderLibrary
|
|
- visibilityConfig
|
|
- isActive
|
|
|
|
PlexHubConfigUpdate:
|
|
type: object
|
|
description: "Schema for updating PlexHubConfig settings (excludes computed fields)"
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: "Unique hub identifier (libraryId-hubIdentifier)"
|
|
example: "1-movie.recentlyadded"
|
|
hubIdentifier:
|
|
type: string
|
|
description: "Plex built-in hub identifier"
|
|
example: "movie.recentlyadded"
|
|
name:
|
|
type: string
|
|
description: "Display name for the hub"
|
|
example: "Recently Added Movies"
|
|
libraryId:
|
|
type: string
|
|
description: "Plex library ID"
|
|
example: "1"
|
|
libraryName:
|
|
type: string
|
|
description: "Plex library display name"
|
|
example: "Films"
|
|
mediaType:
|
|
type: string
|
|
enum: ['movie', 'tv', 'both']
|
|
description: "Media type of the hub"
|
|
example: 'movie'
|
|
sortOrderHome:
|
|
type: integer
|
|
description: "Position/order on Plex home screen"
|
|
example: 0
|
|
sortOrderLibrary:
|
|
type: integer
|
|
description: "Position/order within the library"
|
|
example: 0
|
|
isLibraryPromoted:
|
|
type: boolean
|
|
description: "true = promoted section (uses exclamation marks), false = A-Z section"
|
|
example: false
|
|
visibilityConfig:
|
|
type: object
|
|
properties:
|
|
usersHome:
|
|
type: boolean
|
|
description: "Show on shared users' home screens"
|
|
example: true
|
|
serverOwnerHome:
|
|
type: boolean
|
|
description: "Show on server owner's home screen"
|
|
example: false
|
|
libraryRecommended:
|
|
type: boolean
|
|
description: "Show in library recommended section"
|
|
example: false
|
|
required:
|
|
- usersHome
|
|
- serverOwnerHome
|
|
- libraryRecommended
|
|
isLinked:
|
|
type: boolean
|
|
description: "True if hub is actively linked to other hubs"
|
|
example: false
|
|
linkId:
|
|
type: integer
|
|
description: "Group ID for linked hubs (preserved even when isLinked=false)"
|
|
example: 1
|
|
isUnlinked:
|
|
type: boolean
|
|
description: "True if this hub was deliberately unlinked and should not be grouped with siblings"
|
|
example: false
|
|
missing:
|
|
type: boolean
|
|
description: "True if hub no longer exists in Plex"
|
|
example: false
|
|
timeRestriction:
|
|
type: object
|
|
description: "Time restriction settings for the hub"
|
|
properties:
|
|
alwaysActive:
|
|
type: boolean
|
|
description: "If true, hub is always active (default)"
|
|
example: true
|
|
removeFromPlexWhenInactive:
|
|
type: boolean
|
|
description: "If true, remove hub from Plex when inactive"
|
|
example: false
|
|
timeSlots:
|
|
type: array
|
|
description: "Array of time slot objects"
|
|
items:
|
|
type: object
|
|
properties:
|
|
startTime:
|
|
type: string
|
|
description: "HH:MM format"
|
|
example: "09:00"
|
|
endTime:
|
|
type: string
|
|
description: "HH:MM format"
|
|
example: "17:00"
|
|
nullable: true
|
|
dateRanges:
|
|
type: array
|
|
description: "Array of date range objects"
|
|
items:
|
|
type: object
|
|
properties:
|
|
startDate:
|
|
type: string
|
|
description: "DD-MM format"
|
|
example: "05-12"
|
|
endDate:
|
|
type: string
|
|
description: "DD-MM format"
|
|
example: "26-12"
|
|
nullable: true
|
|
weeklySchedule:
|
|
type: object
|
|
properties:
|
|
monday:
|
|
type: boolean
|
|
tuesday:
|
|
type: boolean
|
|
wednesday:
|
|
type: boolean
|
|
thursday:
|
|
type: boolean
|
|
friday:
|
|
type: boolean
|
|
saturday:
|
|
type: boolean
|
|
sunday:
|
|
type: boolean
|
|
nullable: true
|
|
nullable: true
|
|
required:
|
|
- id
|
|
- hubIdentifier
|
|
- name
|
|
- libraryId
|
|
- libraryName
|
|
- mediaType
|
|
- sortOrderLibrary
|
|
- visibilityConfig
|
|
|
|
PreExistingCollectionConfig:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: "Unique collection identifier (libraryId-collectionRatingKey)"
|
|
example: "1-35954"
|
|
collectionRatingKey:
|
|
type: string
|
|
description: "Plex collection rating key"
|
|
example: "35954"
|
|
name:
|
|
type: string
|
|
description: "Display name from Plex"
|
|
example: "Action Movies"
|
|
libraryId:
|
|
type: string
|
|
description: "Plex library ID"
|
|
example: "1"
|
|
libraryName:
|
|
type: string
|
|
description: "Plex library display name"
|
|
example: "Films"
|
|
mediaType:
|
|
type: string
|
|
enum: ['movie', 'tv', 'both']
|
|
description: "Media type based on collection contents"
|
|
example: 'movie'
|
|
sortOrderHome:
|
|
type: integer
|
|
description: "Position on Plex home screen"
|
|
example: 0
|
|
sortOrderLibrary:
|
|
type: integer
|
|
description: "Position in library (0 for A-Z section, 1+ for promoted section)"
|
|
example: 0
|
|
isLibraryPromoted:
|
|
type: boolean
|
|
description: "true = promoted section (uses exclamation marks), false = A-Z section"
|
|
example: false
|
|
visibilityConfig:
|
|
type: object
|
|
properties:
|
|
usersHome:
|
|
type: boolean
|
|
description: "Show on shared users' home screens"
|
|
example: true
|
|
serverOwnerHome:
|
|
type: boolean
|
|
description: "Show on server owner's home screen"
|
|
example: false
|
|
libraryRecommended:
|
|
type: boolean
|
|
description: "Show in library recommended section"
|
|
example: false
|
|
required:
|
|
- usersHome
|
|
- serverOwnerHome
|
|
- libraryRecommended
|
|
isActive:
|
|
type: boolean
|
|
description: "Whether collection is currently active (computed from time restrictions)"
|
|
example: true
|
|
readOnly: true
|
|
collectionType:
|
|
type: string
|
|
enum: ['default_plex_hub', 'agregarr_created', 'pre_existing']
|
|
description: "Type of collection (determined during discovery)"
|
|
example: 'pre_existing'
|
|
readOnly: true
|
|
isLinked:
|
|
type: boolean
|
|
description: "True if collection is actively linked to other collections"
|
|
example: false
|
|
linkId:
|
|
type: integer
|
|
description: "Group ID for linked collections (preserved even when isLinked=false)"
|
|
example: 1
|
|
isUnlinked:
|
|
type: boolean
|
|
description: "True if this collection was deliberately unlinked and should not be grouped with siblings"
|
|
example: false
|
|
nullable: true
|
|
timeRestriction:
|
|
type: object
|
|
properties:
|
|
alwaysActive:
|
|
type: boolean
|
|
description: "If true, collection is always active (default)"
|
|
example: true
|
|
removeFromPlexWhenInactive:
|
|
type: boolean
|
|
description: "If true, completely remove from Plex when inactive"
|
|
example: false
|
|
nullable: true
|
|
inactiveVisibilityConfig:
|
|
type: object
|
|
properties:
|
|
usersHome:
|
|
type: boolean
|
|
serverOwnerHome:
|
|
type: boolean
|
|
libraryRecommended:
|
|
type: boolean
|
|
nullable: true
|
|
dateRanges:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
startDate:
|
|
type: string
|
|
description: "DD-MM format (e.g., '05-12' for 5th December)"
|
|
example: "05-12"
|
|
endDate:
|
|
type: string
|
|
description: "DD-MM format (e.g., '26-12' for 26th December)"
|
|
example: "26-12"
|
|
required:
|
|
- startDate
|
|
- endDate
|
|
nullable: true
|
|
weeklySchedule:
|
|
type: object
|
|
properties:
|
|
monday:
|
|
type: boolean
|
|
tuesday:
|
|
type: boolean
|
|
wednesday:
|
|
type: boolean
|
|
thursday:
|
|
type: boolean
|
|
friday:
|
|
type: boolean
|
|
saturday:
|
|
type: boolean
|
|
sunday:
|
|
type: boolean
|
|
nullable: true
|
|
required:
|
|
- alwaysActive
|
|
nullable: true
|
|
customPoster:
|
|
type: string
|
|
description: "Path to custom poster image file"
|
|
example: "/app/config/poster-123.jpg"
|
|
nullable: true
|
|
autoPoster:
|
|
type: boolean
|
|
description: "Auto-generate poster during sync"
|
|
example: true
|
|
nullable: true
|
|
missing:
|
|
type: boolean
|
|
description: "True if collection no longer exists in Plex"
|
|
example: false
|
|
lastSyncedAt:
|
|
type: string
|
|
format: date-time
|
|
description: "ISO timestamp of last successful sync to Plex"
|
|
example: "2024-01-15T10:30:00.000Z"
|
|
nullable: true
|
|
lastModifiedAt:
|
|
type: string
|
|
format: date-time
|
|
description: "ISO timestamp when config was last modified"
|
|
example: "2024-01-15T09:15:00.000Z"
|
|
nullable: true
|
|
needsSync:
|
|
type: boolean
|
|
description: "True if collection has been modified and needs to be synced to Plex"
|
|
example: false
|
|
nullable: true
|
|
required:
|
|
- id
|
|
- collectionRatingKey
|
|
- name
|
|
- libraryId
|
|
- libraryName
|
|
- mediaType
|
|
- sortOrderHome
|
|
- sortOrderLibrary
|
|
- visibilityConfig
|
|
- isActive
|
|
|
|
PreExistingCollectionConfigUpdate:
|
|
type: object
|
|
description: "Schema for updating PreExistingCollectionConfig settings (excludes computed fields)"
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: "Unique collection identifier (libraryId-collectionRatingKey)"
|
|
example: "1-35954"
|
|
collectionRatingKey:
|
|
type: string
|
|
description: "Plex collection rating key"
|
|
example: "35954"
|
|
name:
|
|
type: string
|
|
description: "Display name from Plex"
|
|
example: "Action Movies"
|
|
libraryId:
|
|
type: string
|
|
description: "Plex library ID"
|
|
example: "1"
|
|
libraryName:
|
|
type: string
|
|
description: "Plex library display name"
|
|
example: "Films"
|
|
mediaType:
|
|
type: string
|
|
enum: ['movie', 'tv', 'both']
|
|
description: "Media type based on collection contents"
|
|
example: 'movie'
|
|
sortOrderHome:
|
|
type: integer
|
|
description: "Position on Plex home screen"
|
|
example: 0
|
|
sortOrderLibrary:
|
|
type: integer
|
|
description: "Position in library (0 for A-Z section, 1+ for promoted section)"
|
|
example: 0
|
|
isLibraryPromoted:
|
|
type: boolean
|
|
description: "true = promoted section (uses exclamation marks), false = A-Z section"
|
|
example: false
|
|
visibilityConfig:
|
|
type: object
|
|
properties:
|
|
usersHome:
|
|
type: boolean
|
|
description: "Show on shared users' home screens"
|
|
example: true
|
|
serverOwnerHome:
|
|
type: boolean
|
|
description: "Show on server owner's home screen"
|
|
example: false
|
|
libraryRecommended:
|
|
type: boolean
|
|
description: "Show in library recommended section"
|
|
example: false
|
|
required:
|
|
- usersHome
|
|
- serverOwnerHome
|
|
- libraryRecommended
|
|
isLinked:
|
|
type: boolean
|
|
description: "True if collection is actively linked to other collections"
|
|
example: false
|
|
linkId:
|
|
type: integer
|
|
description: "Group ID for linked collections (preserved even when isLinked=false)"
|
|
example: 1
|
|
isUnlinked:
|
|
type: boolean
|
|
description: "True if this collection was deliberately unlinked and should not be grouped with siblings"
|
|
example: false
|
|
timeRestriction:
|
|
type: object
|
|
description: "Time restriction settings for the collection"
|
|
properties:
|
|
alwaysActive:
|
|
type: boolean
|
|
description: "If true, collection is always active (default)"
|
|
example: true
|
|
removeFromPlexWhenInactive:
|
|
type: boolean
|
|
description: "If true, remove collection from Plex when inactive"
|
|
example: false
|
|
timeSlots:
|
|
type: array
|
|
description: "Array of time slot objects"
|
|
items:
|
|
type: object
|
|
properties:
|
|
startTime:
|
|
type: string
|
|
description: "HH:MM format"
|
|
example: "09:00"
|
|
endTime:
|
|
type: string
|
|
description: "HH:MM format"
|
|
example: "17:00"
|
|
nullable: true
|
|
dateRanges:
|
|
type: array
|
|
description: "Array of date range objects"
|
|
items:
|
|
type: object
|
|
properties:
|
|
startDate:
|
|
type: string
|
|
description: "DD-MM format"
|
|
example: "05-12"
|
|
endDate:
|
|
type: string
|
|
description: "DD-MM format"
|
|
example: "26-12"
|
|
nullable: true
|
|
weeklySchedule:
|
|
type: object
|
|
properties:
|
|
monday:
|
|
type: boolean
|
|
tuesday:
|
|
type: boolean
|
|
wednesday:
|
|
type: boolean
|
|
thursday:
|
|
type: boolean
|
|
friday:
|
|
type: boolean
|
|
saturday:
|
|
type: boolean
|
|
sunday:
|
|
type: boolean
|
|
nullable: true
|
|
required:
|
|
- alwaysActive
|
|
nullable: true
|
|
customPoster:
|
|
oneOf:
|
|
- type: string
|
|
description: "Filename of custom poster image (legacy format)"
|
|
example: "f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
- type: object
|
|
description: "Per-library poster mapping (libraryId -> filename)"
|
|
additionalProperties:
|
|
type: string
|
|
example:
|
|
lib1: "f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
lib2: "a12bc34d-58cc-4372-a567-0e02b2c3d480.jpg"
|
|
nullable: true
|
|
autoPoster:
|
|
type: boolean
|
|
description: "Auto-generate poster during sync"
|
|
example: true
|
|
nullable: true
|
|
missing:
|
|
type: boolean
|
|
description: "True if collection no longer exists in Plex"
|
|
example: false
|
|
required:
|
|
- id
|
|
- collectionRatingKey
|
|
- name
|
|
- libraryId
|
|
- libraryName
|
|
- mediaType
|
|
- sortOrderHome
|
|
- sortOrderLibrary
|
|
- visibilityConfig
|
|
|
|
DiscoveredCollectionConfig:
|
|
type: object
|
|
description: "Pre-existing collection config for discovery (collectionRatingKey is extracted server-side)"
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: "Unique collection identifier (libraryId-collectionRatingKey)"
|
|
example: "1:36466"
|
|
hubIdentifier:
|
|
type: string
|
|
description: "Plex hub identifier for the collection"
|
|
example: "custom.collection.1.36466"
|
|
name:
|
|
type: string
|
|
description: "Display name from Plex"
|
|
example: "movies that i like"
|
|
libraryId:
|
|
type: string
|
|
description: "Plex library ID"
|
|
example: "1"
|
|
libraryName:
|
|
type: string
|
|
description: "Plex library display name"
|
|
example: "Films"
|
|
mediaType:
|
|
type: string
|
|
enum: ['movie', 'tv', 'both']
|
|
description: "Media type based on collection contents"
|
|
example: 'movie'
|
|
sortOrderHome:
|
|
type: integer
|
|
description: "Position on Plex home screen"
|
|
example: 0
|
|
sortOrderLibrary:
|
|
type: integer
|
|
description: "Position in library"
|
|
example: 0
|
|
visibilityConfig:
|
|
type: object
|
|
properties:
|
|
usersHome:
|
|
type: boolean
|
|
example: false
|
|
serverOwnerHome:
|
|
type: boolean
|
|
example: true
|
|
libraryRecommended:
|
|
type: boolean
|
|
example: false
|
|
required:
|
|
- usersHome
|
|
- serverOwnerHome
|
|
- libraryRecommended
|
|
collectionType:
|
|
type: string
|
|
description: "Type of collection for discovery"
|
|
example: "pre_existing"
|
|
required:
|
|
- id
|
|
- name
|
|
- libraryId
|
|
- libraryName
|
|
- mediaType
|
|
- sortOrderHome
|
|
- sortOrderLibrary
|
|
- visibilityConfig
|
|
PlexConnection:
|
|
type: object
|
|
properties:
|
|
protocol:
|
|
type: string
|
|
example: 'https'
|
|
address:
|
|
type: string
|
|
example: '127.0.0.1'
|
|
port:
|
|
type: number
|
|
example: 32400
|
|
uri:
|
|
type: string
|
|
example: 'https://127-0-0-1.2ab6ce1a093d465e910def96cf4e4799.plex.direct:32400'
|
|
local:
|
|
type: boolean
|
|
example: true
|
|
status:
|
|
type: number
|
|
example: 200
|
|
message:
|
|
type: string
|
|
example: 'OK'
|
|
required:
|
|
- protocol
|
|
- address
|
|
- port
|
|
- uri
|
|
- local
|
|
PlexDevice:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
example: 'My Plex Server'
|
|
product:
|
|
type: string
|
|
example: 'Plex Media Server'
|
|
productVersion:
|
|
type: string
|
|
example: '1.21'
|
|
platform:
|
|
type: string
|
|
example: 'Linux'
|
|
platformVersion:
|
|
type: string
|
|
example: 'default/linux/amd64/17.1/systemd'
|
|
device:
|
|
type: string
|
|
example: 'PC'
|
|
clientIdentifier:
|
|
type: string
|
|
example: '85a943ce-a0cc-4d2a-a4ec-f74f06e40feb'
|
|
createdAt:
|
|
type: string
|
|
example: '2021-01-01T00:00:00.000Z'
|
|
lastSeenAt:
|
|
type: string
|
|
example: '2021-01-01T00:00:00.000Z'
|
|
provides:
|
|
type: array
|
|
items:
|
|
type: string
|
|
example: 'server'
|
|
owned:
|
|
type: boolean
|
|
example: true
|
|
ownerID:
|
|
type: string
|
|
example: '12345'
|
|
home:
|
|
type: boolean
|
|
example: true
|
|
sourceTitle:
|
|
type: string
|
|
example: 'xyzabc'
|
|
accessToken:
|
|
type: string
|
|
example: 'supersecretaccesstoken'
|
|
publicAddress:
|
|
type: string
|
|
example: '127.0.0.1'
|
|
httpsRequired:
|
|
type: boolean
|
|
example: true
|
|
synced:
|
|
type: boolean
|
|
example: true
|
|
relay:
|
|
type: boolean
|
|
example: true
|
|
dnsRebindingProtection:
|
|
type: boolean
|
|
example: false
|
|
natLoopbackSupported:
|
|
type: boolean
|
|
example: false
|
|
publicAddressMatches:
|
|
type: boolean
|
|
example: false
|
|
presence:
|
|
type: boolean
|
|
example: true
|
|
connection:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexConnection'
|
|
required:
|
|
- name
|
|
- product
|
|
- productVersion
|
|
- platform
|
|
- device
|
|
- clientIdentifier
|
|
- createdAt
|
|
- lastSeenAt
|
|
- provides
|
|
- owned
|
|
- connection
|
|
TautulliSettings:
|
|
type: object
|
|
properties:
|
|
hostname:
|
|
type: string
|
|
nullable: true
|
|
example: 'tautulli.example.com'
|
|
port:
|
|
type: number
|
|
nullable: true
|
|
example: 8181
|
|
useSsl:
|
|
type: boolean
|
|
nullable: true
|
|
urlBase:
|
|
type: string
|
|
nullable: true
|
|
example: '/tautulli'
|
|
apiKey:
|
|
type: string
|
|
nullable: true
|
|
externalUrl:
|
|
type: string
|
|
nullable: true
|
|
TraktSettings:
|
|
type: object
|
|
properties:
|
|
apiKey:
|
|
type: string
|
|
nullable: true
|
|
example: 'your-trakt-api-key-here'
|
|
OverseerrSettings:
|
|
type: object
|
|
properties:
|
|
hostname:
|
|
type: string
|
|
nullable: true
|
|
example: 'overseerr.example.com'
|
|
port:
|
|
type: number
|
|
nullable: true
|
|
example: 5055
|
|
useSsl:
|
|
type: boolean
|
|
nullable: true
|
|
example: false
|
|
urlBase:
|
|
type: string
|
|
nullable: true
|
|
example: '/overseerr'
|
|
apiKey:
|
|
type: string
|
|
nullable: true
|
|
example: 'your-agregarr-api-key-here'
|
|
externalUrl:
|
|
type: string
|
|
nullable: true
|
|
example: 'https://overseerr.example.com:5055'
|
|
ServiceUserSettings:
|
|
type: object
|
|
properties:
|
|
userCreationMode:
|
|
type: string
|
|
enum: ['single', 'per-service', 'granular']
|
|
example: 'per-service'
|
|
description: 'How to create service users - single (one Agregarr user), per-service (TraktAgregarr, TMDbAgregarr), or granular (TraktTrendingAgregarr, TMDbPopularAgregarr)'
|
|
RadarrSettings:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: number
|
|
example: 0
|
|
readOnly: true
|
|
name:
|
|
type: string
|
|
example: 'Radarr Main'
|
|
hostname:
|
|
type: string
|
|
example: '127.0.0.1'
|
|
port:
|
|
type: number
|
|
example: 7878
|
|
apiKey:
|
|
type: string
|
|
example: 'exampleapikey'
|
|
useSsl:
|
|
type: boolean
|
|
example: false
|
|
baseUrl:
|
|
type: string
|
|
activeProfileId:
|
|
type: number
|
|
example: 1
|
|
activeProfileName:
|
|
type: string
|
|
example: 720p/1080p
|
|
activeDirectory:
|
|
type: string
|
|
example: '/movies'
|
|
minimumAvailability:
|
|
type: string
|
|
example: 'In Cinema'
|
|
isDefault:
|
|
type: boolean
|
|
example: false
|
|
externalUrl:
|
|
type: string
|
|
example: http://radarr.example.com
|
|
syncEnabled:
|
|
type: boolean
|
|
example: false
|
|
preventSearch:
|
|
type: boolean
|
|
example: false
|
|
required:
|
|
- hostname
|
|
- port
|
|
- apiKey
|
|
- useSsl
|
|
- activeProfileId
|
|
- activeProfileName
|
|
- activeDirectory
|
|
- minimumAvailability
|
|
- isDefault
|
|
SonarrSettings:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: number
|
|
example: 0
|
|
readOnly: true
|
|
name:
|
|
type: string
|
|
example: 'Sonarr Main'
|
|
hostname:
|
|
type: string
|
|
example: '127.0.0.1'
|
|
port:
|
|
type: number
|
|
example: 8989
|
|
apiKey:
|
|
type: string
|
|
example: 'exampleapikey'
|
|
useSsl:
|
|
type: boolean
|
|
example: false
|
|
baseUrl:
|
|
type: string
|
|
activeProfileId:
|
|
type: number
|
|
example: 1
|
|
activeProfileName:
|
|
type: string
|
|
example: 720p/1080p
|
|
activeDirectory:
|
|
type: string
|
|
example: '/tv/'
|
|
activeLanguageProfileId:
|
|
type: number
|
|
example: 1
|
|
activeAnimeProfileId:
|
|
type: number
|
|
nullable: true
|
|
activeAnimeLanguageProfileId:
|
|
type: number
|
|
nullable: true
|
|
activeAnimeProfileName:
|
|
type: string
|
|
example: 720p/1080p
|
|
nullable: true
|
|
activeAnimeDirectory:
|
|
type: string
|
|
nullable: true
|
|
enableSeasonFolders:
|
|
type: boolean
|
|
example: false
|
|
isDefault:
|
|
type: boolean
|
|
example: false
|
|
externalUrl:
|
|
type: string
|
|
example: http://radarr.example.com
|
|
syncEnabled:
|
|
type: boolean
|
|
example: false
|
|
preventSearch:
|
|
type: boolean
|
|
example: false
|
|
required:
|
|
- hostname
|
|
- port
|
|
- apiKey
|
|
- useSsl
|
|
- activeProfileId
|
|
- activeProfileName
|
|
- activeDirectory
|
|
- isDefault
|
|
ServarrTag:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: number
|
|
example: 1
|
|
label:
|
|
type: string
|
|
example: A Label
|
|
PublicSettings:
|
|
type: object
|
|
properties:
|
|
initialized:
|
|
type: boolean
|
|
example: false
|
|
MovieResult:
|
|
type: object
|
|
required:
|
|
- id
|
|
- mediaType
|
|
- title
|
|
properties:
|
|
id:
|
|
type: number
|
|
example: 1234
|
|
mediaType:
|
|
type: string
|
|
popularity:
|
|
type: number
|
|
example: 10
|
|
posterPath:
|
|
type: string
|
|
backdropPath:
|
|
type: string
|
|
voteCount:
|
|
type: number
|
|
voteAverage:
|
|
type: number
|
|
genreIds:
|
|
type: array
|
|
items:
|
|
type: number
|
|
overview:
|
|
type: string
|
|
example: 'Overview of the movie'
|
|
originalLanguage:
|
|
type: string
|
|
example: 'en'
|
|
title:
|
|
type: string
|
|
example: Movie Title
|
|
originalTitle:
|
|
type: string
|
|
example: Original Movie Title
|
|
releaseDate:
|
|
type: string
|
|
adult:
|
|
type: boolean
|
|
example: false
|
|
video:
|
|
type: boolean
|
|
example: false
|
|
TvResult:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: number
|
|
example: 1234
|
|
mediaType:
|
|
type: string
|
|
popularity:
|
|
type: number
|
|
example: 10
|
|
posterPath:
|
|
type: string
|
|
backdropPath:
|
|
type: string
|
|
voteCount:
|
|
type: number
|
|
voteAverage:
|
|
type: number
|
|
genreIds:
|
|
type: array
|
|
items:
|
|
type: number
|
|
overview:
|
|
type: string
|
|
example: 'Overview of the movie'
|
|
originalLanguage:
|
|
type: string
|
|
example: 'en'
|
|
name:
|
|
type: string
|
|
example: TV Show Name
|
|
originalName:
|
|
type: string
|
|
example: Original TV Show Name
|
|
originCountry:
|
|
type: array
|
|
items:
|
|
type: string
|
|
firstAirDate:
|
|
type: string
|
|
PersonResult:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: number
|
|
example: 12345
|
|
profilePath:
|
|
type: string
|
|
adult:
|
|
type: boolean
|
|
example: false
|
|
mediaType:
|
|
type: string
|
|
default: 'person'
|
|
knownFor:
|
|
type: array
|
|
items:
|
|
oneOf:
|
|
- $ref: '#/components/schemas/MovieResult'
|
|
- $ref: '#/components/schemas/TvResult'
|
|
Genre:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: number
|
|
example: 1
|
|
name:
|
|
type: string
|
|
example: Adventure
|
|
Company:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: number
|
|
example: 1
|
|
logo_path:
|
|
type: string
|
|
nullable: true
|
|
name:
|
|
type: string
|
|
ProductionCompany:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: number
|
|
example: 1
|
|
logoPath:
|
|
type: string
|
|
nullable: true
|
|
originCountry:
|
|
type: string
|
|
name:
|
|
type: string
|
|
Network:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: number
|
|
example: 1
|
|
logoPath:
|
|
type: string
|
|
nullable: true
|
|
originCountry:
|
|
type: string
|
|
name:
|
|
type: string
|
|
RelatedVideo:
|
|
type: object
|
|
properties:
|
|
url:
|
|
type: string
|
|
example: https://www.youtube.com/watch?v=9qhL2_UxXM0/
|
|
key:
|
|
type: string
|
|
example: 9qhL2_UxXM0
|
|
name:
|
|
type: string
|
|
example: Trailer for some movie (1978)
|
|
size:
|
|
type: number
|
|
example: 1080
|
|
type:
|
|
type: string
|
|
example: Trailer
|
|
enum:
|
|
- Clip
|
|
- Teaser
|
|
- Trailer
|
|
- Featurette
|
|
- Opening Credits
|
|
- Behind the Scenes
|
|
- Bloopers
|
|
site:
|
|
type: string
|
|
enum:
|
|
- 'YouTube'
|
|
MovieDetails:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: number
|
|
example: 123
|
|
readOnly: true
|
|
imdbId:
|
|
type: string
|
|
example: 'tt123'
|
|
adult:
|
|
type: boolean
|
|
backdropPath:
|
|
type: string
|
|
posterPath:
|
|
type: string
|
|
budget:
|
|
type: number
|
|
example: 1000000
|
|
genres:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Genre'
|
|
homepage:
|
|
type: string
|
|
relatedVideos:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/RelatedVideo'
|
|
originalLanguage:
|
|
type: string
|
|
originalTitle:
|
|
type: string
|
|
overview:
|
|
type: string
|
|
popularity:
|
|
type: number
|
|
productionCompanies:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ProductionCompany'
|
|
productionCountries:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
iso_3166_1:
|
|
type: string
|
|
name:
|
|
type: string
|
|
releaseDate:
|
|
type: string
|
|
releases:
|
|
type: object
|
|
properties:
|
|
results:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
iso_3166_1:
|
|
type: string
|
|
example: 'US'
|
|
rating:
|
|
type: string
|
|
nullable: true
|
|
release_dates:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
certification:
|
|
type: string
|
|
example: 'PG-13'
|
|
iso_639_1:
|
|
type: string
|
|
nullable: true
|
|
note:
|
|
type: string
|
|
nullable: true
|
|
example: 'Blu ray'
|
|
release_date:
|
|
type: string
|
|
example: '2017-07-12T00:00:00.000Z'
|
|
type:
|
|
type: number
|
|
example: 1
|
|
revenue:
|
|
type: number
|
|
nullable: true
|
|
runtime:
|
|
type: number
|
|
status:
|
|
type: string
|
|
tagline:
|
|
type: string
|
|
title:
|
|
type: string
|
|
video:
|
|
type: boolean
|
|
voteAverage:
|
|
type: number
|
|
voteCount:
|
|
type: number
|
|
collection:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: number
|
|
example: 1
|
|
name:
|
|
type: string
|
|
example: A collection
|
|
posterPath:
|
|
type: string
|
|
backdropPath:
|
|
type: string
|
|
externalIds:
|
|
$ref: '#/components/schemas/ExternalIds'
|
|
watchProviders:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/WatchProviders'
|
|
Episode:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: number
|
|
name:
|
|
type: string
|
|
airDate:
|
|
type: string
|
|
nullable: true
|
|
episodeNumber:
|
|
type: number
|
|
overview:
|
|
type: string
|
|
productionCode:
|
|
type: string
|
|
seasonNumber:
|
|
type: number
|
|
showId:
|
|
type: number
|
|
stillPath:
|
|
type: string
|
|
nullable: true
|
|
voteAverage:
|
|
type: number
|
|
voteCount:
|
|
type: number
|
|
Season:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: number
|
|
airDate:
|
|
type: string
|
|
nullable: true
|
|
episodeCount:
|
|
type: number
|
|
name:
|
|
type: string
|
|
overview:
|
|
type: string
|
|
posterPath:
|
|
type: string
|
|
seasonNumber:
|
|
type: number
|
|
episodes:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Episode'
|
|
TvDetails:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: number
|
|
example: 123
|
|
backdropPath:
|
|
type: string
|
|
posterPath:
|
|
type: string
|
|
contentRatings:
|
|
type: object
|
|
properties:
|
|
results:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
iso_3166_1:
|
|
type: string
|
|
example: 'US'
|
|
rating:
|
|
type: string
|
|
example: 'TV-14'
|
|
createdBy:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: number
|
|
name:
|
|
type: string
|
|
gender:
|
|
type: number
|
|
profilePath:
|
|
type: string
|
|
nullable: true
|
|
episodeRunTime:
|
|
type: array
|
|
items:
|
|
type: number
|
|
firstAirDate:
|
|
type: string
|
|
genres:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Genre'
|
|
homepage:
|
|
type: string
|
|
inProduction:
|
|
type: boolean
|
|
languages:
|
|
type: array
|
|
items:
|
|
type: string
|
|
lastAirDate:
|
|
type: string
|
|
lastEpisodeToAir:
|
|
$ref: '#/components/schemas/Episode'
|
|
name:
|
|
type: string
|
|
nextEpisodeToAir:
|
|
$ref: '#/components/schemas/Episode'
|
|
networks:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ProductionCompany'
|
|
numberOfEpisodes:
|
|
type: number
|
|
numberOfSeason:
|
|
type: number
|
|
originCountry:
|
|
type: array
|
|
items:
|
|
type: string
|
|
originalLanguage:
|
|
type: string
|
|
originalName:
|
|
type: string
|
|
overview:
|
|
type: string
|
|
popularity:
|
|
type: number
|
|
productionCompanies:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ProductionCompany'
|
|
productionCountries:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
iso_3166_1:
|
|
type: string
|
|
name:
|
|
type: string
|
|
seasons:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Season'
|
|
status:
|
|
type: string
|
|
tagline:
|
|
type: string
|
|
type:
|
|
type: string
|
|
voteAverage:
|
|
type: number
|
|
voteCount:
|
|
type: number
|
|
externalIds:
|
|
$ref: '#/components/schemas/ExternalIds'
|
|
keywords:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Keyword'
|
|
watchProviders:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/WatchProviders'
|
|
ExternalIds:
|
|
type: object
|
|
properties:
|
|
facebookId:
|
|
type: string
|
|
nullable: true
|
|
freebaseId:
|
|
type: string
|
|
nullable: true
|
|
freebaseMid:
|
|
type: string
|
|
nullable: true
|
|
imdbId:
|
|
type: string
|
|
nullable: true
|
|
instagramId:
|
|
type: string
|
|
nullable: true
|
|
tvdbId:
|
|
type: number
|
|
nullable: true
|
|
tvrageId:
|
|
type: number
|
|
nullable: true
|
|
twitterId:
|
|
type: string
|
|
nullable: true
|
|
ServiceProfile:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: number
|
|
example: 1
|
|
name:
|
|
type: string
|
|
example: 720p/1080p
|
|
PageInfo:
|
|
type: object
|
|
properties:
|
|
page:
|
|
type: number
|
|
example: 1
|
|
pages:
|
|
type: number
|
|
example: 10
|
|
results:
|
|
type: number
|
|
example: 100
|
|
Job:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
example: job-name
|
|
type:
|
|
type: string
|
|
enum: [process, command]
|
|
interval:
|
|
type: string
|
|
enum: [short, long, fixed]
|
|
name:
|
|
type: string
|
|
example: A Job Name
|
|
nextExecutionTime:
|
|
type: string
|
|
example: '2020-09-02T05:02:23.000Z'
|
|
running:
|
|
type: boolean
|
|
example: false
|
|
Keyword:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: number
|
|
example: 1
|
|
name:
|
|
type: string
|
|
example: 'anime'
|
|
SonarrSeries:
|
|
type: object
|
|
properties:
|
|
title:
|
|
type: string
|
|
example: COVID-25
|
|
sortTitle:
|
|
type: string
|
|
example: covid 25
|
|
seasonCount:
|
|
type: number
|
|
example: 1
|
|
status:
|
|
type: string
|
|
example: upcoming
|
|
overview:
|
|
type: string
|
|
example: The thread is picked up again by Marianne Schmidt which ...
|
|
network:
|
|
type: string
|
|
example: CBS
|
|
airTime:
|
|
type: string
|
|
example: 02:15
|
|
images:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
coverType:
|
|
type: string
|
|
example: banner
|
|
url:
|
|
type: string
|
|
example: /sonarr/MediaCoverProxy/6467f05d9872726ad08cbf920e5fee4bf69198682260acab8eab5d3c2c958e92/5c8f116c6aa5c.jpg
|
|
remotePoster:
|
|
type: string
|
|
example: https://artworks.thetvdb.com/banners/posters/5c8f116129983.jpg
|
|
seasons:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
seasonNumber:
|
|
type: number
|
|
example: 1
|
|
monitored:
|
|
type: boolean
|
|
example: true
|
|
year:
|
|
type: number
|
|
example: 2015
|
|
path:
|
|
type: string
|
|
profileId:
|
|
type: number
|
|
languageProfileId:
|
|
type: number
|
|
seasonFolder:
|
|
type: boolean
|
|
monitored:
|
|
type: boolean
|
|
useSceneNumbering:
|
|
type: boolean
|
|
runtime:
|
|
type: number
|
|
tvdbId:
|
|
type: number
|
|
example: 12345
|
|
tvRageId:
|
|
type: number
|
|
tvMazeId:
|
|
type: number
|
|
firstAired:
|
|
type: string
|
|
lastInfoSync:
|
|
type: string
|
|
nullable: true
|
|
seriesType:
|
|
type: string
|
|
cleanTitle:
|
|
type: string
|
|
imdbId:
|
|
type: string
|
|
titleSlug:
|
|
type: string
|
|
certification:
|
|
type: string
|
|
genres:
|
|
type: array
|
|
items:
|
|
type: string
|
|
tags:
|
|
type: array
|
|
items:
|
|
type: string
|
|
added:
|
|
type: string
|
|
ratings:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
votes:
|
|
type: number
|
|
value:
|
|
type: number
|
|
qualityProfileId:
|
|
type: number
|
|
id:
|
|
type: number
|
|
nullable: true
|
|
rootFolderPath:
|
|
type: string
|
|
nullable: true
|
|
addOptions:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
ignoreEpisodesWithFiles:
|
|
type: boolean
|
|
nullable: true
|
|
ignoreEpisodesWithoutFiles:
|
|
type: boolean
|
|
nullable: true
|
|
searchForMissingEpisodes:
|
|
type: boolean
|
|
nullable: true
|
|
WatchProviders:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
iso_3166_1:
|
|
type: string
|
|
link:
|
|
type: string
|
|
buy:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/WatchProviderDetails'
|
|
flatrate:
|
|
items:
|
|
$ref: '#/components/schemas/WatchProviderDetails'
|
|
WatchProviderDetails:
|
|
type: object
|
|
properties:
|
|
displayPriority:
|
|
type: number
|
|
logoPath:
|
|
type: string
|
|
id:
|
|
type: number
|
|
name:
|
|
type: string
|
|
WatchProviderRegion:
|
|
type: object
|
|
properties:
|
|
iso_3166_1:
|
|
type: string
|
|
english_name:
|
|
type: string
|
|
native_name:
|
|
type: string
|
|
MissingItemRequest:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
example: 1
|
|
tmdbId:
|
|
type: integer
|
|
example: 550
|
|
mediaType:
|
|
type: string
|
|
enum: [movie, tv]
|
|
example: movie
|
|
title:
|
|
type: string
|
|
example: "Fight Club"
|
|
posterPath:
|
|
type: string
|
|
nullable: true
|
|
example: "/pB8BM7pdSp6B6Ih7QZ4DrQ3PmJK.jpg"
|
|
year:
|
|
type: integer
|
|
nullable: true
|
|
example: 1999
|
|
collectionName:
|
|
type: string
|
|
example: "Trending Movies"
|
|
collectionSource:
|
|
type: string
|
|
enum: [trakt, tmdb, imdb, letterboxd]
|
|
example: "trakt"
|
|
collectionSubtype:
|
|
type: string
|
|
nullable: true
|
|
example: "trending"
|
|
requestService:
|
|
type: string
|
|
enum: [overseerr, radarr, sonarr]
|
|
example: "overseerr"
|
|
requestMethod:
|
|
type: string
|
|
enum: [auto, manual]
|
|
example: "auto"
|
|
requestStatus:
|
|
type: string
|
|
enum: [pending, approved, declined, available, processing, failed, partially_available]
|
|
example: "approved"
|
|
overseerrRequestId:
|
|
type: integer
|
|
nullable: true
|
|
example: 123
|
|
requestedBy:
|
|
type: object
|
|
nullable: true
|
|
properties:
|
|
id:
|
|
type: integer
|
|
example: 1
|
|
displayName:
|
|
type: string
|
|
example: "TraktAgregarr"
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
example: "2023-12-01T10:30:00Z"
|
|
requestedAt:
|
|
type: string
|
|
format: date-time
|
|
nullable: true
|
|
example: "2023-12-01T10:35:00Z"
|
|
MissingItemsResponse:
|
|
type: object
|
|
properties:
|
|
results:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/MissingItemRequest'
|
|
total:
|
|
type: integer
|
|
example: 150
|
|
limit:
|
|
type: integer
|
|
example: 20
|
|
offset:
|
|
type: integer
|
|
example: 0
|
|
MissingItemStats:
|
|
type: object
|
|
properties:
|
|
stats:
|
|
type: object
|
|
properties:
|
|
total:
|
|
type: integer
|
|
example: 150
|
|
pending:
|
|
type: integer
|
|
example: 45
|
|
approved:
|
|
type: integer
|
|
example: 90
|
|
declined:
|
|
type: integer
|
|
example: 10
|
|
available:
|
|
type: integer
|
|
example: 5
|
|
processing:
|
|
type: integer
|
|
example: 12
|
|
failed:
|
|
type: integer
|
|
example: 2
|
|
partially_available:
|
|
type: integer
|
|
example: 3
|
|
byMediaType:
|
|
type: object
|
|
properties:
|
|
movie:
|
|
type: integer
|
|
example: 85
|
|
tv:
|
|
type: integer
|
|
example: 65
|
|
bySource:
|
|
type: object
|
|
properties:
|
|
trakt:
|
|
type: integer
|
|
example: 60
|
|
tmdb:
|
|
type: integer
|
|
example: 45
|
|
imdb:
|
|
type: integer
|
|
example: 30
|
|
letterboxd:
|
|
type: integer
|
|
example: 15
|
|
DashboardStats:
|
|
type: object
|
|
properties:
|
|
collections:
|
|
type: object
|
|
properties:
|
|
configured:
|
|
type: integer
|
|
example: 25
|
|
active:
|
|
type: integer
|
|
example: 18
|
|
stats:
|
|
type: object
|
|
nullable: true
|
|
properties:
|
|
topCollections:
|
|
type: array
|
|
items:
|
|
type: object
|
|
totalCollections:
|
|
type: integer
|
|
example: 15
|
|
activity:
|
|
type: object
|
|
nullable: true
|
|
properties:
|
|
totalPlays:
|
|
type: integer
|
|
example: 156
|
|
moviePlays:
|
|
type: integer
|
|
example: 89
|
|
tvPlays:
|
|
type: integer
|
|
example: 67
|
|
tautulli:
|
|
type: object
|
|
nullable: true
|
|
properties:
|
|
isConnected:
|
|
type: boolean
|
|
example: true
|
|
error:
|
|
type: string
|
|
nullable: true
|
|
example: null
|
|
weeklyActivity:
|
|
type: object
|
|
nullable: true
|
|
properties:
|
|
totalPlays:
|
|
type: integer
|
|
example: 156
|
|
moviePlays:
|
|
type: integer
|
|
example: 89
|
|
tvPlays:
|
|
type: integer
|
|
example: 67
|
|
timestamp:
|
|
type: string
|
|
format: date-time
|
|
example: "2024-01-15T10:30:00Z"
|
|
CollectionStatsResponse:
|
|
type: object
|
|
properties:
|
|
collections:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/CollectionStats'
|
|
metadata:
|
|
type: object
|
|
properties:
|
|
limit:
|
|
type: integer
|
|
example: 10
|
|
statType:
|
|
type: string
|
|
enum: [plays, duration]
|
|
example: "plays"
|
|
days:
|
|
type: integer
|
|
example: 30
|
|
timestamp:
|
|
type: string
|
|
format: date-time
|
|
example: "2024-01-15T10:30:00Z"
|
|
CollectionStats:
|
|
type: object
|
|
properties:
|
|
rating_key:
|
|
type: string
|
|
example: "12345"
|
|
title:
|
|
type: string
|
|
example: "Marvel Movies"
|
|
media_type:
|
|
type: string
|
|
example: "collection"
|
|
section_id:
|
|
type: integer
|
|
example: 1
|
|
section_name:
|
|
type: string
|
|
example: "Movies"
|
|
item_count:
|
|
type: integer
|
|
example: 28
|
|
total_plays:
|
|
type: integer
|
|
example: 145
|
|
total_duration:
|
|
type: integer
|
|
example: 18000
|
|
last_played:
|
|
type: integer
|
|
nullable: true
|
|
example: 1642291200
|
|
play_count:
|
|
type: integer
|
|
nullable: true
|
|
example: 145
|
|
watch_time_stats:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
query_days:
|
|
type: integer
|
|
example: 30
|
|
total_time:
|
|
type: integer
|
|
example: 18000
|
|
total_plays:
|
|
type: integer
|
|
example: 145
|
|
user_stats:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
friendly_name:
|
|
type: string
|
|
example: "John Doe"
|
|
user_id:
|
|
type: integer
|
|
example: 1
|
|
total_plays:
|
|
type: integer
|
|
example: 45
|
|
total_time:
|
|
type: integer
|
|
example: 5400
|
|
ActivityStatsResponse:
|
|
type: object
|
|
properties:
|
|
activity:
|
|
type: object
|
|
properties:
|
|
topMovies:
|
|
type: array
|
|
items:
|
|
type: object
|
|
topTV:
|
|
type: array
|
|
items:
|
|
type: object
|
|
tautulliInfo:
|
|
type: object
|
|
nullable: true
|
|
metadata:
|
|
type: object
|
|
properties:
|
|
days:
|
|
type: integer
|
|
example: 7
|
|
limit:
|
|
type: integer
|
|
example: 10
|
|
timestamp:
|
|
type: string
|
|
format: date-time
|
|
example: "2024-01-15T10:30:00Z"
|
|
# Discovery-specific schemas that allow collectionType to be sent (not readOnly)
|
|
PlexHubConfigForDiscovery:
|
|
type: object
|
|
description: "PlexHubConfig schema for discovery operations - allows collectionType to be sent"
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: "Unique hub identifier (libraryId-hubIdentifier)"
|
|
example: "1-movie.recentlyadded"
|
|
hubIdentifier:
|
|
type: string
|
|
description: "Plex built-in hub identifier"
|
|
example: "movie.recentlyadded"
|
|
name:
|
|
type: string
|
|
description: "Display name for the hub"
|
|
example: "Recently Added Movies"
|
|
libraryId:
|
|
type: string
|
|
description: "Plex library ID"
|
|
example: "1"
|
|
libraryName:
|
|
type: string
|
|
description: "Plex library display name"
|
|
example: "Films"
|
|
mediaType:
|
|
type: string
|
|
enum: ['movie', 'tv', 'both']
|
|
description: "Media type of the hub"
|
|
example: 'movie'
|
|
sortOrderLibrary:
|
|
type: integer
|
|
description: "Position/order within the library"
|
|
example: 0
|
|
visibilityConfig:
|
|
type: object
|
|
properties:
|
|
usersHome:
|
|
type: boolean
|
|
description: "Show on shared users' home screens"
|
|
example: true
|
|
serverOwnerHome:
|
|
type: boolean
|
|
description: "Show on server owner's home screen"
|
|
example: false
|
|
libraryRecommended:
|
|
type: boolean
|
|
description: "Show in library recommended section"
|
|
example: false
|
|
required:
|
|
- usersHome
|
|
- serverOwnerHome
|
|
- libraryRecommended
|
|
isActive:
|
|
type: boolean
|
|
description: "Whether hub is currently active"
|
|
example: true
|
|
readOnly: true
|
|
collectionType:
|
|
type: string
|
|
enum: ['default_plex_hub', 'agregarr_created', 'pre_existing']
|
|
description: "Type of collection (determined during discovery)"
|
|
example: 'default_plex_hub'
|
|
isLinked:
|
|
type: boolean
|
|
description: "True if hub is actively linked to other hubs"
|
|
example: false
|
|
linkId:
|
|
type: integer
|
|
description: "Group ID for linked hubs"
|
|
example: 1
|
|
isUnlinked:
|
|
type: boolean
|
|
description: "True if this hub was deliberately unlinked"
|
|
example: false
|
|
required:
|
|
- id
|
|
- hubIdentifier
|
|
- name
|
|
- libraryId
|
|
- libraryName
|
|
- mediaType
|
|
- sortOrderLibrary
|
|
- visibilityConfig
|
|
- isActive
|
|
|
|
PreExistingCollectionConfigForDiscovery:
|
|
type: object
|
|
description: "PreExistingCollectionConfig schema for discovery operations - allows collectionType to be sent"
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: "Unique collection identifier (libraryId-collectionRatingKey)"
|
|
example: "1-35954"
|
|
collectionRatingKey:
|
|
type: string
|
|
description: "Plex collection rating key"
|
|
example: "35954"
|
|
name:
|
|
type: string
|
|
description: "Display name from Plex"
|
|
example: "Action Movies"
|
|
libraryId:
|
|
type: string
|
|
description: "Plex library ID"
|
|
example: "1"
|
|
libraryName:
|
|
type: string
|
|
description: "Plex library display name"
|
|
example: "Films"
|
|
mediaType:
|
|
type: string
|
|
enum: ['movie', 'tv', 'both']
|
|
description: "Media type based on collection contents"
|
|
example: 'movie'
|
|
sortOrderHome:
|
|
type: integer
|
|
description: "Position on Plex home screen"
|
|
example: 0
|
|
sortOrderLibrary:
|
|
type: integer
|
|
description: "Position in library"
|
|
example: 0
|
|
visibilityConfig:
|
|
type: object
|
|
properties:
|
|
usersHome:
|
|
type: boolean
|
|
description: "Show on shared users' home screens"
|
|
example: true
|
|
serverOwnerHome:
|
|
type: boolean
|
|
description: "Show on server owner's home screen"
|
|
example: false
|
|
libraryRecommended:
|
|
type: boolean
|
|
description: "Show in library recommended section"
|
|
example: false
|
|
required:
|
|
- usersHome
|
|
- serverOwnerHome
|
|
- libraryRecommended
|
|
isActive:
|
|
type: boolean
|
|
description: "Whether collection is currently active"
|
|
example: true
|
|
readOnly: true
|
|
collectionType:
|
|
type: string
|
|
enum: ['default_plex_hub', 'agregarr_created', 'pre_existing']
|
|
description: "Type of collection (determined during discovery)"
|
|
example: 'pre_existing'
|
|
isLinked:
|
|
type: boolean
|
|
description: "True if collection is actively linked to other collections"
|
|
example: false
|
|
linkId:
|
|
type: integer
|
|
description: "Group ID for linked collections"
|
|
example: 1
|
|
isUnlinked:
|
|
type: boolean
|
|
description: "True if this collection was deliberately unlinked"
|
|
example: false
|
|
timeRestriction:
|
|
type: object
|
|
properties:
|
|
alwaysActive:
|
|
type: boolean
|
|
example: true
|
|
dateRanges:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
startDate:
|
|
type: string
|
|
description: "DD-MM format"
|
|
example: "05-12"
|
|
endDate:
|
|
type: string
|
|
description: "DD-MM format"
|
|
example: "26-12"
|
|
nullable: true
|
|
weeklySchedule:
|
|
type: object
|
|
properties:
|
|
monday:
|
|
type: boolean
|
|
tuesday:
|
|
type: boolean
|
|
wednesday:
|
|
type: boolean
|
|
thursday:
|
|
type: boolean
|
|
friday:
|
|
type: boolean
|
|
saturday:
|
|
type: boolean
|
|
sunday:
|
|
type: boolean
|
|
nullable: true
|
|
nullable: true
|
|
customPoster:
|
|
type: string
|
|
description: "Custom poster filename"
|
|
nullable: true
|
|
autoPoster:
|
|
type: boolean
|
|
description: "Auto-generate poster during sync"
|
|
example: true
|
|
nullable: true
|
|
required:
|
|
- id
|
|
- collectionRatingKey
|
|
- name
|
|
- libraryId
|
|
- libraryName
|
|
- mediaType
|
|
- sortOrderHome
|
|
- sortOrderLibrary
|
|
- visibilityConfig
|
|
- isActive
|
|
|
|
NetworksCountryOption:
|
|
type: object
|
|
description: "Country option for Networks collections"
|
|
properties:
|
|
value:
|
|
type: string
|
|
description: "Country code/identifier"
|
|
example: "united-states"
|
|
label:
|
|
type: string
|
|
description: "Display name for country"
|
|
example: "United States"
|
|
required:
|
|
- value
|
|
- label
|
|
|
|
NetworksPlatformOption:
|
|
type: object
|
|
description: "Platform option for Networks collections"
|
|
properties:
|
|
value:
|
|
type: string
|
|
description: "Platform identifier for Networks collections"
|
|
example: "netflix_top_10"
|
|
label:
|
|
type: string
|
|
description: "Display name for platform"
|
|
example: "Netflix Top 10"
|
|
required:
|
|
- value
|
|
- label
|
|
|
|
securitySchemes:
|
|
cookieAuth:
|
|
type: apiKey
|
|
name: agregarr.sid
|
|
in: cookie
|
|
apiKey:
|
|
type: apiKey
|
|
in: header
|
|
name: X-Api-Key
|
|
|
|
paths:
|
|
/status:
|
|
get:
|
|
summary: Get Agregarr status
|
|
description: Returns the current Agregarr status in a JSON object.
|
|
security: []
|
|
tags:
|
|
- public
|
|
responses:
|
|
'200':
|
|
description: Returned status
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
version:
|
|
type: string
|
|
example: 1.0.0
|
|
commitTag:
|
|
type: string
|
|
updateAvailable:
|
|
type: boolean
|
|
commitsBehind:
|
|
type: number
|
|
restartRequired:
|
|
type: boolean
|
|
/status/appdata:
|
|
get:
|
|
summary: Get application data volume status
|
|
description: For Docker installs, returns whether or not the volume mount was configured properly. Always returns true for non-Docker installs.
|
|
security: []
|
|
tags:
|
|
- public
|
|
responses:
|
|
'200':
|
|
description: Application data volume status and path
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
appData:
|
|
type: boolean
|
|
example: true
|
|
appDataPath:
|
|
type: string
|
|
example: /app/config
|
|
/collections:
|
|
get:
|
|
summary: Get collection configurations
|
|
description: Returns all collection configurations.
|
|
tags:
|
|
- collection
|
|
responses:
|
|
'200':
|
|
description: Collection configurations retrieved successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
collectionConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/CollectionConfig'
|
|
post:
|
|
summary: Save collection configurations
|
|
description: Updates collection configurations with the provided values.
|
|
tags:
|
|
- collection
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
collectionConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/CollectionConfig'
|
|
responses:
|
|
'200':
|
|
description: Collection configurations saved successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
collectionConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/CollectionConfig'
|
|
message:
|
|
type: string
|
|
example: "Collection configurations saved successfully"
|
|
'500':
|
|
description: Failed to save collection configurations
|
|
/collections/create:
|
|
post:
|
|
summary: Create a new collection
|
|
description: Creates a new collection configuration.
|
|
tags:
|
|
- collection
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CollectionConfigCreate'
|
|
responses:
|
|
'201':
|
|
description: Collection created successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
collectionConfig:
|
|
$ref: '#/components/schemas/CollectionConfig'
|
|
message:
|
|
type: string
|
|
example: "Collection created successfully"
|
|
'500':
|
|
description: Failed to create collection
|
|
/collections/{id}/settings:
|
|
put:
|
|
summary: Update individual collection settings
|
|
description: Updates settings for a specific collection while preserving computed fields.
|
|
tags:
|
|
- collection
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: Collection ID
|
|
schema:
|
|
type: string
|
|
example: "collection-123"
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CollectionConfigUpdate'
|
|
responses:
|
|
'200':
|
|
description: Collection settings updated successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
collectionConfig:
|
|
$ref: '#/components/schemas/CollectionConfig'
|
|
message:
|
|
type: string
|
|
example: "Collection settings updated successfully"
|
|
'404':
|
|
description: Collection not found
|
|
'500':
|
|
description: Failed to update collection settings
|
|
/collections/{id}:
|
|
delete:
|
|
summary: Delete individual collection
|
|
description: Delete individual collection and recalculate sort orders. If the collection is linked, all linked collections will be deleted.
|
|
tags:
|
|
- collection
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: Collection ID
|
|
schema:
|
|
type: string
|
|
example: "collection-123"
|
|
responses:
|
|
'200':
|
|
description: Collection(s) deleted successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
message:
|
|
type: string
|
|
example: "1 collection(s) deleted successfully"
|
|
deletedConfigs:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
name:
|
|
type: string
|
|
'404':
|
|
description: Collection not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Collection not found"
|
|
message:
|
|
type: string
|
|
example: "Collection with id \"collection-123\" not found"
|
|
'500':
|
|
description: Failed to delete collection
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Failed to delete collection"
|
|
message:
|
|
type: string
|
|
/collections/{id}/promote:
|
|
patch:
|
|
summary: Promote collection to top section
|
|
description: Moves a collection from the A-Z alphabetical section to the promoted section with custom ordering.
|
|
tags:
|
|
- collection
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: Collection ID
|
|
schema:
|
|
type: string
|
|
example: "collection-123"
|
|
responses:
|
|
'200':
|
|
description: Collection promoted successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: true
|
|
config:
|
|
$ref: '#/components/schemas/CollectionConfig'
|
|
'400':
|
|
description: Collection is already in promoted section
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Collection is already in promoted section"
|
|
'404':
|
|
description: Collection not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Collection not found"
|
|
'500':
|
|
description: Failed to promote collection
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Failed to promote collection"
|
|
/collections/{id}/demote:
|
|
patch:
|
|
summary: Demote collection to A-Z section
|
|
description: Moves a collection from the promoted section to the A-Z alphabetical section.
|
|
tags:
|
|
- collection
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: Collection ID
|
|
schema:
|
|
type: string
|
|
example: "collection-123"
|
|
responses:
|
|
'200':
|
|
description: Collection demoted successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: true
|
|
config:
|
|
$ref: '#/components/schemas/CollectionConfig'
|
|
'400':
|
|
description: Collection is already in A-Z section
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Collection is already in A-Z section"
|
|
'404':
|
|
description: Collection not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Collection not found"
|
|
'500':
|
|
description: Failed to demote collection
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Failed to demote collection"
|
|
/collections/sync:
|
|
get:
|
|
summary: Get collections sync status
|
|
description: Returns the current status of collection synchronization.
|
|
tags:
|
|
- collection
|
|
responses:
|
|
'200':
|
|
description: Sync status retrieved successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
running:
|
|
type: boolean
|
|
example: false
|
|
message:
|
|
type: string
|
|
example: "Not running"
|
|
post:
|
|
summary: Start collection sync
|
|
description: Starts a collection synchronization process in the background.
|
|
tags:
|
|
- collection
|
|
responses:
|
|
'200':
|
|
description: Collection sync started successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
status:
|
|
type: string
|
|
example: "success"
|
|
message:
|
|
type: string
|
|
example: "Collections sync started in background"
|
|
'400':
|
|
description: Bad request - missing configuration or connection issue
|
|
'500':
|
|
description: Failed to start collection sync
|
|
/collections/sync/status:
|
|
get:
|
|
summary: Get detailed collections sync status
|
|
description: Returns detailed sync status including current stage, progress, and global sync information.
|
|
tags:
|
|
- collection
|
|
responses:
|
|
'200':
|
|
description: Detailed sync status retrieved successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
running:
|
|
type: boolean
|
|
description: Whether a sync is currently running
|
|
example: true
|
|
currentStage:
|
|
type: string
|
|
description: Current stage of the sync process
|
|
example: "Processing collections..."
|
|
totalCollections:
|
|
type: integer
|
|
description: Total number of collections to process
|
|
example: 15
|
|
processedCollections:
|
|
type: integer
|
|
description: Number of collections processed so far
|
|
example: 8
|
|
progress:
|
|
type: integer
|
|
description: Sync progress percentage (0-100)
|
|
example: 53
|
|
lastGlobalSyncAt:
|
|
type: string
|
|
format: date-time
|
|
description: ISO timestamp of last successful global sync
|
|
example: "2024-01-15T10:30:00.000Z"
|
|
globalSyncError:
|
|
type: string
|
|
nullable: true
|
|
description: Last global sync error message, if any
|
|
example: null
|
|
collectionsNeedingSync:
|
|
type: integer
|
|
description: Number of collections that need to be synced
|
|
example: 7
|
|
/collections/preview-template:
|
|
post:
|
|
summary: Preview a collection template
|
|
description: Generates a preview of a collection name template with given context.
|
|
tags:
|
|
- collection
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
template:
|
|
type: string
|
|
example: "{{mediaType}} {{type}} Collection"
|
|
mediaType:
|
|
type: string
|
|
enum: [movie, tv]
|
|
example: "movie"
|
|
type:
|
|
type: string
|
|
example: "trakt"
|
|
subtype:
|
|
type: string
|
|
example: ""
|
|
customDays:
|
|
type: number
|
|
example: 30
|
|
minimumPlays:
|
|
type: number
|
|
example: 3
|
|
required:
|
|
- template
|
|
- mediaType
|
|
responses:
|
|
'200':
|
|
description: Template preview generated successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
status:
|
|
type: string
|
|
example: "success"
|
|
preview:
|
|
type: string
|
|
example: "Movie Trakt Collection"
|
|
'400':
|
|
description: Bad request - invalid template or parameters
|
|
'500':
|
|
description: Failed to generate template preview
|
|
/collections/fetch-title:
|
|
post:
|
|
summary: Quick validation and title extraction from external collection URL
|
|
description: Performs quick validation (first 10 items) and extracts the title from external collection URLs (Trakt, TMDb, IMDb, Letterboxd). Returns immediately with basic media type detection for fast UX. For comprehensive media type analysis, use the /collections/detect-media-type endpoint.
|
|
tags:
|
|
- collection
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
url:
|
|
type: string
|
|
example: "https://trakt.tv/users/username/lists/my-list"
|
|
type:
|
|
type: string
|
|
enum: [trakt, tmdb, imdb, letterboxd]
|
|
example: "trakt"
|
|
required:
|
|
- url
|
|
- type
|
|
responses:
|
|
'200':
|
|
description: Title fetched successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
status:
|
|
type: string
|
|
example: "success"
|
|
title:
|
|
type: string
|
|
example: "My List"
|
|
mediaType:
|
|
type: string
|
|
enum: [movie, tv, both]
|
|
example: "movie"
|
|
'400':
|
|
description: Bad request - invalid URL or unsupported type
|
|
'429':
|
|
description: Too many requests - rate limited
|
|
'500':
|
|
description: Failed to fetch title
|
|
/collections/detect-media-type:
|
|
post:
|
|
summary: Comprehensive media type detection from external collection URL
|
|
description: Performs comprehensive analysis (up to 1000 items) to accurately detect media types from external collection URLs. This endpoint runs in the background after quick title validation to provide detailed media type information for better user guidance.
|
|
tags:
|
|
- collection
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
url:
|
|
type: string
|
|
example: "https://trakt.tv/users/username/lists/my-list"
|
|
type:
|
|
type: string
|
|
enum: [trakt, tmdb, imdb, letterboxd]
|
|
example: "trakt"
|
|
required:
|
|
- url
|
|
- type
|
|
responses:
|
|
'200':
|
|
description: Media type detected successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
status:
|
|
type: string
|
|
example: "success"
|
|
mediaType:
|
|
type: string
|
|
enum: [movie, tv, both]
|
|
example: "both"
|
|
description: "Detected media type based on comprehensive list analysis"
|
|
'400':
|
|
description: Bad request - invalid URL, unsupported type, or failed to analyze list content
|
|
'429':
|
|
description: Too many requests - rate limited
|
|
'500':
|
|
description: Internal server error while detecting media type
|
|
/collections/poster:
|
|
post:
|
|
summary: Upload a poster image for collections
|
|
description: Uploads a custom poster image that can be used for collections. Supports JPEG, PNG, and WebP formats.
|
|
tags:
|
|
- collection
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
multipart/form-data:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
poster:
|
|
type: string
|
|
format: binary
|
|
description: The poster image file
|
|
required:
|
|
- poster
|
|
responses:
|
|
'200':
|
|
description: Poster uploaded successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
filename:
|
|
type: string
|
|
example: "f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
url:
|
|
type: string
|
|
example: "/api/v1/collections/poster/f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
'400':
|
|
description: Bad request - invalid file or upload error
|
|
'403':
|
|
description: Authentication required
|
|
'500':
|
|
description: Internal server error
|
|
/collections/generate-poster:
|
|
post:
|
|
summary: Generate a poster for a collection
|
|
description: Generates a custom poster based on collection configuration data. Creates text-based posters with collection type styling.
|
|
tags:
|
|
- collection
|
|
security:
|
|
- cookieAuth: []
|
|
- apiKeyAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
collectionName:
|
|
type: string
|
|
description: Name of the collection to generate poster for
|
|
example: "Top Trakt Movies"
|
|
collectionType:
|
|
type: string
|
|
description: Type of collection (trakt, tmdb, imdb, letterboxd, tautulli, overseerr, hub)
|
|
example: "trakt"
|
|
collectionSubtype:
|
|
type: string
|
|
description: Subtype of the collection
|
|
example: "popular"
|
|
mediaType:
|
|
type: string
|
|
enum: [movie, tv]
|
|
description: Media type for the collection
|
|
example: "movie"
|
|
template:
|
|
type: string
|
|
description: Collection template for additional context
|
|
example: "Top {count} {type} from Trakt"
|
|
required:
|
|
- collectionName
|
|
responses:
|
|
'200':
|
|
description: Poster generated successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
filename:
|
|
type: string
|
|
example: "generated_abc123def.jpg"
|
|
url:
|
|
type: string
|
|
example: "/api/v1/collections/poster/generated_abc123def.jpg"
|
|
message:
|
|
type: string
|
|
example: "Poster generated successfully"
|
|
'400':
|
|
description: Bad request - missing or invalid collection name
|
|
'401':
|
|
description: Authentication required
|
|
'500':
|
|
description: Internal server error
|
|
/collections/download-poster:
|
|
post:
|
|
summary: Download a poster from a URL
|
|
description: Downloads a poster image from a given URL and saves it to the system. Supports JPEG, PNG, and WebP formats with automatic validation and processing.
|
|
tags:
|
|
- collection
|
|
security:
|
|
- cookieAuth: []
|
|
- apiKeyAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
url:
|
|
type: string
|
|
format: uri
|
|
description: URL of the poster image to download
|
|
example: "https://example.com/poster.jpg"
|
|
required:
|
|
- url
|
|
responses:
|
|
'200':
|
|
description: Poster downloaded successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
filename:
|
|
type: string
|
|
example: "f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
url:
|
|
type: string
|
|
example: "/api/v1/collections/poster/f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
message:
|
|
type: string
|
|
example: "Poster downloaded successfully"
|
|
'400':
|
|
description: Bad request - invalid URL, unsupported format, or file too large
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Invalid URL format"
|
|
'401':
|
|
description: Authentication required
|
|
'429':
|
|
description: Too many requests - rate limit exceeded
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Too many requests. Please try again later."
|
|
'500':
|
|
description: Internal server error
|
|
/collections/posters:
|
|
get:
|
|
summary: List all stored poster files
|
|
description: Returns a list of all poster files currently stored in the system with their URLs.
|
|
tags:
|
|
- collection
|
|
security:
|
|
- cookieAuth: []
|
|
- apiKeyAuth: []
|
|
responses:
|
|
'200':
|
|
description: List of poster files
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
posters:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
filename:
|
|
type: string
|
|
description: The filename of the poster
|
|
example: "f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
url:
|
|
type: string
|
|
description: The URL to access the poster
|
|
example: "/api/v1/collections/poster/f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
'401':
|
|
description: Authentication required
|
|
'500':
|
|
description: Internal server error
|
|
/collections/poster/{filename}:
|
|
get:
|
|
summary: Serve poster image
|
|
description: Serves a poster image by filename. No authentication required.
|
|
tags:
|
|
- collection
|
|
parameters:
|
|
- in: path
|
|
name: filename
|
|
required: true
|
|
schema:
|
|
type: string
|
|
example: "f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
responses:
|
|
'200':
|
|
description: Poster image served successfully
|
|
content:
|
|
image/jpeg:
|
|
schema:
|
|
type: string
|
|
format: binary
|
|
'404':
|
|
description: Poster not found
|
|
'500':
|
|
description: Internal server error
|
|
delete:
|
|
summary: Delete a poster image
|
|
description: Deletes a poster image by filename. Authentication required.
|
|
tags:
|
|
- collection
|
|
parameters:
|
|
- in: path
|
|
name: filename
|
|
required: true
|
|
schema:
|
|
type: string
|
|
example: "f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
responses:
|
|
'200':
|
|
description: Poster deleted successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
message:
|
|
type: string
|
|
example: "Poster deleted successfully"
|
|
'403':
|
|
description: Authentication required
|
|
'404':
|
|
description: Poster not found
|
|
'500':
|
|
description: Internal server error
|
|
/collections/cleanup-missing:
|
|
delete:
|
|
summary: Clean up missing collections
|
|
description: Removes all collection configurations where missing is true (collections that no longer exist in Plex) and also deletes them from Plex hubs if they are present there.
|
|
tags:
|
|
- collection
|
|
responses:
|
|
'200':
|
|
description: Missing collections cleaned up successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
message:
|
|
type: string
|
|
example: "3 missing collection configurations removed successfully (2 also deleted from Plex hubs)"
|
|
cleanupCount:
|
|
type: integer
|
|
description: "Number of configurations that were removed"
|
|
example: 3
|
|
hubDeleteCount:
|
|
type: integer
|
|
description: "Number of collections that were deleted from Plex hubs"
|
|
example: 2
|
|
'403':
|
|
description: Authentication required
|
|
'500':
|
|
description: Failed to cleanup missing collections
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Failed to cleanup missing collections"
|
|
/collections/networks/countries:
|
|
get:
|
|
summary: Get available countries for Networks collections
|
|
description: Returns all available countries/regions that can be used for Networks streaming platform collections.
|
|
tags:
|
|
- collection
|
|
responses:
|
|
'200':
|
|
description: Countries retrieved successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/NetworksCountryOption'
|
|
'500':
|
|
description: Failed to fetch countries
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Failed to load available countries"
|
|
/collections/networks/platforms:
|
|
get:
|
|
summary: Get available platforms for a country
|
|
description: Returns all available streaming platforms for the specified country/region.
|
|
tags:
|
|
- collection
|
|
parameters:
|
|
- name: country
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: Country code to get platforms for
|
|
example: "united-states"
|
|
responses:
|
|
'200':
|
|
description: Platforms retrieved successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/NetworksPlatformOption'
|
|
'400':
|
|
description: Country parameter is required
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Country parameter is required"
|
|
'500':
|
|
description: Failed to fetch platforms
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Failed to load platforms for country"
|
|
/collections/preexisting:
|
|
get:
|
|
summary: Get pre-existing Plex collections
|
|
description: Returns all Plex collections that were not created by Agregarr (collections without Agregarr labels).
|
|
tags:
|
|
- collection
|
|
responses:
|
|
'200':
|
|
description: Pre-existing collections retrieved successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
collections:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
example: "12345"
|
|
name:
|
|
type: string
|
|
example: "My Collection"
|
|
summary:
|
|
type: string
|
|
example: "A collection of my favorite movies"
|
|
libraryId:
|
|
type: string
|
|
example: "1"
|
|
libraryTitle:
|
|
type: string
|
|
example: "Movies"
|
|
itemCount:
|
|
type: number
|
|
example: 25
|
|
thumb:
|
|
type: string
|
|
example: "/library/metadata/12345/thumb"
|
|
art:
|
|
type: string
|
|
example: "/library/metadata/12345/art"
|
|
guid:
|
|
type: string
|
|
example: "com.plexapp.agents.none://12345"
|
|
updatedAt:
|
|
type: number
|
|
example: 1640995200
|
|
addedAt:
|
|
type: number
|
|
example: 1640995200
|
|
labels:
|
|
type: array
|
|
items:
|
|
type: object
|
|
'400':
|
|
description: Bad request - Plex server not configured or no admin token
|
|
'500':
|
|
description: Failed to fetch pre-existing collections
|
|
/defaulthubs:
|
|
get:
|
|
summary: Get default Plex hub configurations
|
|
description: Returns all default Plex hub configurations.
|
|
tags:
|
|
- collection
|
|
responses:
|
|
'200':
|
|
description: Default hub configurations retrieved successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexHubConfig'
|
|
'500':
|
|
description: Failed to retrieve hub configurations
|
|
post:
|
|
summary: Save default Plex hub configurations
|
|
description: Updates default Plex hub configurations with the provided values.
|
|
tags:
|
|
- collection
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
hubConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexHubConfig'
|
|
responses:
|
|
'200':
|
|
description: Hub configurations saved successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexHubConfig'
|
|
'500':
|
|
description: Failed to save hub configurations
|
|
/defaulthubs/{id}/settings:
|
|
put:
|
|
summary: Update individual default hub settings
|
|
description: Updates settings for a specific default hub while preserving computed fields.
|
|
tags:
|
|
- collection
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: Default hub ID
|
|
schema:
|
|
type: string
|
|
example: "1-movie.recentlyadded"
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PlexHubConfigUpdate'
|
|
responses:
|
|
'200':
|
|
description: Default hub settings updated successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
hubConfig:
|
|
$ref: '#/components/schemas/PlexHubConfig'
|
|
message:
|
|
type: string
|
|
example: "Default hub settings updated successfully"
|
|
'404':
|
|
description: Default hub not found
|
|
'500':
|
|
description: Failed to update default hub settings
|
|
/defaulthubs/discover:
|
|
post:
|
|
summary: Discover new default hubs
|
|
description: Discovery operation for new default hubs (replaces /append for discovery).
|
|
tags:
|
|
- collection
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
hubConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexHubConfigForDiscovery'
|
|
responses:
|
|
'200':
|
|
description: Default hubs discovered successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
hubConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexHubConfig'
|
|
message:
|
|
type: string
|
|
example: "Default hubs discovered successfully"
|
|
'500':
|
|
description: Failed to discover default hubs
|
|
/defaulthubs/append:
|
|
post:
|
|
summary: Append default Plex hub configurations
|
|
description: Appends new default hub configurations to existing ones (for discovery).
|
|
tags:
|
|
- collection
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
hubConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexHubConfig'
|
|
responses:
|
|
'200':
|
|
description: Hub configurations appended successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
hubConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexHubConfig'
|
|
message:
|
|
type: string
|
|
example: 'Default hub configurations appended successfully'
|
|
'400':
|
|
description: Invalid request body
|
|
'500':
|
|
description: Failed to append hub configurations
|
|
/preexisting:
|
|
get:
|
|
summary: Get pre-existing collection configurations
|
|
description: Returns all pre-existing Plex collection configurations.
|
|
tags:
|
|
- collection
|
|
responses:
|
|
'200':
|
|
description: Pre-existing collection configurations retrieved successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PreExistingCollectionConfig'
|
|
'500':
|
|
description: Failed to retrieve pre-existing collection configurations
|
|
post:
|
|
summary: Save pre-existing collection configurations
|
|
description: Updates pre-existing collection configurations with the provided values.
|
|
tags:
|
|
- collection
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
preExistingConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PreExistingCollectionConfig'
|
|
responses:
|
|
'200':
|
|
description: Pre-existing collection configurations saved successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PreExistingCollectionConfig'
|
|
'500':
|
|
description: Failed to save pre-existing collection configurations
|
|
/preexisting/{id}/settings:
|
|
put:
|
|
summary: Update individual pre-existing collection settings
|
|
description: Updates settings for a specific pre-existing collection while preserving computed fields.
|
|
tags:
|
|
- collection
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: Pre-existing collection ID
|
|
schema:
|
|
type: string
|
|
example: "1-35954"
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PreExistingCollectionConfigUpdate'
|
|
responses:
|
|
'200':
|
|
description: Pre-existing collection settings updated successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
preExistingCollectionConfig:
|
|
$ref: '#/components/schemas/PreExistingCollectionConfig'
|
|
message:
|
|
type: string
|
|
example: "Pre-existing collection settings updated successfully"
|
|
'404':
|
|
description: Pre-existing collection not found
|
|
'500':
|
|
description: Failed to update pre-existing collection settings
|
|
/preexisting/{id}/promote:
|
|
patch:
|
|
summary: Promote pre-existing collection to top section
|
|
description: Moves a pre-existing collection from the A-Z alphabetical section to the promoted section with custom ordering.
|
|
tags:
|
|
- collection
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: Pre-existing collection ID
|
|
schema:
|
|
type: string
|
|
example: "1-35954"
|
|
responses:
|
|
'200':
|
|
description: Pre-existing collection promoted successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: true
|
|
config:
|
|
$ref: '#/components/schemas/PreExistingCollectionConfig'
|
|
'400':
|
|
description: Collection is already in promoted section
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Collection is already in promoted section"
|
|
'404':
|
|
description: Pre-existing collection not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Pre-existing collection not found"
|
|
'500':
|
|
description: Failed to promote pre-existing collection
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Failed to promote pre-existing collection"
|
|
/preexisting/{id}/demote:
|
|
patch:
|
|
summary: Demote pre-existing collection to A-Z section
|
|
description: Moves a pre-existing collection from the promoted section to the A-Z alphabetical section.
|
|
tags:
|
|
- collection
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
description: Pre-existing collection ID
|
|
schema:
|
|
type: string
|
|
example: "1-35954"
|
|
responses:
|
|
'200':
|
|
description: Pre-existing collection demoted successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: true
|
|
config:
|
|
$ref: '#/components/schemas/PreExistingCollectionConfig'
|
|
'400':
|
|
description: Collection is already in A-Z section
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Collection is already in A-Z section"
|
|
'404':
|
|
description: Pre-existing collection not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Pre-existing collection not found"
|
|
'500':
|
|
description: Failed to demote pre-existing collection
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Failed to demote pre-existing collection"
|
|
/preexisting/discover:
|
|
post:
|
|
summary: Discover new pre-existing collections
|
|
description: Discovery operation for new pre-existing collections (replaces /append for discovery).
|
|
tags:
|
|
- collection
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
preExistingCollectionConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PreExistingCollectionConfigForDiscovery'
|
|
responses:
|
|
'200':
|
|
description: Pre-existing collections discovered successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
preExistingCollectionConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PreExistingCollectionConfig'
|
|
message:
|
|
type: string
|
|
example: "Pre-existing collections discovered successfully"
|
|
'500':
|
|
description: Failed to discover pre-existing collections
|
|
/preexisting/append:
|
|
post:
|
|
summary: Append pre-existing collection configurations
|
|
description: Appends new pre-existing collection configurations to existing ones (for discovery).
|
|
tags:
|
|
- collection
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
preExistingCollectionConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/DiscoveredCollectionConfig'
|
|
responses:
|
|
'200':
|
|
description: Pre-existing collection configurations appended successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
preExistingCollectionConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PreExistingCollectionConfig'
|
|
message:
|
|
type: string
|
|
example: 'Pre-existing collection configurations appended successfully'
|
|
'400':
|
|
description: Invalid request body
|
|
'500':
|
|
description: Failed to append pre-existing collection configurations
|
|
/reorder:
|
|
post:
|
|
summary: True unified reordering for mixed collection lists
|
|
description: Reorders mixed collection lists in a single operation, eliminating race conditions and multiple API calls.
|
|
tags:
|
|
- collection
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
libraryId:
|
|
type: string
|
|
description: "Plex library ID where reordering occurs"
|
|
example: "1"
|
|
mixedItems:
|
|
type: array
|
|
description: "Array of mixed collection items in their new order"
|
|
items:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: "Item ID"
|
|
configType:
|
|
type: string
|
|
enum: ['collection', 'hub', 'preExisting']
|
|
description: "Type of collection item"
|
|
position:
|
|
type: number
|
|
description: "Position in the mixed list"
|
|
additionalProperties: true
|
|
required:
|
|
- id
|
|
- configType
|
|
- position
|
|
context:
|
|
type: string
|
|
enum: ['home', 'recommended', 'library']
|
|
description: "Context determining which sortOrder field to update"
|
|
example: 'home'
|
|
required:
|
|
- libraryId
|
|
- mixedItems
|
|
- context
|
|
responses:
|
|
'200':
|
|
description: Items reordered successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: true
|
|
message:
|
|
type: string
|
|
example: 'Successfully reordered 3 collections'
|
|
updatedItems:
|
|
type: array
|
|
description: "Items with updated sort orders"
|
|
items:
|
|
oneOf:
|
|
- $ref: '#/components/schemas/CollectionConfig'
|
|
- $ref: '#/components/schemas/PlexHubConfig'
|
|
- $ref: '#/components/schemas/PreExistingCollectionConfig'
|
|
'400':
|
|
description: Invalid request parameters
|
|
'500':
|
|
description: Failed to reorder items
|
|
/settings/main:
|
|
get:
|
|
summary: Get main settings
|
|
description: Retrieves all main settings in a JSON object.
|
|
tags:
|
|
- settings
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/MainSettings'
|
|
post:
|
|
summary: Update main settings
|
|
description: Updates main settings with the provided values.
|
|
tags:
|
|
- settings
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/MainSettings'
|
|
responses:
|
|
'200':
|
|
description: 'Values were sucessfully updated'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/MainSettings'
|
|
/settings/main/regenerate:
|
|
post:
|
|
summary: Get main settings with newly-generated API key
|
|
description: Returns main settings in a JSON object, using the new API key.
|
|
tags:
|
|
- settings
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/MainSettings'
|
|
/settings/plex:
|
|
get:
|
|
summary: Get Plex settings
|
|
description: Retrieves current Plex settings.
|
|
tags:
|
|
- settings
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PlexSettings'
|
|
post:
|
|
summary: Update Plex settings
|
|
description: Updates Plex settings with the provided values.
|
|
tags:
|
|
- settings
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PlexSettings'
|
|
responses:
|
|
'200':
|
|
description: 'Values were successfully updated'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PlexSettings'
|
|
/settings/plex/libraries:
|
|
get:
|
|
summary: Get Plex libraries directly from Plex server
|
|
description: Fetches all available libraries directly from the connected Plex server.
|
|
tags:
|
|
- settings
|
|
responses:
|
|
'200':
|
|
description: Plex libraries retrieved successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: Library ID from Plex
|
|
example: "1"
|
|
name:
|
|
type: string
|
|
description: Library name
|
|
example: "Movies"
|
|
type:
|
|
type: string
|
|
enum: [movie, show]
|
|
description: Library media type
|
|
example: "movie"
|
|
enabled:
|
|
type: boolean
|
|
description: Always true for direct Plex libraries
|
|
example: true
|
|
'400':
|
|
description: No admin Plex token found
|
|
'500':
|
|
description: Failed to fetch Plex libraries
|
|
/settings/plex/library:
|
|
get:
|
|
summary: Get Plex libraries
|
|
description: Returns a list of Plex libraries in a JSON array.
|
|
tags:
|
|
- settings
|
|
parameters:
|
|
- in: query
|
|
name: sync
|
|
description: Syncs the current libraries with the current Plex server
|
|
schema:
|
|
type: string
|
|
nullable: true
|
|
responses:
|
|
'200':
|
|
description: 'Plex libraries returned'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexLibrary'
|
|
/settings/plex/sync:
|
|
get:
|
|
summary: Get status of full Plex library scan
|
|
description: Returns scan progress in a JSON array.
|
|
tags:
|
|
- settings
|
|
responses:
|
|
'200':
|
|
description: Status of Plex scan
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
running:
|
|
type: boolean
|
|
example: false
|
|
progress:
|
|
type: number
|
|
example: 0
|
|
total:
|
|
type: number
|
|
example: 100
|
|
currentLibrary:
|
|
$ref: '#/components/schemas/PlexLibrary'
|
|
libraries:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexLibrary'
|
|
post:
|
|
summary: Start full Plex library scan
|
|
description: Runs a full Plex library scan and returns the progress in a JSON array.
|
|
tags:
|
|
- settings
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
cancel:
|
|
type: boolean
|
|
example: false
|
|
start:
|
|
type: boolean
|
|
example: false
|
|
responses:
|
|
'200':
|
|
description: Status of Plex scan
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
running:
|
|
type: boolean
|
|
example: false
|
|
progress:
|
|
type: number
|
|
example: 0
|
|
total:
|
|
type: number
|
|
example: 100
|
|
currentLibrary:
|
|
$ref: '#/components/schemas/PlexLibrary'
|
|
libraries:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexLibrary'
|
|
/settings/plex/devices/servers:
|
|
get:
|
|
summary: Gets the user's available Plex servers
|
|
description: Returns a list of available Plex servers and their connectivity state
|
|
tags:
|
|
- settings
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexDevice'
|
|
/settings/plex/users:
|
|
get:
|
|
summary: Get Plex users
|
|
description: |
|
|
Returns a list of Plex users in a JSON array.
|
|
|
|
Requires the `MANAGE_USERS` permission.
|
|
tags:
|
|
- settings
|
|
- users
|
|
responses:
|
|
'200':
|
|
description: Plex users
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
title:
|
|
type: string
|
|
username:
|
|
type: string
|
|
email:
|
|
type: string
|
|
thumb:
|
|
type: string
|
|
/settings/collections/poster:
|
|
post:
|
|
summary: Upload collection poster image
|
|
description: |
|
|
Uploads a custom poster image for collections. The image will be processed, optimized, and stored securely.
|
|
|
|
**Important: Sync-Based Behavior**
|
|
- Posters are only validated and stored when uploaded
|
|
- Posters are applied to Plex collections during the next collection sync run
|
|
- Changes are not immediately visible in Plex until sync occurs
|
|
|
|
**Security Features:**
|
|
- Admin-only access required
|
|
- File type validation (JPEG, PNG, WebP only)
|
|
- File size limit (10MB maximum)
|
|
- Automatic image processing and optimization
|
|
- Secure filename generation using UUIDs
|
|
|
|
**Processing:**
|
|
- Images are automatically resized to 500x750 pixels (2:3 aspect ratio)
|
|
- All images are converted to JPEG format for consistency
|
|
- Quality optimization applied (85% quality)
|
|
tags:
|
|
- settings
|
|
security:
|
|
- cookieAuth: []
|
|
- apiKeyAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
multipart/form-data:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
poster:
|
|
type: string
|
|
format: binary
|
|
description: The poster image file (JPEG, PNG, or WebP, max 10MB)
|
|
required:
|
|
- poster
|
|
responses:
|
|
'200':
|
|
description: Poster uploaded successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
filename:
|
|
type: string
|
|
description: The generated filename for the uploaded poster
|
|
example: "f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
url:
|
|
type: string
|
|
description: The URL to access the uploaded poster
|
|
example: "/api/v1/settings/collections/poster/f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
'400':
|
|
description: Bad request - Invalid file or upload error
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
enum:
|
|
- "No file uploaded"
|
|
- "Invalid file type. Only JPEG, PNG, and WebP are allowed."
|
|
- "File extension does not match file type."
|
|
- "File size too large. Maximum size: 10MB"
|
|
- "Invalid image format detected"
|
|
- "Image dimensions too large"
|
|
- "Failed to process poster"
|
|
example: "Invalid file type. Only JPEG, PNG, and WebP are allowed."
|
|
'403':
|
|
description: Insufficient permissions
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Insufficient permissions"
|
|
'500':
|
|
description: Internal server error
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Internal server error"
|
|
/settings/collections/poster/{filename}:
|
|
get:
|
|
summary: Serve collection poster image
|
|
description: |
|
|
Serves a collection poster image by filename. Images are cached for optimal performance.
|
|
|
|
**Security Features:**
|
|
- Filename validation to prevent path traversal attacks
|
|
- UUID-based filenames make guessing difficult
|
|
- No authentication required (images are already admin-uploaded)
|
|
|
|
**Caching:**
|
|
- Images are cached for 1 year for optimal performance
|
|
- Content-Type is always image/jpeg (all images are converted)
|
|
tags:
|
|
- settings
|
|
parameters:
|
|
- name: filename
|
|
in: path
|
|
required: true
|
|
description: The filename of the poster image (UUID format with extension)
|
|
schema:
|
|
type: string
|
|
pattern: '^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\.(jpg|jpeg|png|webp)$'
|
|
example: "f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
responses:
|
|
'200':
|
|
description: Poster image served successfully
|
|
content:
|
|
image/jpeg:
|
|
schema:
|
|
type: string
|
|
format: binary
|
|
headers:
|
|
Cache-Control:
|
|
description: Caching directive
|
|
schema:
|
|
type: string
|
|
example: "public, max-age=31536000"
|
|
Content-Type:
|
|
description: Content type header
|
|
schema:
|
|
type: string
|
|
example: "image/jpeg"
|
|
'400':
|
|
description: Invalid filename format
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Invalid filename"
|
|
'404':
|
|
description: Poster not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Poster not found"
|
|
'500':
|
|
description: Internal server error
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Failed to serve poster"
|
|
delete:
|
|
summary: Delete collection poster image
|
|
description: |
|
|
Deletes a collection poster image by filename. Requires admin permissions.
|
|
|
|
**Important: Sync-Based Behavior**
|
|
- Poster file is immediately deleted from storage
|
|
- Collections using this poster will revert to default during the next collection sync run
|
|
- Changes are not immediately visible in Plex until sync occurs
|
|
|
|
**Security Features:**
|
|
- Admin-only access required
|
|
- Filename validation to prevent path traversal attacks
|
|
- Safe deletion with error handling
|
|
tags:
|
|
- settings
|
|
security:
|
|
- cookieAuth: []
|
|
- apiKeyAuth: []
|
|
parameters:
|
|
- name: filename
|
|
in: path
|
|
required: true
|
|
description: The filename of the poster image to delete
|
|
schema:
|
|
type: string
|
|
pattern: '^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\.(jpg|jpeg|png|webp)$'
|
|
example: "f47ac10b-58cc-4372-a567-0e02b2c3d479.jpg"
|
|
responses:
|
|
'200':
|
|
description: Poster deleted successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
message:
|
|
type: string
|
|
example: "Poster deleted successfully"
|
|
'400':
|
|
description: Invalid filename format
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Invalid filename"
|
|
'403':
|
|
description: Insufficient permissions
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Insufficient permissions"
|
|
'404':
|
|
description: Poster not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Poster not found"
|
|
'500':
|
|
description: Internal server error
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Internal server error"
|
|
/settings/tautulli:
|
|
get:
|
|
summary: Get Tautulli settings
|
|
description: Retrieves current Tautulli settings.
|
|
tags:
|
|
- settings
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/TautulliSettings'
|
|
post:
|
|
summary: Update Tautulli settings
|
|
description: Updates Tautulli settings with the provided values.
|
|
tags:
|
|
- settings
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/TautulliSettings'
|
|
responses:
|
|
'200':
|
|
description: 'Values were successfully updated'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/TautulliSettings'
|
|
/settings/tautulli/test:
|
|
post:
|
|
summary: Test Tautulli connection
|
|
description: Tests connection to a Tautulli instance.
|
|
tags:
|
|
- settings
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
hostname:
|
|
type: string
|
|
example: 'tautulli.example.com'
|
|
port:
|
|
type: number
|
|
example: 8181
|
|
apiKey:
|
|
type: string
|
|
example: 'your-api-key-here'
|
|
useSsl:
|
|
type: boolean
|
|
example: false
|
|
urlBase:
|
|
type: string
|
|
example: '/tautulli'
|
|
required:
|
|
- hostname
|
|
- port
|
|
- apiKey
|
|
responses:
|
|
'200':
|
|
description: 'Connection test successful'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: true
|
|
version:
|
|
type: string
|
|
example: '2.13.4'
|
|
'400':
|
|
description: 'Missing required parameters'
|
|
'500':
|
|
description: 'Connection test failed'
|
|
/settings/trakt:
|
|
get:
|
|
summary: Get Trakt settings
|
|
description: Retrieves current Trakt settings.
|
|
tags:
|
|
- settings
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/TraktSettings'
|
|
post:
|
|
summary: Update Trakt settings
|
|
description: Updates Trakt settings with the provided values.
|
|
tags:
|
|
- settings
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/TraktSettings'
|
|
responses:
|
|
'200':
|
|
description: 'Values were successfully updated'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/TraktSettings'
|
|
/settings/trakt/test:
|
|
post:
|
|
summary: Test Trakt connection
|
|
description: Tests connection to Trakt API with the provided API key.
|
|
tags:
|
|
- settings
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
apiKey:
|
|
type: string
|
|
description: Trakt API key (Client ID)
|
|
required:
|
|
- apiKey
|
|
responses:
|
|
'200':
|
|
description: 'Connection test successful'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: true
|
|
'400':
|
|
description: 'Missing required parameters'
|
|
'500':
|
|
description: 'Connection test failed'
|
|
/settings/overseerr:
|
|
get:
|
|
summary: Get Overseerr settings
|
|
description: Retrieves current Overseerr connection settings for external instances.
|
|
tags:
|
|
- settings
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/OverseerrSettings'
|
|
post:
|
|
summary: Update Overseerr settings
|
|
description: Updates Overseerr connection settings and tests the connection.
|
|
tags:
|
|
- settings
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/OverseerrSettings'
|
|
responses:
|
|
'200':
|
|
description: 'Values were successfully updated'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/OverseerrSettings'
|
|
'500':
|
|
description: 'Connection test failed'
|
|
/overseerr/test:
|
|
post:
|
|
summary: Test Overseerr connection
|
|
description: Tests connection to an external Overseerr instance.
|
|
tags:
|
|
- other
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
hostname:
|
|
type: string
|
|
example: 'overseerr.example.com'
|
|
port:
|
|
type: number
|
|
example: 5055
|
|
apiKey:
|
|
type: string
|
|
example: 'your-api-key-here'
|
|
useSsl:
|
|
type: boolean
|
|
example: false
|
|
urlBase:
|
|
type: string
|
|
example: '/overseerr'
|
|
required:
|
|
- hostname
|
|
- port
|
|
- apiKey
|
|
responses:
|
|
'200':
|
|
description: 'Connection test successful'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: true
|
|
version:
|
|
type: string
|
|
example: '1.33.2'
|
|
'400':
|
|
description: 'Missing required parameters'
|
|
'500':
|
|
description: 'Connection test failed'
|
|
/settings/serviceuser:
|
|
get:
|
|
summary: Get service user settings
|
|
description: Returns service user creation settings.
|
|
tags:
|
|
- settings
|
|
responses:
|
|
'200':
|
|
description: 'Service user settings returned successfully'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ServiceUserSettings'
|
|
post:
|
|
summary: Update service user settings
|
|
description: Updates service user creation settings.
|
|
tags:
|
|
- settings
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ServiceUserSettings'
|
|
responses:
|
|
'200':
|
|
description: 'Service user settings updated successfully'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ServiceUserSettings'
|
|
'500':
|
|
description: 'Settings update failed'
|
|
/settings/radarr:
|
|
get:
|
|
summary: Get Radarr settings
|
|
description: Returns all Radarr settings in a JSON array.
|
|
tags:
|
|
- settings
|
|
responses:
|
|
'200':
|
|
description: 'Values were returned'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/RadarrSettings'
|
|
post:
|
|
summary: Create Radarr instance
|
|
description: Creates a new Radarr instance from the request body.
|
|
tags:
|
|
- settings
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/RadarrSettings'
|
|
responses:
|
|
'201':
|
|
description: 'New Radarr instance created'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/RadarrSettings'
|
|
/settings/radarr/test:
|
|
post:
|
|
summary: Test Radarr configuration
|
|
description: Tests if the Radarr configuration is valid. Returns profiles and root folders on success.
|
|
tags:
|
|
- settings
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
hostname:
|
|
type: string
|
|
example: '127.0.0.1'
|
|
port:
|
|
type: number
|
|
example: 7878
|
|
apiKey:
|
|
type: string
|
|
example: yourapikey
|
|
useSsl:
|
|
type: boolean
|
|
example: false
|
|
baseUrl:
|
|
type: string
|
|
required:
|
|
- hostname
|
|
- port
|
|
- apiKey
|
|
- useSsl
|
|
responses:
|
|
'200':
|
|
description: Succesfully connected to Radarr instance
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
profiles:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ServiceProfile'
|
|
/settings/radarr/{radarrId}:
|
|
put:
|
|
summary: Update Radarr instance
|
|
description: Updates an existing Radarr instance with the provided values.
|
|
tags:
|
|
- settings
|
|
parameters:
|
|
- in: path
|
|
name: radarrId
|
|
required: true
|
|
schema:
|
|
type: integer
|
|
description: Radarr instance ID
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/RadarrSettings'
|
|
responses:
|
|
'200':
|
|
description: 'Radarr instance updated'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/RadarrSettings'
|
|
delete:
|
|
summary: Delete Radarr instance
|
|
description: Deletes an existing Radarr instance based on the radarrId parameter.
|
|
tags:
|
|
- settings
|
|
parameters:
|
|
- in: path
|
|
name: radarrId
|
|
required: true
|
|
schema:
|
|
type: integer
|
|
description: Radarr instance ID
|
|
responses:
|
|
'200':
|
|
description: 'Radarr instance updated'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/RadarrSettings'
|
|
/settings/radarr/{radarrId}/profiles:
|
|
get:
|
|
summary: Get available Radarr profiles
|
|
description: Returns a list of profiles available on the Radarr server instance in a JSON array.
|
|
tags:
|
|
- settings
|
|
parameters:
|
|
- in: path
|
|
name: radarrId
|
|
required: true
|
|
schema:
|
|
type: integer
|
|
description: Radarr instance ID
|
|
responses:
|
|
'200':
|
|
description: Returned list of profiles
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ServiceProfile'
|
|
/settings/sonarr:
|
|
get:
|
|
summary: Get Sonarr settings
|
|
description: Returns all Sonarr settings in a JSON array.
|
|
tags:
|
|
- settings
|
|
responses:
|
|
'200':
|
|
description: 'Values were returned'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/SonarrSettings'
|
|
post:
|
|
summary: Create Sonarr instance
|
|
description: Creates a new Sonarr instance from the request body.
|
|
tags:
|
|
- settings
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SonarrSettings'
|
|
responses:
|
|
'201':
|
|
description: 'New Sonarr instance created'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SonarrSettings'
|
|
/settings/sonarr/test:
|
|
post:
|
|
summary: Test Sonarr configuration
|
|
description: Tests if the Sonarr configuration is valid. Returns profiles and root folders on success.
|
|
tags:
|
|
- settings
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
hostname:
|
|
type: string
|
|
example: '127.0.0.1'
|
|
port:
|
|
type: number
|
|
example: 8989
|
|
apiKey:
|
|
type: string
|
|
example: yourapikey
|
|
useSsl:
|
|
type: boolean
|
|
example: false
|
|
baseUrl:
|
|
type: string
|
|
required:
|
|
- hostname
|
|
- port
|
|
- apiKey
|
|
- useSsl
|
|
responses:
|
|
'200':
|
|
description: Succesfully connected to Sonarr instance
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
profiles:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ServiceProfile'
|
|
/settings/sonarr/{sonarrId}:
|
|
put:
|
|
summary: Update Sonarr instance
|
|
description: Updates an existing Sonarr instance with the provided values.
|
|
tags:
|
|
- settings
|
|
parameters:
|
|
- in: path
|
|
name: sonarrId
|
|
required: true
|
|
schema:
|
|
type: integer
|
|
description: Sonarr instance ID
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SonarrSettings'
|
|
responses:
|
|
'200':
|
|
description: 'Sonarr instance updated'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SonarrSettings'
|
|
delete:
|
|
summary: Delete Sonarr instance
|
|
description: Deletes an existing Sonarr instance based on the sonarrId parameter.
|
|
tags:
|
|
- settings
|
|
parameters:
|
|
- in: path
|
|
name: sonarrId
|
|
required: true
|
|
schema:
|
|
type: integer
|
|
description: Sonarr instance ID
|
|
responses:
|
|
'200':
|
|
description: 'Sonarr instance updated'
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SonarrSettings'
|
|
/settings/public:
|
|
get:
|
|
summary: Get public settings
|
|
security: []
|
|
description: Returns settings that are not protected or sensitive. Mainly used to determine if the application has been configured for the first time.
|
|
tags:
|
|
- settings
|
|
responses:
|
|
'200':
|
|
description: Public settings returned
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PublicSettings'
|
|
/settings/initialize:
|
|
post:
|
|
summary: Initialize application
|
|
description: Sets the app as initialized, allowing the user to navigate to pages other than the setup page.
|
|
tags:
|
|
- settings
|
|
responses:
|
|
'200':
|
|
description: Public settings returned
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PublicSettings'
|
|
/settings/jobs:
|
|
get:
|
|
summary: Get scheduled jobs
|
|
description: Returns list of all scheduled jobs and details about their next execution time in a JSON array.
|
|
tags:
|
|
- settings
|
|
responses:
|
|
'200':
|
|
description: Scheduled jobs returned
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Job'
|
|
/settings/jobs/{jobId}/run:
|
|
post:
|
|
summary: Invoke a specific job
|
|
description: Invokes a specific job to run. Will return the new job status in JSON format.
|
|
tags:
|
|
- settings
|
|
parameters:
|
|
- in: path
|
|
name: jobId
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Invoked job returned
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Job'
|
|
/settings/jobs/{jobId}/cancel:
|
|
post:
|
|
summary: Cancel a specific job
|
|
description: Cancels a specific job. Will return the new job status in JSON format.
|
|
tags:
|
|
- settings
|
|
parameters:
|
|
- in: path
|
|
name: jobId
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Canceled job returned
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Job'
|
|
/settings/jobs/{jobId}/schedule:
|
|
post:
|
|
summary: Modify job schedule
|
|
description: Re-registers the job with the schedule specified. Will return the job in JSON format.
|
|
tags:
|
|
- settings
|
|
parameters:
|
|
- in: path
|
|
name: jobId
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
schedule:
|
|
type: string
|
|
example: '0 */5 * * * *'
|
|
responses:
|
|
'200':
|
|
description: Rescheduled job
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Job'
|
|
/settings/cache:
|
|
get:
|
|
summary: Get a list of active caches
|
|
description: Retrieves a list of all active caches and their current stats.
|
|
tags:
|
|
- settings
|
|
responses:
|
|
'200':
|
|
description: Caches returned
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
imageCache:
|
|
type: object
|
|
properties:
|
|
tmdb:
|
|
type: object
|
|
properties:
|
|
size:
|
|
type: number
|
|
example: 123456
|
|
imageCount:
|
|
type: number
|
|
example: 123
|
|
apiCaches:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
example: cache-id
|
|
name:
|
|
type: string
|
|
example: cache name
|
|
stats:
|
|
type: object
|
|
properties:
|
|
hits:
|
|
type: number
|
|
misses:
|
|
type: number
|
|
keys:
|
|
type: number
|
|
ksize:
|
|
type: number
|
|
vsize:
|
|
type: number
|
|
/settings/cache/{cacheId}/flush:
|
|
post:
|
|
summary: Flush a specific cache
|
|
description: Flushes all data from the cache ID provided
|
|
tags:
|
|
- settings
|
|
parameters:
|
|
- in: path
|
|
name: cacheId
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'204':
|
|
description: 'Flushed cache'
|
|
/settings/logs:
|
|
get:
|
|
summary: Returns logs
|
|
description: Returns list of all log items and details
|
|
tags:
|
|
- settings
|
|
parameters:
|
|
- in: query
|
|
name: take
|
|
schema:
|
|
type: number
|
|
nullable: true
|
|
example: 25
|
|
- in: query
|
|
name: skip
|
|
schema:
|
|
type: number
|
|
nullable: true
|
|
example: 0
|
|
- in: query
|
|
name: filter
|
|
schema:
|
|
type: string
|
|
nullable: true
|
|
enum: [debug, info, warn, error]
|
|
default: debug
|
|
- in: query
|
|
name: search
|
|
schema:
|
|
type: string
|
|
nullable: true
|
|
example: plex
|
|
responses:
|
|
'200':
|
|
description: Server log returned
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
label:
|
|
type: string
|
|
example: server
|
|
level:
|
|
type: string
|
|
example: info
|
|
message:
|
|
type: string
|
|
example: Server ready on port 5055
|
|
timestamp:
|
|
type: string
|
|
example: '2020-12-15T16:20:00.069Z'
|
|
/settings/about:
|
|
get:
|
|
summary: Get server stats
|
|
description: Returns current server stats in a JSON object.
|
|
tags:
|
|
- settings
|
|
responses:
|
|
'200':
|
|
description: Returned about settings
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
version:
|
|
type: string
|
|
example: '1.0.0'
|
|
totalRequests:
|
|
type: number
|
|
example: 100
|
|
totalMediaItems:
|
|
type: number
|
|
example: 100
|
|
tz:
|
|
type: string
|
|
nullable: true
|
|
example: Asia/Tokyo
|
|
appDataPath:
|
|
type: string
|
|
example: /app/config
|
|
/auth/me:
|
|
get:
|
|
summary: Get logged-in user
|
|
description: Returns the currently logged-in user.
|
|
tags:
|
|
- auth
|
|
- users
|
|
responses:
|
|
'200':
|
|
description: Object containing the logged-in user in JSON
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/User'
|
|
/auth/plex:
|
|
post:
|
|
summary: Sign in using a Plex token
|
|
description: Takes an `authToken` (Plex token) to log the user in. Generates a session cookie for use in further requests. If the user does not exist, and there are no other users, then a user will be created with full admin privileges. If a user logs in with access to the main Plex server, they will also have an account created, but without any permissions.
|
|
security: []
|
|
tags:
|
|
- auth
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/User'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
authToken:
|
|
type: string
|
|
required:
|
|
- authToken
|
|
/auth/local:
|
|
post:
|
|
summary: Sign in using a local account
|
|
description: Takes an `email` and a `password` to log the user in. Generates a session cookie for use in further requests.
|
|
security: []
|
|
tags:
|
|
- auth
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/User'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
email:
|
|
type: string
|
|
password:
|
|
type: string
|
|
required:
|
|
- email
|
|
- password
|
|
/auth/logout:
|
|
post:
|
|
summary: Sign out and clear session cookie
|
|
description: Completely clear the session cookie and associated values, effectively signing the user out.
|
|
tags:
|
|
- auth
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
status:
|
|
type: string
|
|
example: 'ok'
|
|
/auth/reset-password:
|
|
post:
|
|
summary: Send a reset password email
|
|
description: Sends a reset password email to the email if the user exists
|
|
security: []
|
|
tags:
|
|
- users
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
status:
|
|
type: string
|
|
example: 'ok'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
email:
|
|
type: string
|
|
required:
|
|
- email
|
|
/auth/reset-password/{guid}:
|
|
post:
|
|
summary: Reset the password for a user
|
|
description: Resets the password for a user if the given guid is connected to a user
|
|
security: []
|
|
tags:
|
|
- users
|
|
parameters:
|
|
- in: path
|
|
name: guid
|
|
required: true
|
|
schema:
|
|
type: string
|
|
example: '9afef5a7-ec89-4d5f-9397-261e96970b50'
|
|
responses:
|
|
'200':
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
status:
|
|
type: string
|
|
example: 'ok'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
password:
|
|
type: string
|
|
required:
|
|
- password
|
|
/user:
|
|
get:
|
|
summary: Get all users
|
|
description: Returns all users in a JSON object.
|
|
tags:
|
|
- users
|
|
parameters:
|
|
- in: query
|
|
name: take
|
|
schema:
|
|
type: number
|
|
nullable: true
|
|
example: 20
|
|
- in: query
|
|
name: skip
|
|
schema:
|
|
type: number
|
|
nullable: true
|
|
example: 0
|
|
- in: query
|
|
name: sort
|
|
schema:
|
|
type: string
|
|
enum: [created, updated, requests, displayname]
|
|
default: created
|
|
responses:
|
|
'200':
|
|
description: A JSON array of all users
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
pageInfo:
|
|
$ref: '#/components/schemas/PageInfo'
|
|
results:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/User'
|
|
post:
|
|
summary: Create new user
|
|
description: |
|
|
Creates a new user. Requires the `MANAGE_USERS` permission.
|
|
tags:
|
|
- users
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
email:
|
|
type: string
|
|
example: 'hey@itsme.com'
|
|
username:
|
|
type: string
|
|
permissions:
|
|
type: number
|
|
responses:
|
|
'201':
|
|
description: The created user
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/User'
|
|
put:
|
|
summary: Update batch of users
|
|
description: |
|
|
Update users with given IDs with provided values in request `body.settings`. You cannot update users' Plex tokens through this request.
|
|
|
|
Requires the `MANAGE_USERS` permission.
|
|
tags:
|
|
- users
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
ids:
|
|
type: array
|
|
items:
|
|
type: integer
|
|
permissions:
|
|
type: integer
|
|
responses:
|
|
'200':
|
|
description: Successfully updated user details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/User'
|
|
/user/import-from-plex:
|
|
post:
|
|
summary: Import all users from Plex
|
|
description: |
|
|
Fetches and imports users from the Plex server. If a list of Plex IDs is provided in the request body, only the specified users will be imported. Otherwise, all users will be imported.
|
|
|
|
Requires the `MANAGE_USERS` permission.
|
|
tags:
|
|
- users
|
|
requestBody:
|
|
required: false
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
plexIds:
|
|
type: array
|
|
items:
|
|
type: string
|
|
responses:
|
|
'201':
|
|
description: A list of the newly created users
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/User'
|
|
/movie/{movieId}:
|
|
get:
|
|
summary: Get movie details
|
|
description: Returns full movie details in a JSON object.
|
|
tags:
|
|
- movies
|
|
parameters:
|
|
- in: path
|
|
name: movieId
|
|
required: true
|
|
schema:
|
|
type: number
|
|
example: 337401
|
|
- in: query
|
|
name: language
|
|
schema:
|
|
type: string
|
|
example: en
|
|
responses:
|
|
'200':
|
|
description: Movie details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/MovieDetails'
|
|
/movie/{movieId}/recommendations:
|
|
get:
|
|
summary: Get recommended movies
|
|
description: Returns list of recommended movies based on provided movie ID in a JSON object.
|
|
tags:
|
|
- movies
|
|
parameters:
|
|
- in: path
|
|
name: movieId
|
|
required: true
|
|
schema:
|
|
type: number
|
|
example: 337401
|
|
- in: query
|
|
name: page
|
|
schema:
|
|
type: number
|
|
example: 1
|
|
default: 1
|
|
- in: query
|
|
name: language
|
|
schema:
|
|
type: string
|
|
example: en
|
|
responses:
|
|
'200':
|
|
description: List of movies
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
page:
|
|
type: number
|
|
example: 1
|
|
totalPages:
|
|
type: number
|
|
example: 20
|
|
totalResults:
|
|
type: number
|
|
example: 200
|
|
results:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/MovieResult'
|
|
/movie/{movieId}/similar:
|
|
get:
|
|
summary: Get similar movies
|
|
description: Returns list of similar movies based on the provided movieId in a JSON object.
|
|
tags:
|
|
- movies
|
|
parameters:
|
|
- in: path
|
|
name: movieId
|
|
required: true
|
|
schema:
|
|
type: number
|
|
example: 337401
|
|
- in: query
|
|
name: page
|
|
schema:
|
|
type: number
|
|
example: 1
|
|
default: 1
|
|
- in: query
|
|
name: language
|
|
schema:
|
|
type: string
|
|
example: en
|
|
responses:
|
|
'200':
|
|
description: List of movies
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
page:
|
|
type: number
|
|
example: 1
|
|
totalPages:
|
|
type: number
|
|
example: 20
|
|
totalResults:
|
|
type: number
|
|
example: 200
|
|
results:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/MovieResult'
|
|
/movie/{movieId}/ratings:
|
|
get:
|
|
summary: Get movie ratings
|
|
description: Returns ratings based on the provided movieId in a JSON object.
|
|
tags:
|
|
- movies
|
|
parameters:
|
|
- in: path
|
|
name: movieId
|
|
required: true
|
|
schema:
|
|
type: number
|
|
example: 337401
|
|
responses:
|
|
'200':
|
|
description: Ratings returned
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
title:
|
|
type: string
|
|
example: Mulan
|
|
year:
|
|
type: number
|
|
example: 2020
|
|
url:
|
|
type: string
|
|
example: 'http://www.rottentomatoes.com/m/mulan_2020/'
|
|
criticsScore:
|
|
type: number
|
|
example: 85
|
|
criticsRating:
|
|
type: string
|
|
enum: ['Rotten', 'Fresh', 'Certified Fresh']
|
|
audienceScore:
|
|
type: number
|
|
example: 65
|
|
audienceRating:
|
|
type: string
|
|
enum: ['Spilled', 'Upright']
|
|
/movie/{movieId}/ratingscombined:
|
|
get:
|
|
summary: Get RT and IMDB movie ratings combined
|
|
description: Returns ratings from RottenTomatoes and IMDB based on the provided movieId in a JSON object.
|
|
tags:
|
|
- movies
|
|
parameters:
|
|
- in: path
|
|
name: movieId
|
|
required: true
|
|
schema:
|
|
type: number
|
|
example: 337401
|
|
responses:
|
|
'200':
|
|
description: Ratings returned
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
rt:
|
|
type: object
|
|
properties:
|
|
title:
|
|
type: string
|
|
example: Mulan
|
|
year:
|
|
type: number
|
|
example: 2020
|
|
url:
|
|
type: string
|
|
example: 'http://www.rottentomatoes.com/m/mulan_2020/'
|
|
criticsScore:
|
|
type: number
|
|
example: 85
|
|
criticsRating:
|
|
type: string
|
|
enum: ['Rotten', 'Fresh', 'Certified Fresh']
|
|
audienceScore:
|
|
type: number
|
|
example: 65
|
|
audienceRating:
|
|
type: string
|
|
enum: ['Spilled', 'Upright']
|
|
imdb:
|
|
type: object
|
|
properties:
|
|
title:
|
|
type: string
|
|
example: I am Legend
|
|
url:
|
|
type: string
|
|
example: 'https://www.imdb.com/title/tt0480249'
|
|
criticsScore:
|
|
type: number
|
|
example: 6.5
|
|
/tv/{tvId}:
|
|
get:
|
|
summary: Get TV details
|
|
description: Returns full TV details in a JSON object.
|
|
tags:
|
|
- tv
|
|
parameters:
|
|
- in: path
|
|
name: tvId
|
|
required: true
|
|
schema:
|
|
type: number
|
|
example: 76479
|
|
- in: query
|
|
name: language
|
|
schema:
|
|
type: string
|
|
example: en
|
|
responses:
|
|
'200':
|
|
description: TV details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/TvDetails'
|
|
/tv/{tvId}/season/{seasonId}:
|
|
get:
|
|
summary: Get season details and episode list
|
|
description: Returns season details with a list of episodes in a JSON object.
|
|
tags:
|
|
- tv
|
|
parameters:
|
|
- in: path
|
|
name: tvId
|
|
required: true
|
|
schema:
|
|
type: number
|
|
example: 76479
|
|
- in: path
|
|
name: seasonId
|
|
required: true
|
|
schema:
|
|
type: number
|
|
example: 1
|
|
- in: query
|
|
name: language
|
|
schema:
|
|
type: string
|
|
example: en
|
|
responses:
|
|
'200':
|
|
description: TV details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Season'
|
|
/media:
|
|
get:
|
|
summary: Get media
|
|
description: Returns all media (can be filtered and limited) in a JSON object.
|
|
tags:
|
|
- media
|
|
parameters:
|
|
- in: query
|
|
name: take
|
|
schema:
|
|
type: number
|
|
nullable: true
|
|
example: 20
|
|
- in: query
|
|
name: skip
|
|
schema:
|
|
type: number
|
|
nullable: true
|
|
example: 0
|
|
- in: query
|
|
name: filter
|
|
schema:
|
|
type: string
|
|
nullable: true
|
|
enum:
|
|
[
|
|
all,
|
|
available,
|
|
partial,
|
|
allavailable,
|
|
processing,
|
|
pending,
|
|
deleted,
|
|
]
|
|
- in: query
|
|
name: sort
|
|
schema:
|
|
type: string
|
|
enum: [added, modified, mediaAdded]
|
|
default: added
|
|
responses:
|
|
'200':
|
|
description: Returned media
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
pageInfo:
|
|
$ref: '#/components/schemas/PageInfo'
|
|
results:
|
|
type: array
|
|
/media/{mediaId}:
|
|
delete:
|
|
summary: Delete media item
|
|
description: Removes a media item. The `MANAGE_REQUESTS` permission is required to perform this action.
|
|
tags:
|
|
- media
|
|
parameters:
|
|
- in: path
|
|
name: mediaId
|
|
description: Media ID
|
|
required: true
|
|
example: '1'
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'204':
|
|
description: Succesfully removed media item
|
|
/media/{mediaId}/{status}:
|
|
post:
|
|
summary: Update media status
|
|
description: Updates a media item's status and returns the media in JSON format
|
|
tags:
|
|
- media
|
|
parameters:
|
|
- in: path
|
|
name: mediaId
|
|
description: Media ID
|
|
required: true
|
|
example: '1'
|
|
schema:
|
|
type: string
|
|
- in: path
|
|
name: status
|
|
description: New status
|
|
required: true
|
|
example: available
|
|
schema:
|
|
type: string
|
|
enum: [available, partial, processing, pending, unknown, deleted]
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
is4k:
|
|
type: boolean
|
|
example: false
|
|
responses:
|
|
'200':
|
|
description: Returned media
|
|
/media/{mediaId}/watch_data:
|
|
get:
|
|
summary: Get watch data
|
|
description: |
|
|
Returns play count, play duration, and users who have watched the media.
|
|
|
|
Requires the `ADMIN` permission.
|
|
tags:
|
|
- media
|
|
parameters:
|
|
- in: path
|
|
name: mediaId
|
|
description: Media ID
|
|
required: true
|
|
example: '1'
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Users
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
data:
|
|
type: object
|
|
properties:
|
|
playCount7Days:
|
|
type: number
|
|
playCount30Days:
|
|
type: number
|
|
playCount:
|
|
type: number
|
|
users:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/User'
|
|
data4k:
|
|
type: object
|
|
properties:
|
|
playCount7Days:
|
|
type: number
|
|
playCount30Days:
|
|
type: number
|
|
playCount:
|
|
type: number
|
|
users:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/User'
|
|
/service/radarr:
|
|
get:
|
|
summary: Get non-sensitive Radarr server list
|
|
description: Returns a list of Radarr server IDs and names in a JSON object.
|
|
tags:
|
|
- service
|
|
responses:
|
|
'200':
|
|
description: Request successful
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/RadarrSettings'
|
|
/service/radarr/{radarrId}:
|
|
get:
|
|
summary: Get Radarr server quality profiles and root folders
|
|
description: Returns a Radarr server's quality profile and root folder details in a JSON object.
|
|
tags:
|
|
- service
|
|
parameters:
|
|
- in: path
|
|
name: radarrId
|
|
required: true
|
|
schema:
|
|
type: number
|
|
example: 0
|
|
responses:
|
|
'200':
|
|
description: Request successful
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
server:
|
|
$ref: '#/components/schemas/RadarrSettings'
|
|
profiles:
|
|
$ref: '#/components/schemas/ServiceProfile'
|
|
/service/sonarr:
|
|
get:
|
|
summary: Get non-sensitive Sonarr server list
|
|
description: Returns a list of Sonarr server IDs and names in a JSON object.
|
|
tags:
|
|
- service
|
|
responses:
|
|
'200':
|
|
description: Request successful
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/SonarrSettings'
|
|
/service/sonarr/{sonarrId}:
|
|
get:
|
|
summary: Get Sonarr server quality profiles and root folders
|
|
description: Returns a Sonarr server's quality profile and root folder details in a JSON object.
|
|
tags:
|
|
- service
|
|
parameters:
|
|
- in: path
|
|
name: sonarrId
|
|
required: true
|
|
schema:
|
|
type: number
|
|
example: 0
|
|
responses:
|
|
'200':
|
|
description: Request successful
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
server:
|
|
$ref: '#/components/schemas/SonarrSettings'
|
|
profiles:
|
|
$ref: '#/components/schemas/ServiceProfile'
|
|
/service/sonarr/lookup/{tmdbId}:
|
|
get:
|
|
summary: Get series from Sonarr
|
|
description: Returns a list of series returned by searching for the name in Sonarr.
|
|
tags:
|
|
- service
|
|
parameters:
|
|
- in: path
|
|
name: tmdbId
|
|
required: true
|
|
schema:
|
|
type: number
|
|
example: 0
|
|
responses:
|
|
'200':
|
|
description: Request successful
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/SonarrSeries'
|
|
/backdrops:
|
|
get:
|
|
summary: Get backdrops of trending items
|
|
description: Returns a list of backdrop image paths in a JSON array.
|
|
security: []
|
|
tags:
|
|
- tmdb
|
|
responses:
|
|
'200':
|
|
description: Results
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
type: string
|
|
/keyword/{keywordId}:
|
|
get:
|
|
summary: Get keyword
|
|
description: |
|
|
Returns a single keyword in JSON format.
|
|
tags:
|
|
- other
|
|
parameters:
|
|
- in: path
|
|
name: keywordId
|
|
required: true
|
|
schema:
|
|
type: number
|
|
example: 1
|
|
responses:
|
|
'200':
|
|
description: Keyword returned
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Keyword'
|
|
/missing-items:
|
|
get:
|
|
summary: Get missing item requests
|
|
description: |
|
|
Returns a paginated list of missing item requests with optional filtering.
|
|
tags:
|
|
- missing-items
|
|
parameters:
|
|
- in: query
|
|
name: limit
|
|
schema:
|
|
type: integer
|
|
default: 10
|
|
minimum: 1
|
|
maximum: 100
|
|
description: Number of items to return
|
|
- in: query
|
|
name: offset
|
|
schema:
|
|
type: integer
|
|
default: 0
|
|
minimum: 0
|
|
description: Number of items to skip
|
|
- in: query
|
|
name: status
|
|
schema:
|
|
type: string
|
|
enum: [pending, approved, declined, available, processing, failed, partially_available]
|
|
description: Filter by request status
|
|
- in: query
|
|
name: mediaType
|
|
schema:
|
|
type: string
|
|
enum: [movie, tv]
|
|
description: Filter by media type
|
|
- in: query
|
|
name: collectionSource
|
|
schema:
|
|
type: string
|
|
enum: [trakt, tmdb, imdb, letterboxd]
|
|
description: Filter by collection source
|
|
- in: query
|
|
name: requestService
|
|
schema:
|
|
type: string
|
|
enum: [overseerr, radarr, sonarr]
|
|
description: Filter by request service
|
|
responses:
|
|
'200':
|
|
description: Missing item requests returned
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/MissingItemsResponse'
|
|
/missing-items/recent:
|
|
get:
|
|
summary: Get recent missing item requests
|
|
description: |
|
|
Returns the most recent missing item requests for dashboard display.
|
|
tags:
|
|
- missing-items
|
|
parameters:
|
|
- in: query
|
|
name: limit
|
|
schema:
|
|
type: integer
|
|
default: 5
|
|
minimum: 1
|
|
maximum: 20
|
|
description: Number of recent items to return
|
|
responses:
|
|
'200':
|
|
description: Recent missing item requests returned
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
results:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/MissingItemRequest'
|
|
/missing-items/stats:
|
|
get:
|
|
summary: Get missing item statistics
|
|
description: |
|
|
Returns statistics about missing item requests including status breakdowns and source/service distribution.
|
|
tags:
|
|
- missing-items
|
|
responses:
|
|
'200':
|
|
description: Missing item statistics returned
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/MissingItemStats'
|
|
/missing-items/sync:
|
|
post:
|
|
summary: Sync missing item status
|
|
description: |
|
|
Synchronizes the status of missing item requests with their current status in Overseerr.
|
|
This endpoint checks recent missing item requests and updates their status based on
|
|
the current state in Overseerr (e.g., pending → declined, approved → available).
|
|
tags:
|
|
- missing-items
|
|
responses:
|
|
'200':
|
|
description: Missing item status sync completed successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
message:
|
|
type: string
|
|
example: "Missing item status sync completed"
|
|
'500':
|
|
description: Failed to sync missing item status
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
message:
|
|
type: string
|
|
example: "Failed to sync missing item status"
|
|
/dashboard/stats:
|
|
get:
|
|
summary: Get dashboard statistics
|
|
description: |
|
|
Returns general dashboard statistics including collection counts, activity stats from Tautulli, and weekly plays.
|
|
tags:
|
|
- dashboard
|
|
responses:
|
|
'200':
|
|
description: Dashboard statistics returned successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/DashboardStats'
|
|
'500':
|
|
description: Failed to get dashboard statistics
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Failed to get dashboard stats"
|
|
message:
|
|
type: string
|
|
example: "Tautulli connection failed"
|
|
/dashboard/collections:
|
|
get:
|
|
summary: Get collection statistics
|
|
description: |
|
|
Returns detailed collection statistics from Tautulli including play counts, duration, and user activity.
|
|
tags:
|
|
- dashboard
|
|
parameters:
|
|
- in: query
|
|
name: limit
|
|
schema:
|
|
type: integer
|
|
default: 10
|
|
minimum: 1
|
|
maximum: 50
|
|
description: Number of collections to return
|
|
- in: query
|
|
name: statType
|
|
schema:
|
|
type: string
|
|
enum: [plays, duration]
|
|
default: plays
|
|
description: Type of statistics to sort by
|
|
- in: query
|
|
name: days
|
|
schema:
|
|
type: integer
|
|
default: 30
|
|
minimum: 1
|
|
maximum: 365
|
|
description: Number of days to include in statistics
|
|
responses:
|
|
'200':
|
|
description: Collection statistics returned successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CollectionStatsResponse'
|
|
'400':
|
|
description: Tautulli not configured
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Tautulli not configured"
|
|
message:
|
|
type: string
|
|
example: "Tautulli settings are required to fetch collection statistics"
|
|
'500':
|
|
description: Failed to get collection statistics
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Failed to get collection statistics"
|
|
message:
|
|
type: string
|
|
example: "Tautulli API error"
|
|
/dashboard/activity:
|
|
get:
|
|
summary: Get activity statistics
|
|
description: |
|
|
Returns recent activity and general statistics from Tautulli including top movies and TV shows.
|
|
tags:
|
|
- dashboard
|
|
parameters:
|
|
- in: query
|
|
name: days
|
|
schema:
|
|
type: integer
|
|
default: 7
|
|
minimum: 1
|
|
maximum: 365
|
|
description: Number of days to include in activity statistics
|
|
- in: query
|
|
name: limit
|
|
schema:
|
|
type: integer
|
|
default: 10
|
|
minimum: 1
|
|
maximum: 50
|
|
description: Number of items to return
|
|
responses:
|
|
'200':
|
|
description: Activity statistics returned successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ActivityStatsResponse'
|
|
'400':
|
|
description: Tautulli not configured
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Tautulli not configured"
|
|
message:
|
|
type: string
|
|
example: "Tautulli settings are required to fetch activity statistics"
|
|
'500':
|
|
description: Failed to get activity statistics
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "Failed to get activity statistics"
|
|
message:
|
|
type: string
|
|
example: "Tautulli API error"
|
|
|
|
# Hub Management Endpoints
|
|
/hubs/configs:
|
|
get:
|
|
summary: Get current Plex hub configurations
|
|
tags:
|
|
- settings
|
|
responses:
|
|
'200':
|
|
description: Hub configurations returned successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
hubConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexHubConfig'
|
|
preExistingCollectionConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexHubConfig'
|
|
'500':
|
|
description: Failed to get hub configurations
|
|
post:
|
|
summary: Save Plex hub configurations
|
|
tags:
|
|
- settings
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
hubConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexHubConfig'
|
|
preExistingCollectionConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexHubConfig'
|
|
responses:
|
|
'200':
|
|
description: Configurations saved successfully
|
|
'400':
|
|
description: Invalid input
|
|
'500':
|
|
description: Failed to save configurations
|
|
|
|
/hubs/configs/append:
|
|
post:
|
|
summary: Append new hub configurations to existing ones
|
|
tags:
|
|
- settings
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
hubConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexHubConfig'
|
|
preExistingCollectionConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexHubConfig'
|
|
responses:
|
|
'200':
|
|
description: Configurations appended successfully
|
|
'400':
|
|
description: Invalid input
|
|
'500':
|
|
description: Failed to append configurations
|
|
|
|
/hubs/libraries/{sectionId}/move:
|
|
put:
|
|
summary: Move a hub to a new position in the library
|
|
tags:
|
|
- settings
|
|
parameters:
|
|
- in: path
|
|
name: sectionId
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: Plex library section ID
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
hubId:
|
|
type: string
|
|
description: Hub identifier to move
|
|
afterHubId:
|
|
type: string
|
|
description: Hub identifier to move after (optional)
|
|
required:
|
|
- hubId
|
|
responses:
|
|
'200':
|
|
description: Hub moved successfully
|
|
'400':
|
|
description: Invalid input
|
|
'500':
|
|
description: Failed to move hub
|
|
|
|
/hubs/libraries/{sectionId}/reorder:
|
|
put:
|
|
summary: Reorder multiple hubs in a library section
|
|
tags:
|
|
- settings
|
|
parameters:
|
|
- in: path
|
|
name: sectionId
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: Plex library section ID
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
hubOrder:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Array of hub IDs in desired order
|
|
required:
|
|
- hubOrder
|
|
responses:
|
|
'200':
|
|
description: Hubs reordered successfully
|
|
'400':
|
|
description: Invalid input
|
|
'500':
|
|
description: Failed to reorder hubs
|
|
|
|
/hubs/libraries/{sectionId}/visibility:
|
|
put:
|
|
summary: Update hub visibility settings
|
|
tags:
|
|
- settings
|
|
parameters:
|
|
- in: path
|
|
name: sectionId
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: Plex library section ID
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
hubId:
|
|
type: string
|
|
description: Hub identifier
|
|
visibility:
|
|
type: object
|
|
description: Visibility configuration
|
|
required:
|
|
- hubId
|
|
- visibility
|
|
responses:
|
|
'200':
|
|
description: Hub visibility updated successfully
|
|
'400':
|
|
description: Invalid input
|
|
'500':
|
|
description: Failed to update hub visibility
|
|
|
|
# Discovery Endpoints
|
|
/discovery/hubs/libraries:
|
|
get:
|
|
summary: Get all library hubs across all sections
|
|
tags:
|
|
- search
|
|
responses:
|
|
'200':
|
|
description: Library hubs returned successfully
|
|
'500':
|
|
description: Failed to fetch library hubs
|
|
|
|
/discovery/hubs/libraries/{sectionId}:
|
|
get:
|
|
summary: Get hubs for a specific library section
|
|
tags:
|
|
- search
|
|
parameters:
|
|
- in: path
|
|
name: sectionId
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: Plex library section ID
|
|
responses:
|
|
'200':
|
|
description: Library hubs returned successfully
|
|
'500':
|
|
description: Failed to fetch library hubs
|
|
|
|
/discovery/hubs/libraries/{sectionId}/manage:
|
|
get:
|
|
summary: Get hub management interface for a library section
|
|
tags:
|
|
- search
|
|
parameters:
|
|
- in: path
|
|
name: sectionId
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: Plex library section ID
|
|
responses:
|
|
'200':
|
|
description: Hub management data returned successfully
|
|
'500':
|
|
description: Failed to fetch hub management data
|
|
|
|
/discovery/hubs/scan:
|
|
get:
|
|
summary: Discover available Plex hubs and convert them to hub configurations
|
|
tags:
|
|
- search
|
|
responses:
|
|
'200':
|
|
description: Hub discovery completed successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
discoveredHubConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexHubConfig'
|
|
discoveredPreExistingConfigs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PlexHubConfig'
|
|
totalHubsFound:
|
|
type: integer
|
|
totalPreExistingCollectionsFound:
|
|
type: integer
|
|
totalActualCollections:
|
|
type: integer
|
|
'500':
|
|
description: Failed to discover Plex hubs
|
|
|
|
/discovery/hubs/status:
|
|
get:
|
|
summary: Get hub management system status and capabilities
|
|
tags:
|
|
- search
|
|
responses:
|
|
'200':
|
|
description: Hub management status returned successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
enabled:
|
|
type: boolean
|
|
plexConnected:
|
|
type: boolean
|
|
libraryCount:
|
|
type: integer
|
|
capabilities:
|
|
type: object
|
|
properties:
|
|
hubReordering:
|
|
type: boolean
|
|
visibilityControl:
|
|
type: boolean
|
|
builtInHubManagement:
|
|
type: boolean
|
|
collectionHubManagement:
|
|
type: boolean
|
|
'500':
|
|
description: Failed to get hub management status
|
|
|
|
security:
|
|
- cookieAuth: []
|
|
- apiKey: []
|