Jellyfin Enhanced's API
Jellyfin Enhanced adds features like Bookmarks and User Reviews/Ratings that live entirely in this plugin, not in Jellyfin Server itself. A user of any other Jellyfin client (Wholphin, Streamyfin, Afinity, a custom app, etc.) only gets these features if that client talks to the endpoints on this page directly, over plain HTTP with a Jellyfin token or API key. No client-side plugin, SDK, or Jellyfin Enhanced code is required, just an HTTP client and the request shapes documented below.
Requirements before any of this works:
- The Jellyfin Enhanced plugin must be installed and enabled on the target server
- Your app needs a Jellyfin auth token (per-user, from that user logging in) or a server API key, exactly as it would for any other Jellyfin Server request. See Quick Start below for how to get one and which calls need which
- Bookmarks and Reviews both use TMDB IDs, not Jellyfin item IDs, to key data server-side (bookmarks also take an
itemIdwhen adding one, see Bookmarks API endpoints)
What this lets a client build, using only these HTTP endpoints:
- A "bookmark this moment" button on the video player, and a bookmarks list/library screen (see Bookmarks API)
- Star ratings and written reviews on a movie/show/season/episode details page, shared across every user on the server (see Reviews API)
Jellyfin 10.11 vs 12: the auth header that works is not the same
This plugin builds one identical set of endpoints for both Jellyfin 10.11 and 12, so the request/response shapes on this page don't change between server versions, only which auth header Jellyfin Server itself accepts does. Confirmed live against both a 10.11.11 and a 12.0.0 server:
X-Emby-TokenandX-Emby-Authorizationwork on Jellyfin 10.11- On Jellyfin 12, both of the above are rejected by default (
401/400) — Jellyfin 12 ships withServerConfiguration.EnableLegacyAuthorizationoff, and a server-side migration force-disables it even on servers upgraded from 10.x Authorization: MediaBrowser Token="..."(and, for the one pre-login call below,Authorization: MediaBrowser Client="...", Device="...", DeviceId="...", Version="...") works on both versions, unaffected by that setting
A client that only wants to support one code path, rather than detecting the server version and switching headers, should always send Authorization, never X-Emby-Token/X-Emby-Authorization alone. Some examples below still show X-Emby-Token because that's what a plain server API key traditionally uses; substitute Authorization: MediaBrowser Token="{apiKeyOrUserToken}" for the same call if the target server might be running Jellyfin 12.
/JellyfinEnhanced
Check version
/JellyfinEnhanced/version
- Jellyfin Server URL (
JELLYFIN_URL)
Quick Start: Normal User vs Admin
There are two distinct ways to call the Bookmarks and Reviews endpoints below, depending on who is calling and whose data they are touching.
As a normal user, your own data only
Log in as that user to get a per-user access token, then use that token in Authorization: MediaBrowser Token="..." for every call. With this token you can only read or write your own bookmarks and your own review, never another user's.
How do I get JELLYFIN_USER_ACCESS_TOKEN?
Call Jellyfin's own POST /Users/AuthenticateByName with that user's username and password. This is not a Jellyfin Enhanced endpoint, it is part of Jellyfin Server's own API.
A client-identification header (Client, Device, DeviceId, Version, any values that identify your app) is required here, Jellyfin rejects the request without it even though no token exists yet at this point. Use the Authorization header for it, not X-Emby-Authorization: confirmed live against a Jellyfin 12 server, X-Emby-Authorization alone gets a bare 400 Error processing request there, because Jellyfin 12 disables the legacy X-Emby-*/X-MediaBrowser-* header family by default (ServerConfiguration.EnableLegacyAuthorization). Authorization: MediaBrowser ... is never gated by that setting, on 10.11 or 12, so it is the one header name safe to hard-code in a client.
The response body includes an AccessToken field, that is JELLYFIN_USER_ACCESS_TOKEN. It does not expire on its own, it stays valid until the user signs out or an admin revokes it from the Jellyfin Dashboard.
Alternatively, Quick Connect gets a token without the app ever handling the user's password.
- Post your own review:
POST /JellyfinEnhanced/reviews/{mediaType}/{tmdbId} - Delete your own review:
DELETE /JellyfinEnhanced/reviews/{mediaType}/{tmdbId} - Add a bookmark for yourself:
POST /JellyfinEnhanced/user-settings/{yourUserId}/bookmark.json/add - Remove a bookmark for yourself:
DELETE /JellyfinEnhanced/user-settings/{yourUserId}/bookmark.json/{bookmarkId}
As an admin, any user's data
Generate a server API key from the Jellyfin Dashboard (Settings > API Keys), created by an Administrator account. Use that key in X-Emby-Token (Reviews) or Authorization: MediaBrowser Token="..." (Bookmarks), and put the target user's ID directly in the URL. This is the pattern a 3rd-party app should use to manage bookmarks and reviews for every user with a single credential, with no per-user login required.
- Post a review as a specific user:
POST /JellyfinEnhanced/reviews/admin/{userIdN}/{mediaType}/{tmdbId} - Delete a specific user's review:
DELETE /JellyfinEnhanced/reviews/admin/{userIdN}/{mediaType}/{tmdbId} - Add a bookmark for a specific user:
POST /JellyfinEnhanced/user-settings/{userId}/bookmark.json/add - Remove a bookmark for a specific user:
DELETE /JellyfinEnhanced/user-settings/{userId}/bookmark.json/{bookmarkId}
A non-admin token used against another user's {userId} is rejected. Full request and response details for every endpoint are below.
Ratings vs. text reviews
{tmdbId} in every Reviews endpoint above also accepts {tmdbId}:s{season} or {tmdbId}:s{season}:e{episode}, so a TV show can carry its own review plus separate ones per season/episode. A review's rating (1-5) and content are independent: send rating alone for a star-rating-only UI, content alone for text-only, or both. See Rating and content rules in the Reviews API section.
Bookmarks API
New in v11.13.0.0
The additive bookmark.json/add and bookmark.json/{bookmarkId} endpoints below, and admin access to any user's bookmarks via a server API key, are new in v11.13.0.0. Earlier versions only support reading or replacing the whole file with a per-user access token.
Bookmarks Storage Directory
Bookmarks are stored as bookmark.json (singular), inside a folder named after the user's ID, under the plugin's own configuration directory:
{JELLYFIN_DATA_DIR}/plugins/configurations/Jellyfin.Plugin.JellyfinEnhanced/JELLYFIN_USER_ID/bookmark.json
JELLYFIN_USER_ID here is the user's GUID with hyphens stripped and lowercased (e.g. 9285e8b541494149...), regardless of the casing or format used in the URL.
userID? JELLYFIN_USER_ID?
userIDis Jellyfin Server's unique ID for each user
JELLYFIN_USER_IDis a placeholder for the user'suserID
Reference:
Tip
A simple way to find which userID belongs to which user:
- Jellyfin Dashboard:
Users - Click a user's profile
- The
userIDfor that user appears in the URL. For example:9285e8b54149414941494edb9e464dcdin the URLhttp://localhost:8096/#/dashboard/users/profile?userId=9285e8b54149414941494edb9e464dcd
{
"Bookmarks": {
"unique-bookmark-id": {
"ItemId": "jellyfin-item-id",
"TmdbId": "12345",
"TvdbId": "67890",
"MediaType": "movie" | "tv",
"Name": "Item Name",
"Timestamp": 123.45,
"Label": "Epic scene",
"CreatedAt": "2026-01-03T12:00:00.000Z",
"UpdatedAt": "2026-01-03T12:00:00.000Z",
"SyncedFrom": "original-item-id"
}
}
}
Field casing is PascalCase, except on add
The Get, Replace-all, and Remove endpoints below all read/write BookmarkItem fields in PascalCase (ItemId, TmdbId, MediaType, Timestamp, ...) as shown above — confirmed against a live server, not just the source. The one exception is the Add one Bookmark endpoint: its request body accepts either casing (ASP.NET Core's model binder is case-insensitive), but its own success response is a separate small object using camelCase ({"success": true, "id": "..."}). Don't assume one casing convention across every Bookmarks endpoint.
Authentication: two ways to call these
- As the user themselves: pass a per-user access token (obtained by that user logging in) in
Authorization: MediaBrowser Token="...". Works for the user's ownJELLYFIN_USER_IDonly. - As an admin, for any user: pass a server Administrator API key. The plugin will let an Administrator key act on any
JELLYFIN_USER_ID, which is what lets a 3rd-party app manage bookmarks for every user with a single credential.
A non-admin user calling with someone else's JELLYFIN_USER_ID is rejected.
Bookmarks API endpoints
bookmark.json is one of several per-user settings files served under /user-settings/{userId}/{file} (the same pattern covers settings.json, shortcuts.json, elsewhere.json, and hidden-content.json).
Get Bookmarks
/JellyfinEnhanced/user-settings/{userId}/bookmark.json
JELLYFIN_TOKEN: a per-user access token forJELLYFIN_USER_ID, or an Administrator API key- Jellyfin Server URL
JELLYFIN_SERVER_URL
Returns the bookmark.json contents directly, not wrapped. An empty {"Bookmarks": {}} if the user has none yet.
Replace all Bookmarks
/JellyfinEnhanced/user-settings/{userId}/bookmark.json
Overwrites the whole file. Use the additive endpoint below instead if you only want to add or remove one bookmark.
JELLYFIN_TOKEN: a per-user access token forJELLYFIN_USER_ID, or an Administrator API key- Jellyfin Server URL
JELLYFIN_SERVER_URL - The request body is the raw bookmarks object itself, not wrapped in
{ "fileName": ..., "data": ... }. Each bookmark item's fields are PascalCase (ItemId,TmdbId,MediaType,Timestamp,Label, ...), matching the Example Data structure above.
Add one Bookmark
/JellyfinEnhanced/user-settings/{userId}/bookmark.json/add
Adds a single bookmark without touching the rest of the file. The server generates the bookmark ID and timestamps and returns the new ID.
curl -X POST \
-H 'Content-Type: application/json' \
-H 'Authorization: MediaBrowser Token="JELLYFIN_TOKEN"' \
-d '{
"itemId": "jellyfin-item-id",
"tmdbId": "1949",
"mediaType": "movie",
"name": "Zodiac",
"timestamp": 1234.5,
"label": "Great scene"
}' \
'JELLYFIN_SERVER_URL/JellyfinEnhanced/user-settings/JELLYFIN_USER_ID/bookmark.json/add'
JELLYFIN_TOKEN: a per-user access token forJELLYFIN_USER_ID, or an Administrator API keyitemIdis required.tmdbId,tvdbId,mediaType,name,timestamp,label, andsyncedFromare all optional.
Response: {"success": true, "id": "Bm_1234567890_abc123xyz"}
Remove one Bookmark
/JellyfinEnhanced/user-settings/{userId}/bookmark.json/{bookmarkId}
BOOKMARK_IDis the ID returned by the add endpoint, or a key from theBookmarksobject returned by the get endpoint- Returns
404with{"success": false, "removed": false}if no bookmark with that ID exists
Reviews API
New in v11.13.0.0
Admin access to any user's reviews via a server API key is new in v11.13.0.0. Earlier versions only support reading reviews or writing your own review with a per-user access token.
User reviews and ratings, shared across all users on the server. Each review is a content string and an optional 1-5 star rating, keyed by author + item, and reviews for one item are stored together in a single shared reviews.json (not a per-user file). This is the API to use if you want to build star ratings, review lists, or an average-rating badge for a client.
Rating and content rules
Every write endpoint below (self or admin) validates the same ReviewPayload body:
content(string, optional): trimmed server-side; rejected with400if longer than 2000 charactersrating(number, optional): must be1-5inclusive in0.5increments (e.g.4.5), or omitted;0,6, or a value not on a half-star boundary (e.g.4.3) is rejected with400- At least one of
contentorratingmust be present, an empty payload ({}) is rejected with400 {"success": false, "message": "A rating or review text is required."} - This means a ratings-only review (
{"rating": 4}, no text) and a text-only review ({"content": "..."}, no rating) are both valid
Reviewing a season or episode of a TV show
{tmdbId} in the URL is not just the bare TMDB ID, it also accepts two extended forms so a single mediaType: tv item can carry separate reviews per season or per episode:
{tmdbId}— the show as a whole, e.g.1399{tmdbId}:s{season}— a specific season, e.g.1399:s1{tmdbId}:s{season}:e{episode}— a specific episode, e.g.1399:s1:e1
Any other shape (letters, missing digits, extra segments) is rejected with 400 {"message": "Invalid TmdbId."}. mediaType must always be movie or tv, both movie:s1 and any mediaType other than movie/tv are rejected the same way. URL-encode the colons (%3A) if your HTTP client doesn't do it for you.
Get reviews for an item
/JellyfinEnhanced/reviews/{mediaType}/{tmdbId}
- Jellyfin Server API key (
JELLYFIN_API_KEY) mediaType:movieortvTMDB_ID: the item's TMDB ID, or one of the season/episode forms above
A plain API key is enough to read reviews, there is no per-user identity involved here. Any authenticated caller (per-user token or API key) sees every non-hidden reviewer's review; an admin caller always sees every review, including ones from hidden or disabled authors, for moderation.
Response:
{
"reviews": [
{
"userId": "9285e8b541494149...",
"userName": "alice",
"tmdbId": "TMDB_ID",
"mediaType": "movie",
"content": "Great movie!",
"rating": 5,
"createdAt": "2026-01-03T12:00:00.000Z",
"updatedAt": "2026-01-03T12:00:00.000Z"
}
]
}
reviewsis[], never missing, when nobody has reviewed the item yetratingis omitted from the object entirely for a text-only review, it is not present asrating: null. Check"rating" in review(or the equivalent in your language) rather than a null check if you need to tell "no rating given" apart from "rated 0".contentbehaves differently: a rating-only review still getscontent: ""rather than omitting the key- Average rating and review count are not pre-computed by the server, a client wanting those should reduce over the
ratingfield of the returned array itself, skipping entries where the key is absent
Add or edit your own review
/JellyfinEnhanced/reviews/{mediaType}/{tmdbId}
Creates your review if you don't have one for this item yet, or updates it (both content and rating are replaced, not merged) if you do.
- A per-user access token (
JELLYFIN_USER_ACCESS_TOKEN), this writes the review under whichever user the token belongs to ratingis optional, omit it to leave a text-only review; see Rating and content rules above for the accepted values- Response:
{"success": true}. A400with{"success": false, "message": "..."}explains which validation rule failed
Delete your own review
/JellyfinEnhanced/reviews/{mediaType}/{tmdbId}
- Response:
{"success": true}whether or not a review existed, this endpoint does not report404for a no-op delete (unlike the bookmark and admin-review delete endpoints below)
Add or edit a review as a specific user (admin)
/JellyfinEnhanced/reviews/admin/{userIdN}/{mediaType}/{tmdbId}
Lets an Administrator API key create or update a review for any user, identified by an explicit userIdN. This is what a 3rd-party app should use to manage reviews for multiple users with one credential. Creates the review if none exists yet for that user and item, or updates it otherwise.
- Jellyfin Server Administrator API key (
JELLYFIN_API_KEY) JELLYFIN_USER_IDhere is the 32-character hex form with no dashes (the same format returned by the get-bookmarks endpoint, not the dashed form shown in the Jellyfin dashboard URL)- Same rating and content rules as the self-review endpoint above;
ratingstill only allows1-5in0.5increments or omitted, an admin key does not bypass validation - Response:
{"success": true}. A non-admin key gets403 Forbidden, a malformeduserIdNgets400
Delete a specific user's review (admin)
/JellyfinEnhanced/reviews/admin/{userIdN}/{mediaType}/{tmdbId}
Returns 404 with {"success": false, "removed": false} if no review exists for that user and item.
Seerr Integration API
/JellyfinEnhanced/jellyseerr
Jellyfin Server's API
These values are from Jellyfin Server's API:
X-Jellyfin-User-Id:- User Unique ID (UUID)
- Jellyfin's documentation: users
X-Emby-Token:- API key
Check Seerr connection
/JellyfinEnhanced/jellyseerr/status
- Jellyfin Server API key (
JELLYFIN_API_KEY) - Jellyfin Server User ID (
JELLYFIN_USER_ID) - Jellyfin Server URL (
JELLYFIN_URL)
Using Seerr configuration:
- URL(s)
- API keys
Check if user X-Jellyfin-User-Id has a successfully linked Seerr account
/JellyfinEnhanced/jellyseerr/user-status
- Jellyfin Server API key
X-Emby-Token(JELLYFIN_API_KEY) - Jellyfin Server User ID
X-Jellyfin-User-Id(JELLYFIN_USER_ID) - Jellyfin Server URL (
JELLYFIN_URL)
Example:
curl -X POST \
-H "X-Emby-Token: <API_KEY>" \
-H "X-Jellyfin-User-Id: <USER_ID>" \
-H "Content-Type: application/json" \
-d '{"mediaType": "movie", "mediaId": 27205}' \
"<JELLYFIN_URL>/JellyfinEnhanced/jellyseerr/request"
Admin Hidden Content API
Admin-only endpoints that let an administrator view and manage what other users have hidden. Every endpoint requires a Jellyfin administrator token and the Let admins view and manage other users' hidden content toggle (Pages → Hidden Content → Admin Controls) to be enabled; otherwise it returns 403. <USER_ID> is the 32-character hex ("N" format) Jellyfin user id.
List Users With Hidden Content
Returns each user (except the caller) who has hidden at least one item, with their hidden-item count, used to populate the admin user-filter dropdown.
curl -X GET \
-H "X-Emby-Token: <ADMIN_API_KEY>" \
"<JELLYFIN_URL>/JellyfinEnhanced/admin/hidden-content-users"
Get A User's Hidden Content
Returns a single user's hidden content (read-only).
curl -X GET \
-H "X-Emby-Token: <ADMIN_API_KEY>" \
"<JELLYFIN_URL>/JellyfinEnhanced/admin/hidden-content/<USER_ID>"
Unhide Items For A User
Removes one or more items from a user's hidden list. The body is a JSON array of item keys (an itemId, or tmdb-<id> for items not in the library).
curl -X POST \
-H "X-Emby-Token: <ADMIN_API_KEY>" \
-H "Content-Type: application/json" \
-d '["a1b2c3d4e5f6...", "tmdb-27205"]' \
"<JELLYFIN_URL>/JellyfinEnhanced/admin/hidden-content/<USER_ID>/unhide"
Hide Items For A User
Adds one or more items to a user's hidden list (max 200 per call; an item the user hid themselves is never overwritten). The body is a JSON array of hidden-content items.
curl -X POST \
-H "X-Emby-Token: <ADMIN_API_KEY>" \
-H "Content-Type: application/json" \
-d '[{"TmdbId": "27205", "Name": "Inception", "Type": "Movie", "PosterPath": "/edv5CZvWj09upOsy2Y6IwDhK8bt.jpg"}]' \
"<JELLYFIN_URL>/JellyfinEnhanced/admin/hidden-content/<USER_ID>/hide"
Full Endpoint Index
The sections above document Bookmarks, Reviews, Seerr, and Admin Hidden Content in full (auth, request/response shapes, edge cases). Everything else this plugin exposes is listed here as a map, method + path + a one-line purpose, so a client author knows what exists before reading Controllers/JellyfinEnhancedController.cs for the exact request/response shape. All paths are relative to /JellyfinEnhanced/. [Authorize] means any authenticated Jellyfin user or API key; admin-only endpoints are noted individually.
Not fully documented yet
This index is deliberately terse. If you're building against one of these and need the exact request/response shape, the fastest source of truth is the corresponding controller method (grep the path string in JellyfinEnhancedController.cs) - contributions expanding any of these into full sections like the ones above are welcome.
Seerr Discovery & Requests
| Method | Path | Purpose |
|---|---|---|
| GET | jellyseerr/status |
Seerr connection/reachability check |
| GET | jellyseerr/validate |
Validate configured Seerr URL(s) + API key |
| POST | jellyseerr/trigger-recently-added-scan |
Kick off a Seerr library scan |
| GET | jellyseerr/user-status |
Is the calling Jellyfin user linked to a Seerr account |
| GET | jellyseerr/permission-audit |
Admin: audit every Jellyfin user's Seerr permission bits |
| GET | jellyseerr/search |
Proxy a Seerr search query |
| GET | jellyseerr/sonarr / jellyseerr/radarr |
List Sonarr/Radarr instances known to Seerr (read-only profile/folder discovery, no credentials) |
| GET | jellyseerr/{type}/{serverId} |
Sonarr/Radarr server details by Seerr service id |
| GET | jellyseerr/settings/{type} |
Admin-only: Seerr's own Radarr/Sonarr instance connection settings (hostname, port, apiKey, externalUrl, ...). Backs the *arr tab's "Import from Seerr" button; not the same endpoint as jellyseerr/sonarr/jellyseerr/radarr above |
| GET | jellyfin-urls |
Admin-only: Jellyfin's own detected internal LAN URL and "Published server URIs" external/all override from Dashboard → Networking → Advanced, if configured. Backs the Seerr-import URL Mapping pre-fill |
| POST / GET | jellyseerr/request |
Create / list Seerr requests |
| GET | jellyseerr/quota |
Calling user's Seerr request quota |
| GET | jellyseerr/tv/{tmdbId}, jellyseerr/movie/{tmdbId} |
TV/movie detail proxy |
| GET | .../season/{seasonNumber} |
Season detail proxy |
| GET | .../similar, .../recommendations |
Similar / recommended titles |
| GET | jellyseerr/movie/{tmdbId}/ratingscombined, jellyseerr/tv/{tmdbId}/ratings |
Combined critic/audience ratings |
| GET | jellyseerr/discover/movies, jellyseerr/discover/tv |
Discovery feed |
| GET | .../upcoming |
Upcoming releases |
| GET | .../trending |
Trending feed |
| GET | .../network/{networkId}, .../studio/{studioId} |
Discovery filtered by network/studio |
| GET | .../genre/{genreId}, .../keyword/{keywordId} |
Discovery filtered by genre/keyword |
| GET | jellyseerr/discover/genreslider/movie, .../tv |
Genre-slider rows for the discovery UI |
| GET | jellyseerr/person/{personId} |
Person detail proxy |
| GET | jellyseerr/person/{personId}/combined_credits |
Person's filmography |
| GET | jellyseerr/collection/{collectionId} |
Collection detail proxy |
| GET | jellyseerr/overrideRule |
Seerr auto-approval override rules |
| GET | jellyseerr/user |
Calling user's Seerr profile |
| POST | jellyseerr/request/tv/{tmdbId}/seasons |
Request specific seasons of a show |
| GET | jellyseerr/watchlist |
Calling user's Seerr watchlist |
| POST | jellyseerr/sync-watchlist |
Trigger a watchlist sync |
| POST | jellyseerr/import-users |
Admin: import Jellyfin users into Seerr |
| GET | jellyseerr/settings/partial-requests |
Whether Seerr allows partial season requests |
| GET | jellyseerr/issue, jellyseerr/issue/{id} |
List / get Seerr issues |
| POST | jellyseerr/issue |
File a Seerr issue |
TMDB Proxy & Metadata
| Method | Path | Purpose |
|---|---|---|
| GET | studio/{studioId} |
Studio metadata (non-Seerr TMDB proxy) |
| GET | boxset/{boxsetId} |
Collection/boxset metadata |
| GET | person/{personId} |
Person metadata |
| GET | genre/{genreId} |
Genre metadata |
| GET | tmdb/search/person, tmdb/search/keyword |
TMDB search proxy |
| GET | tmdb/genres/movie, tmdb/genres/tv |
TMDB genre lists |
| GET | tmdb/validate |
Validate the configured TMDB API key |
| GET | tmdb/{**apiPath} |
Generic pass-through TMDB proxy (catch-all) |
Client Bootstrap & Config
| Method | Path | Purpose |
|---|---|---|
| GET | script |
The injected client <script> bundle |
| GET | js/{**path} |
Individual JS module files |
| GET | Configuration/configPage.css |
Admin config page stylesheet |
| GET | version |
Plugin version |
| GET | private-config |
Admin-only: full plugin config |
| GET | public-config |
Curated, non-sensitive config subset the client script reads |
| GET | locales, locales/{lang}.json |
Available languages / one language's translation bundle |
| GET | cdn/{source}/{**path} |
Local mirror of third-party static assets (icons, fonts, logos) |
Per-User Settings Files
Same user-settings/{userId}/{file} pattern as Bookmarks (see above) for every other per-user JSON store:
| Method | Path | Purpose |
|---|---|---|
| GET / POST | user-settings/{userId}/settings.json |
Enhanced panel settings |
| GET / POST | user-settings/{userId}/shortcuts.json |
Keyboard shortcut overrides |
| GET / POST | user-settings/{userId}/elsewhere.json |
Elsewhere (streaming provider) preferences |
| GET / POST | user-settings/{userId}/hidden-content.json |
Hidden Content list |
| GET / POST | user-settings/{userId}/spoilerblur.json |
Spoiler Guard per-user state |
Spoiler Guard
| Method | Path | Purpose |
|---|---|---|
| GET | spoiler-blur/health |
Diagnostic: blur filter health |
| DELETE | spoiler-blur/health/{targetUserId} |
Reset a user's blur-health state |
| GET | spoiler-blur/series |
Series currently under Spoiler Guard |
| GET / POST | spoiler-blur/user-prefs |
Per-user Spoiler Guard preferences |
| POST / DELETE | spoiler-blur/series/{seriesId} |
Enable/disable Spoiler Guard for a series |
| POST / DELETE | spoiler-blur/movies/{movieId} |
Enable/disable for a movie |
| POST / DELETE | spoiler-blur/collections/{collectionId} |
Enable/disable for a collection |
| POST / DELETE | spoiler-blur/pending/{mediaType}/{tmdbId} |
Pre-arm Spoiler Guard for a title not yet in the library |
Continue Watching / Next Up
| Method | Path | Purpose |
|---|---|---|
| POST / DELETE | continue-watching/hide/{itemId} |
Hide/unhide an item from Continue Watching |
| POST / DELETE | next-up/hide/{itemId} |
Hide/unhide an item from Next Up |
Tags, Cache & Watch Data
| Method | Path | Purpose |
|---|---|---|
| POST | tag-cache/rebuild |
Admin: force a full tag-cache rebuild |
| GET | tag-cache/{userId} |
This user's tag cache |
| POST | tag-data/{userId} |
Batch tag lookup by item ids |
| GET | file-size/{userId}/{itemId} |
File size for an item |
| GET | watch-progress/{userId}/{itemId} |
Watch progress for an item |
| GET | awards/{mediaType}/{tmdbId} |
Wikidata award wins/nominations |
| GET | mdblist-ratings/{mediaType}/{tmdbId} |
MDBList ratings for a title |
| GET | mdblist-ratings/account-status |
MDBList account quota/status |
Activity Feed & What's New
| Method | Path | Purpose |
|---|---|---|
| GET | activity |
The Activity Feed (recently watched/favorited/reviewed) |
| GET | whats-new |
Admin: pending "What's New" settings for the config page |
| POST | whats-new/dismiss |
Admin: acknowledge the current "What's New" state |
Branding
| Method | Path | Purpose |
|---|---|---|
| POST | UploadBrandingImage |
Admin: upload a custom logo/banner/favicon |
| GET | BrandingImage |
Serve a custom branding image |
| POST | DeleteBrandingImage |
Admin: remove a custom branding image |
*arr (Sonarr/Radarr/Bazarr)
| Method | Path | Purpose |
|---|---|---|
| GET | arr/validate/sonarr, arr/validate/radarr |
Validate an instance's URL/API key |
| GET | arr/identify-url |
Resolve which configured instance owns a given item |
| GET | arr/series-slug, arr/series-slugs |
Sonarr URL slug lookup, single/batch |
| GET | arr/movie-instances |
Which Radarr instance(s) a movie belongs to |
| GET | arr/queue |
Sonarr/Radarr download queue |
| GET | arr/history |
Sonarr/Radarr import history |
| GET | arr/requests |
Requests page data (Seerr + arr queue merged) |
| POST | arr/requests/{requestId}/approve, .../decline |
Admin: approve/decline a Seerr request |
| GET | arr/calendar |
Calendar page data |
| POST | arr/calendar/user-data |
Per-user calendar preferences (favorites/watched highlighting) |
Active Streams & Proxy
| Method | Path | Purpose |
|---|---|---|
| GET | active-streams/sessions |
Currently active playback sessions |
| POST | active-streams/broadcast |
Admin: broadcast a message to active sessions |
| GET | proxy/avatar |
Cached avatar image proxy |
| GET | items/by-providers |
Look up Jellyfin items by external provider id |
Maintenance Mode
All admin-only.
| Method | Path | Purpose |
|---|---|---|
| GET | MaintenanceMode/Status |
Current maintenance-mode state |
| POST | MaintenanceMode/Enable |
Enable maintenance mode |
| POST | MaintenanceMode/Disable |
Disable maintenance mode |
| GET | MaintenanceMode/Users |
Users affected by the current maintenance-mode config |
| POST | MaintenanceMode/Broadcast |
Send the maintenance notification immediately |
Misc
| Method | Path | Purpose |
|---|---|---|
| POST | reset-all-users-settings |
Admin: overwrite every user's settings with the current defaults |
| GET | {viewName} |
Catch-all: serves a Plugin Pages HTML view by name |