REST API reference
Two API surfaces: the plugin controller (proxied behind Jellyfin auth at /Upscaler/*) and the AI service (direct, :5000).
Auth
- Plugin controller: Jellyfin's standard
X-Emby-Tokenaccess-token header. Elevated endpoints additionally require admin role (RequiresElevation). - AI service: shared-secret
X-Api-Tokenheader whenAPI_TOKENenv var is set on the container. Plain HTTP with no token if unset (homelab-friendly default).
Plugin controller endpoints (/Upscaler/*)
| Method | Path | Purpose |
|---|---|---|
GET | /Upscaler/health | Proxies AI service /health; returns online/offline + auth posture. |
GET | /Upscaler/libraries | Enumerates Jellyfin virtual folders (ID, name, collectionType, paths). Used by the Select-Libraries chip picker. |
GET | /Upscaler/models | Model catalog proxied from service, merged with per-user preference marks. |
POST | /Upscaler/models/{id}/load | Warms the model in GPU memory via service. Admin only. |
POST | /Upscaler/models/{id}/download | Pulls ONNX weights. Admin only. |
GET | /Upscaler/jobs | Active jobs list. Admin only — previously leaked paths to any authenticated user, fixed in v1.6.1.11. |
POST | /Upscaler/upscale-frame | Base64-encoded frame in, upscaled frame out. Uses currently-loaded model. |
POST | /Upscaler/benchmark-frame | Single-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-config | Persists the 6 advanced filter params (gamma/sharpness/temp/vignette/grain/denoise). |
GET | /Upscaler/recommend-model | Given an item ID, returns the best model + filter preset based on genre. Used by Auto-Mode. |
POST | /Upscaler/wrapper/install | Generates the FFmpeg-wrapper script for remote transcoding. Admin only. |
AI service endpoints (:5000)
System
| Method | Path | Purpose |
|---|---|---|
GET | /health | Basic liveness — returns 200 once the FastAPI app is up. |
GET | /status | Detailed: service version, provider, api_token_configured, auth_enabled. |
GET | /features | Feature capability matrix (face-restore, rife, tensorrt, etc). |
GET | /metrics | Prometheus-compatible — per-model latency, queue depth, VRAM, request counts. |
GET | /openapi.json | Full OpenAPI 3.1 schema. Feed it to any generator. |
GET | /logs-stream | Server-Sent Events stream of service logs. Powers the in-UI Console tab. |
Hardware
GET | /hardware | Providers with version strings, ONNX runtime version, build flags. |
GET | /gpus | Per-GPU: name, VRAM total/free, driver, compute capability. |
POST | /benchmark/run | Triggers a full benchmark sweep across all loaded models; async, poll /benchmark/status. |
Models
GET | /models | Full catalog with per-model state. |
GET | /models/{id} | Single model details — scale, input shape, provider compat, SHA. |
POST | /models/{id}/download | Fetch ONNX weights. Streams progress via /models/{id}/progress. |
POST | /models/{id}/load | Create inference session, preallocate tensors, optional TensorRT conversion. |
POST | /models/{id}/unload | Dispose session, free VRAM. |
Inference
POST | /upscale-frame | Single-frame inference. Body: { image, model, scale }. |
POST | /upscale-batch | Multi-frame batched inference; better throughput than per-frame. |
POST | /face-restore/detect | Returns face bounding boxes (Haar cascade). |
POST | /face-restore/restore | Applies GFPGAN or CodeFormer to a face crop. |
POST | /face-restore/pipeline | End-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.