Jellyfin AI Upscalerv1.6.1.16

REST API reference

Two API surfaces: the plugin controller (proxied behind Jellyfin auth at /Upscaler/*) and the AI service (direct, :5000).

Auth

Plugin controller endpoints (/Upscaler/*)

MethodPathPurpose
GET/Upscaler/healthProxies AI service /health; returns online/offline + auth posture.
GET/Upscaler/librariesEnumerates Jellyfin virtual folders (ID, name, collectionType, paths). Used by the Select-Libraries chip picker.
GET/Upscaler/modelsModel catalog proxied from service, merged with per-user preference marks.
POST/Upscaler/models/{id}/loadWarms the model in GPU memory via service. Admin only.
POST/Upscaler/models/{id}/downloadPulls ONNX weights. Admin only.
GET/Upscaler/jobsActive jobs list. Admin only — previously leaked paths to any authenticated user, fixed in v1.6.1.11.
POST/Upscaler/upscale-frameBase64-encoded frame in, upscaled frame out. Uses currently-loaded model.
POST/Upscaler/benchmark-frameSingle-frame benchmark pass; returns ms + provider used.
GET/Upscaler/filter-preview/frame/{itemId}Extracts a real frame from a Jellyfin library item, applies the selected preset, returns before/after PNGs.
POST/Upscaler/filter-configPersists the 6 advanced filter params (gamma/sharpness/temp/vignette/grain/denoise).
GET/Upscaler/recommend-modelGiven an item ID, returns the best model + filter preset based on genre. Used by Auto-Mode.
POST/Upscaler/wrapper/installGenerates the FFmpeg-wrapper script for remote transcoding. Admin only.

AI service endpoints (:5000)

System

MethodPathPurpose
GET/healthBasic liveness — returns 200 once the FastAPI app is up.
GET/statusDetailed: service version, provider, api_token_configured, auth_enabled.
GET/featuresFeature capability matrix (face-restore, rife, tensorrt, etc).
GET/metricsPrometheus-compatible — per-model latency, queue depth, VRAM, request counts.
GET/openapi.jsonFull OpenAPI 3.1 schema. Feed it to any generator.
GET/logs-streamServer-Sent Events stream of service logs. Powers the in-UI Console tab.

Hardware

GET/hardwareProviders with version strings, ONNX runtime version, build flags.
GET/gpusPer-GPU: name, VRAM total/free, driver, compute capability.
POST/benchmark/runTriggers a full benchmark sweep across all loaded models; async, poll /benchmark/status.

Models

GET/modelsFull catalog with per-model state.
GET/models/{id}Single model details — scale, input shape, provider compat, SHA.
POST/models/{id}/downloadFetch ONNX weights. Streams progress via /models/{id}/progress.
POST/models/{id}/loadCreate inference session, preallocate tensors, optional TensorRT conversion.
POST/models/{id}/unloadDispose session, free VRAM.

Inference

POST/upscale-frameSingle-frame inference. Body: { image, model, scale }.
POST/upscale-batchMulti-frame batched inference; better throughput than per-frame.
POST/face-restore/detectReturns face bounding boxes (Haar cascade).
POST/face-restore/restoreApplies GFPGAN or CodeFormer to a face crop.
POST/face-restore/pipelineEnd-to-end: detect → upscale → feathered paste-back.

Example: load a model + upscale a frame

TOKEN=your-api-token
BASE=http://localhost:5000

# 1. Load model
curl -X POST -H "X-Api-Token: $TOKEN" $BASE/models/realesrgan-x4plus/load

# 2. Upscale a PNG (base64 in, base64 out)
IMG=$(base64 -w 0 input.png)
curl -X POST -H "X-Api-Token: $TOKEN" -H "Content-Type: application/json" \
  -d "{\"image\":\"$IMG\",\"model\":\"realesrgan-x4plus\",\"scale\":4}" \
  $BASE/upscale-frame | jq -r .image | base64 -d > output.png

Rate limiting & concurrency

The service has a single GPU serialiser — concurrent /upscale-frame requests queue behind one active inference. The MaxConcurrentStreams plugin config gates how many requests the plugin will have in-flight at once; tune this based on VRAM headroom.

ID validation regex

Model IDs and filter preset IDs are validated against ^[a-zA-Z0-9_-]+(?:\.[a-zA-Z0-9_-]+)*$ — dot-separated segments are allowed (for rife-v4.9 etc) but traversal patterns (.., leading/trailing dots) are blocked.