Skip to content

API Reference

Domekologe edited this page Aug 1, 2026 · 7 revisions

API Reference

🌐 English · Deutsch

There are two API layers:

  1. External REST API (/api/v1/...) — for scripts, dashboards (e.g. Homepage/Homarr) and third-party systems. Authenticated via API key, no login needed.
  2. Internal API (/api/...) — used by the WebUI, session-based (login required, partly admin). It is not a stable contract, but the most important endpoints are documented below anyway.

External API v1

Authentication

Send the API key in the X-Api-Key header. The key is generated automatically on first start and can be viewed (and regenerated) under Settings → API.

curl -H "X-Api-Key: <key>" http://localhost:8080/api/v1/status

Missing/wrong key → 401 Unauthorized.

Endpoints

Method Path Description
GET /api/v1/status Overall status: version, pause state, queue counters by status, currently running download incl. live progress (episode_progress: percent, phase, speed, bandwidth; overall_progress_percent)
GET /api/v1/queue All queue entries; filter: `?status=queued
GET /api/v1/queue/<id> Single queue entry (404 if unknown)
GET /api/v1/library Full library (all paths, titles, seasons, episodes, sizes)
GET /api/v1/library/series Series only
GET /api/v1/library/movies Movies only
GET /api/v1/stats Overall download statistics
GET /api/v1/autosync Auto-Sync jobs — every job of every user (the internal /api/autosync is filtered to the caller)
GET /api/v1/history Download history — every user; filters: ?status=, ?limit=, ?offset=
GET /api/v1/upscale Upscale queue: items, badge count and the running job's progress
GET /api/v1/mediascan MediaScan (Plex/Jellyfin import): run status and cached title count
GET /api/v1/uptime UpTime monitor: current status, uptime % and average response time per tracked source
GET /api/v1/update-status Self-update: progress of a running update, or the idle state

Example: status

{
  "version": "2.5.3",
  "paused": false,
  "queue": {"total": 12, "queued": 2, "running": 1, "completed": 8, "failed": 1, "cancelled": 0},
  "currently_running": {
    "id": 42, "title": "", "current_episode": 3, "total_episodes": 12,
    "episode_progress": {"percent": 57, "phase": "download", "speed": "2.1x", "bandwidth": "8.4 MB/s", "active": true},
    "overall_progress_percent": 29
  }
}

Internal API (selection)

All internal endpoints require a logged-in session; POST/PUT/DELETE require Content-Type: application/json. Entries marked (admin) additionally require the admin role.

Search & browse

Method Path Description
POST /api/search `{keyword, site: "aniworld"
GET /api/series / /api/seasons / /api/episodes Series/season/episode data for a URL
GET /api/providers Available hosts/languages of an episode
GET /api/new-animes, /api/popular-animes, /api/new-series, /api/popular-series, /api/new-movies, /api/random Browse lists
GET /api/home-feed?adult=0|1&limit=30 The whole new home page in one answer: rows (new/popular/movies, deduplicated across all three), the source list with its enabled/error state, and which sources failed upstream. Includes sources registered by modules.
GET /api/home-feed/personal The personal home rows for the current user: continue, watchlist, library, upcoming. Every one degrades to an empty list instead of an error.
GET /api/home-panels The home page's button bar: one entry per panel the current account may see, each with a count badge. Admin-only panels are omitted for non-admins. Includes panels registered by modules.
GET /api/home-panel/<id> The body of one panel (stats, list, link). 403 for an admin-only panel, 404 for an unknown one; a panel that fails answers 200 with error: true.
GET /api/home-feed/sources Every source the feed knows (built-in + module-registered) and the effective row layout, without fetching anything. Feeds the Start Page settings.
GET /api/home-feed/row/<row>?adult=0|1&limit=30 One discovery row (new, popular, movies) on its own. What the home page actually uses: one slow source can no longer hold up the whole page, and rows below the fold are only fetched once they are scrolled to. Cross-row deduplication moves to the client.
GET /api/mediaplayer/users The configured Jellyfin/Plex server's user list, for the profile picker. Names only. {configured, server, users, linked}.
GET /api/mediaplayer/image?path=… Artwork proxy for the media server, so the browser never needs its address or token. Server-relative paths only.
GET /api/home/wrapped?period=YYYY-MM The monthly recap card: watched (from the linked Jellyfin/Plex user, absent when none is linked) and downloaded (always MediaForge's own history).
GET /api/home/onboarding What this instance still needs (sources, TMDB key, library scan, modules, media-server link). Admin-only steps are omitted for a normal account.
GET /api/home/suggest?q=… Instant search suggestions, grouped into library and watchlist. Local lookups only — no provider scrape per keystroke.
POST /api/home/mode Switch the active home mode: {mode, max_fsk, pin}. Lowering the age ceiling is always allowed; raising it needs the kids-mode PIN when one is set. The ceiling itself is enforced server-side in the feed, never in the browser.

Queue

Method Path Description
POST /api/download Create a download job
GET /api/queue Queue incl. progress
POST /api/queue/pause / /api/queue/resume Global pause
POST /api/queue/<id>/cancel / restart / skip-episode / retry-episode / move Actions
DELETE /api/queue/<id> / /api/queue/completed Delete an entry / all finished entries

AutoSync

Method Path Description
GET/POST /api/autosync List / create jobs (create: admin); body incl. language, provider, custom_path_id, episode_filter (JSON), movie_custom_path_id
POST /api/autosync/site-search Resolve a title to candidate series on AniWorld/serienstream.to (used by the Library "Add to Auto-Sync"); body {title}, returns results[] with site, site_label, title, url, score
PUT/DELETE /api/autosync/<id> Update (incl. episode_filter, movie_custom_path_id, group_name) / delete (admin)
POST /api/autosync/<id>/sync, /api/autosync/sync-all Sync immediately
GET/POST /api/autosync/export, /api/autosync/import, /api/autosync/batch Backup / restore / bulk add. batch actions: enable, disable, set_path, set_group (+group_name), remove_group, delete
POST /api/autosync/group/rename Rename a group; body {old, new} — sets group_name of all own jobs (admin: all) from old to new

Calendar & download history

Method Path Description
GET /api/calendar Aggregated calendar events for the user (AutoSync + optional Seerr/Library overlays). Returns events[], a watcher status block (active, is_scanning, last_sync) and meta (seerr_active, seerr_count). Requires the calendar to be enabled + a TMDB key.
GET /api/history Download history; query: ?search=, ?status=all|completed|failed|cancelled|skipped, ?source=all|manual|autosync|seerr, ?range=all|1d|7d|30d, ?limit= (max 200), ?offset=. Users see their own entries, admins all. Returns entries[] + total.
GET /api/history/<id> Single history entry (403 if not yours and not admin)
GET /api/history/export Export the filtered view; ?format=csv|json plus the same filters as /api/history
POST /api/history/<id>/retry Re-queue a failed/cancelled episode
DELETE /api/history/<id> Delete a single entry
POST /api/history/delete Delete multiple entries (body {ids: [...]})
POST /api/history/clear Clear the history; body may include status/source/range/search to delete only the filtered subset (otherwise all; own entries, admins all)

Settings (admin)

Method Path Description
GET/PUT /api/settings General settings
GET/PUT /api/settings/sso, /api/settings/cineinfo, /api/settings/mediaplayer, /api/settings/mediascan, /api/settings/seerr, /api/settings/crunchyroll, /api/settings/dns Sub-areas
GET/POST /api/settings/api-key, /api/settings/api-key/regenerate External API key
GET/POST /api/encoding/settings, /api/encoding/detect-hw Encoding
GET/POST /api/upscale/settings, … Upscaling (reading settings is allowed for everyone)

Crunchyroll

Method Path Description
GET/PUT /api/settings/crunchyroll Load/save settings (password is write-only; clear_password: true forgets it)
POST /api/settings/crunchyroll/test Validate login → {ok, mode, profile, premium}
GET /api/settings/crunchyroll/profiles List account profiles for the selector
GET /api/crunchyroll/availability?title=… Whether a title is on Crunchyroll (powers the provider pill; cached 24 h)

Backed by web/crunchyroll_service.py — a thread-safe client cache (6 h re-login TTL, encrypted session-token file, failure-tolerant) on top of the vendored vendor/crunchyroll_api.py client. Anonymous mode needs no account; watchlist/profile and premium checks require a login. The calendar uses get_simulcast_titles() / get_watchlist_titles() (Crunchyroll knows which anime; TMDB supplies the air dates). Video streams are DRM-protected and never downloaded.

Library & player

Method Path Description
GET /api/library / /api/library/status / /api/library/watcher Inventory & scan status
POST /api/library/refresh (admin), /api/library/delete (admin), /api/library/rename (admin), /api/library/move (admin), /api/library/media_info Management
POST /api/stream/start / /api/stream/stop Start/stop an HLS transcode session (library files)
GET /api/stream/<token>/index.m3u8, /api/stream/<token>/segNNN.ts, /api/stream/<token>/status HLS delivery
POST /api/stream/start-source Stream an episode directly from the provider via transcode; body {episode_url, provider, language, start_pos}
POST /api/stream/start-proxy / /api/stream/close-proxy Start/stop a passthrough proxy session for the provider's native HLS (no FFmpeg); returns {token, playlist_url, hls}
GET /api/proxy/<token>/r/<b64url> Proxy a provider playlist (rewritten) or segment/key (streamed); forwards Range. SSRF-guarded (http/https only, private/loopback hosts blocked)
POST/GET /api/progress/save, /api/progress/get, /api/progress/bulk Watch progress (per user)

Syncplay & Web Console

Method Path Description
GET /api/syncplay/config Whether a Syncplay server is configured
POST /api/syncplay/join / /api/syncplay/leave Join/leave a room (server opens a real Syncplay client); body {room, username?}
POST /api/syncplay/control / /api/syncplay/report Send play/pause/seek; report current position (heartbeat)
GET /api/syncplay/poll Poll authoritative state events + room user list (?session_id=&after=)
GET /api/console (admin) Read-only live console output buffer; ?after=<seq> for incremental polling (only when the Web Console is enabled)

Miscellaneous

Method Path Description
GET /api/captcha/<queue_id>/screenshot / status; POST /api/captcha/<queue_id>/click Interactive captcha solving
GET/POST /api/notif/settings, /api/notif/user-settings, /api/notif/admin-settings, /api/notif/test Notifications
GET /api/seerr/requests; POST …/approve, …/decline, …/hide Seerr requests
GET/POST /api/update-check Update check
GET/POST/DELETE /api/favourites Favourites
GET/POST /api/user/preferences Per-account appearance (theme_pack, theme_mode, accent) — keys whitelisted server-side, extendable by modules via db.register_ui_pref_key()
GET /api/themes; PUT /api/themes/active (admin) Installed theme packs / instance default
GET /api/stats Statistics — accepts ?days= (1–365, default 30) for the trend series
GET /api/stats/trends Chart series only for a given ?days= window (no library scan)
GET /api/media/duplicates One page of duplicate groups: ?page=&per_page= (1–100, default 20) &q= + an aggregate summary
GET /api/history/summary Aggregate figures + 30-day series for the active history filters
GET /api/history/facets Providers and languages present in the history, for the filter dropdowns
GET /api/media/incomplete One page of incomplete or ignored series: ?view=incomplete|ignored&page=&per_page=&q=
GET /api/stats/queue, /api/stats/sync, /api/stats/general Individual statistics sections

Clone this wiki locally