Complete REST API documentation for the Catalogizer backend (catalog-api). All endpoints are served under the base URL http://localhost:8080.
Total registered endpoints: 208
- Overview
- Health and Infrastructure
- Service Discovery
- WebSocket
- Image Proxy
- Cover Art (Public)
- Assets (Public)
- Authentication
- Catalog Browsing
- Search
- Download
- Streaming
- File Copy Operations
- Media Browsing
- Media Operations
- Recommendations
- Subtitles
- Storage and Storage Roots
- Statistics
- SMB Discovery
- Scanning
- Conversion
- Admin
- User Management
- Role Management
- Configuration
- Error Reporting
- Log Management
- Collections
- Assets (Authenticated)
- Media Entities
- Analytics
- Reports
- Favorites
- Playlists
- Browse
- Sync
- Challenges
- Global Middleware
- Error Handling
- Rate Limiting
| Property | Value |
|---|---|
| Base URL | http://localhost:8080 |
| HTTPS URL | https://localhost:8443 (HTTP/2 + HTTP/3 QUIC) |
| API Version | v1 |
| Auth Method | JWT Bearer Token |
| Content Type | application/json |
| Compression | Brotli (primary), gzip (fallback) |
| Database | SQLite (dev) / PostgreSQL (prod) |
All API routes under /api/v1/* (except auth endpoints, public assets, covers, and discovery) require a valid JWT token in the Authorization header:
Authorization: Bearer <jwt_token>
Simple health check endpoint. No authentication required. Cached for 5 seconds.
Description: Returns basic service health status with version info. Auth: None Rate Limit: None
Response: 200 OK
{
"status": "healthy",
"time": "2024-01-20T12:00:00Z",
"version": "2.1.0",
"build_number": "16",
"build_date": "2026-03-31"
}Deep health check that pings the database. Times out after 100ms to avoid blocking. Cached for 5 seconds.
Description: Returns component-level health including database connectivity. Auth: None Rate Limit: None
Response: 200 OK
{
"status": "healthy",
"time": "2024-01-20T12:00:00Z",
"version": "2.1.0",
"components": {
"database": {
"status": "healthy",
"latency_ms": 2
}
}
}Response: 200 OK (degraded, timeout exceeded)
{
"status": "degraded",
"time": "2024-01-20T12:00:00Z",
"version": "2.1.0",
"message": "health check exceeded 100ms timeout",
"components": {
"timeout": {
"status": "degraded",
"message": "deep health check took too long"
}
}
}Response: 503 Service Unavailable (unhealthy)
Prometheus metrics endpoint. Returns metrics in Prometheus exposition format. No authentication required.
Description: Exposes Prometheus metrics (HTTP request durations, counts, response sizes, goroutines, memory). Auth: None Rate Limit: None
Response: 200 OK (text/plain; Prometheus exposition format)
Service discovery endpoint for LAN clients to find the API. Cached for 60 seconds.
Description: Returns service connection info including WebSocket URL and API base URL. Auth: None Rate Limit: None
Response: 200 OK
{
"service": "catalogizer-api",
"name": "Catalogizer API",
"version": "2.1.0",
"build": "16",
"build_date": "2026-03-31",
"host": "192.168.0.100",
"port": 8080,
"protocol": "http",
"websocket_url": "ws://192.168.0.100:8080/ws",
"api_base_url": "http://192.168.0.100:8080/api/v1",
"capabilities": ["catalog", "media", "streaming", "sync", "websocket", "entities"],
"database": "sqlite",
"instance_id": "catalogizer-1234567890",
"uptime_seconds": 3600
}Alias for /discovery under the API path. Same response. Cached for 60 seconds.
Description: Service discovery under the API prefix. Auth: None Rate Limit: None
Alias for /discovery under the announce path. Same response. Cached for 60 seconds.
Description: Service announcement endpoint. Auth: None Rate Limit: None
WebSocket connection endpoint for real-time updates (scan progress, asset updates, live events).
Description: Upgrades to WebSocket. Auth is via query parameter, not header. Auth: Query parameter token Rate Limit: None
Connection:
ws://localhost:8080/ws?token=<jwt_token>
Message Types (server-to-client):
{
"type": "asset_update",
"action": "asset_ready",
"asset_id": "abc123",
"asset_type": "cover",
"entity_type": "movie",
"entity_id": "42"
}Proxy external images (TMDB, OMDB, IGDB CDNs) through the API for devices that cannot reach external CDNs directly.
Description: Fetches and proxies images from allowed CDN domains. Auth: None Rate Limit: None
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
url |
string | Yes | Full URL of the image to proxy |
Allowed Domains: image.tmdb.org, img.omdbapi.com, images.igdb.com
Response: Image binary with original Content-Type. Cached for 24 hours via Cache-Control: public, max-age=86400.
Errors:
| Status | Condition |
|---|---|
| 400 | Missing url parameter |
| 403 | Domain not in allowlist |
| 502 | Failed to fetch image from origin |
Cover image endpoints are public (no auth required).
Serve a placeholder SVG image for a media type. Cached for 24 hours.
Description: Returns an SVG placeholder for the given media type. Auth: None Rate Limit: None
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
type |
string | Media type: movie, tv_show, music_album, game, software, book, comic, etc. |
Response: 200 OK (image/svg+xml)
Get the cover image URL for a media entity. Cached for 5 minutes.
Description: Returns the URL where the cover image can be fetched. Auth: None Rate Limit: None
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
int | Media entity ID |
Response: 200 OK
{
"url": "/api/v1/cover/42",
"source": "tmdb"
}Serve the actual cover image for a media entity. Cached for 24 hours.
Description: Returns the cover image binary data. Auth: None Rate Limit: None
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
int | Media entity ID |
Response: 200 OK (image/jpeg, image/png, or image/svg+xml)
Serve an asset by ID. Static cache headers (immutable, 1 year).
Description: Serves fingerprinted/content-hashed asset files. Auth: None Rate Limit: None
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
string | Asset ID |
Response: 200 OK with Cache-Control: public, max-age=31536000, immutable
Authentication endpoints are under /api/v1/auth. Write operations (login, register) have strict rate limiting (5/min). Read operations use standard rate limiting (100/min).
Authenticate a user and receive JWT tokens.
Description: Validates credentials and returns session + refresh tokens. Auth: None Rate Limit: Strict (5/min)
Request Body:
{
"username": "admin",
"password": "securepassword",
"device_info": {
"device_type": "desktop",
"platform": "linux",
"app_version": "3.0.0"
},
"remember_me": true
}Response: 200 OK
{
"user": {
"id": 1,
"username": "admin",
"email": "admin@example.com",
"role_id": 1,
"role": {
"id": 1,
"name": "admin",
"permissions": ["*"]
},
"is_active": true,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
},
"session_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
"expires_at": "2024-01-02T00:00:00Z"
}Errors: 400 (malformed JSON), 401 (invalid credentials)
Register a new user account.
Description: Creates a new user and returns the user object. Auth: None Rate Limit: Strict (5/min)
Request Body:
{
"username": "newuser",
"email": "newuser@example.com",
"password": "securepassword",
"first_name": "John",
"last_name": "Doe"
}| Field | Type | Required | Validation |
|---|---|---|---|
username |
string | Yes | Unique |
email |
string | Yes | Valid email, unique |
password |
string | Yes | Min 8 characters |
first_name |
string | Yes | - |
last_name |
string | Yes | - |
Response: 201 Created (User object)
Errors: 400 (validation failure), 409 (duplicate username or email)
Refresh an expired access token using a refresh token.
Description: Issues new session and refresh tokens. Auth: None Rate Limit: Standard (100/min)
Request Body:
{
"refresh_token": "eyJhbGciOiJIUzI1NiIs..."
}Response: 200 OK
{
"session_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
"expires_at": "2024-01-02T00:00:00Z"
}Errors: 400 (malformed JSON), 401 (invalid or expired refresh token)
Invalidate the current session token.
Description: Logs out the current session. Auth: None (token optional) Rate Limit: Standard (100/min)
Response: 200 OK
{
"message": "Logged out successfully"
}Get the currently authenticated user's profile.
Description: Returns the user object for the JWT bearer. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK (User object)
Get authentication system status (whether auth is configured, if initial setup is needed).
Description: Returns auth system status without requiring authentication. Auth: None Rate Limit: Standard (100/min)
Response: 200 OK
{
"auth_configured": true,
"users_exist": true,
"registration_enabled": true
}Get the permissions for the current user.
Description: Returns the permission set granted to the authenticated user's role. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"permissions": ["media.view", "media.edit", "media.upload"]
}Alias for /api/v1/auth/me. Returns the current user profile.
Description: Same as GET /api/v1/auth/me. Auth: Required Rate Limit: Standard (100/min)
Get initialization status (whether the system has been set up).
Description: Returns whether the system needs initial configuration. Auth: None Rate Limit: Standard (100/min)
Response: 200 OK
{
"initialized": true,
"has_admin": true,
"has_storage_roots": true,
"has_scanned_files": true
}Change the password for the currently authenticated user.
Description: Updates the user's password after verifying the current password. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"current_password": "oldpassword",
"new_password": "newsecurepassword"
}Response: 200 OK
{
"message": "Password changed successfully"
}Errors: 400 (validation failure), 401 (current password incorrect)
Browse the file catalog across all configured storage roots (SMB, FTP, NFS, WebDAV, local). All endpoints require authentication.
List all available storage root directories.
Description: Returns the list of configured storage root names. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"roots": [
"nas-media",
"nas-backup",
"local-storage"
]
}List files and directories at the specified path.
Description: Browse files and subdirectories within a storage root. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
sort_by |
string | name |
Sort field: name, size, modified |
sort_order |
string | asc |
Sort order: asc, desc |
limit |
int | 100 |
Max results to return |
offset |
int | 0 |
Pagination offset |
Response: 200 OK
{
"files": [
{
"id": 1024,
"storage_root_id": 1,
"storage_root_name": "nas-media",
"path": "movies/The Matrix (1999)",
"name": "The Matrix (1999)",
"size": 4294967296,
"is_directory": true,
"mime_type": null,
"created_at": "2024-01-15T10:30:00Z",
"modified_at": "2024-01-15T10:30:00Z"
}
],
"count": 1,
"limit": 50,
"offset": 0
}Get detailed information about a specific file or directory.
Description: Returns file metadata including size, type, timestamps. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK (FileInfo object)
Errors: 400 (empty path), 404 (path not found)
Search for files and directories using various criteria (catalog-level search).
Description: Full-text search across the file catalog with filtering. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
query |
string | Yes | - | Search term (filename match) |
path |
string | No | - | Path filter |
extension |
string | No | - | File extension filter |
mime_type |
string | No | - | MIME type filter |
min_size |
int | No | - | Minimum file size (bytes) |
max_size |
int | No | - | Maximum file size (bytes) |
smb_roots |
string | No | - | Comma-separated storage root names |
is_directory |
bool | No | - | Filter by directory status |
sort_by |
string | No | name |
Sort field |
sort_order |
string | No | asc |
Sort direction |
limit |
int | No | 100 |
Max results |
offset |
int | No | 0 |
Pagination offset |
Response: 200 OK
{
"files": [...],
"total": 15,
"count": 15,
"limit": 100,
"offset": 0
}Errors: 400 (missing query parameter)
Find groups of duplicate files within a storage root (catalog-level).
Description: Detects duplicate files based on content hashing. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
smb_root |
string | Yes | - | Storage root name to search |
min_count |
int | No | 2 |
Minimum duplicates per group |
limit |
int | No | 50 |
Max groups to return |
Response: 200 OK
{
"groups": [
{
"id": 42,
"file_count": 3,
"total_size": 12884901888,
"created_at": "2024-01-10T08:00:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
],
"count": 1
}Search files in the database (file-level search handler).
Description: Database-level file search with advanced filtering. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
query |
string | Yes | Search term |
storage_root_id |
int | No | Filter by storage root |
extension |
string | No | File extension filter |
min_size |
int | No | Minimum size in bytes |
max_size |
int | No | Maximum size in bytes |
limit |
int | No | Max results |
offset |
int | No | Pagination offset |
Response: 200 OK
{
"files": [...],
"total": 42,
"limit": 100,
"offset": 0
}Find duplicate files via the file-level search handler.
Description: Detects duplicate files using the database search handler. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
storage_root_id |
int | No | Filter by storage root |
min_count |
int | No | Minimum duplicates per group |
limit |
int | No | Max groups |
Response: 200 OK
Advanced multi-criteria search with structured query body.
Description: Accepts a JSON body with complex search criteria. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"query": "matrix",
"filters": {
"extensions": [".mkv", ".mp4"],
"min_size": 1073741824,
"max_size": 10737418240,
"storage_root_ids": [1, 2],
"is_directory": false,
"date_from": "2024-01-01",
"date_to": "2024-12-31"
},
"sort": {
"field": "size",
"order": "desc"
},
"limit": 50,
"offset": 0
}Response: 200 OK
Download a single file by its database ID.
Description: Streams the file binary data for download. Auth: Required Rate Limit: Standard (100/min)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
int | File ID |
Response Headers:
Content-Disposition: attachment; filename="movie.mkv"
Content-Type: application/octet-stream
Content-Length: 4294967296
Errors: 400 (invalid ID, cannot download directory), 404 (file not found)
Download a directory as a compressed archive.
Description: Compresses and streams a directory for download. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
format |
string | zip |
Archive format: zip, tar, tar.gz |
Errors: 400 (unsupported format, directory too large), 404 (not found or empty)
Create and download an archive from multiple specified file paths.
Description: Bundles selected files into an archive for download. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"paths": [
"movies/The Matrix (1999)/The.Matrix.mkv",
"movies/Inception (2010)/Inception.mkv"
],
"format": "zip",
"smb_root": "nas-media"
}| Field | Type | Required | Description |
|---|---|---|---|
paths |
string[] | Yes | Array of file paths to include |
format |
string | No | zip (default), tar, tar.gz |
smb_root |
string | No | Storage root name |
Stream a file from any storage backend (SMB, FTP, NFS, WebDAV, local).
Description: Proxies file data for real-time streaming/playback. Supports range requests. Auth: Required Rate Limit: Standard (100/min)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
int | File ID in the database |
Response Headers:
Content-Type: video/x-matroska
Accept-Ranges: bytes
Content-Length: 4294967296
Errors: 400 (invalid ID), 404 (file not found), 500 (storage backend error)
Copy a file to a storage location.
Description: Copies a file between storage locations. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"source_path": "/tmp/upload/document.pdf",
"dest_path": "/documents/archive/document.pdf",
"storage_id": "local"
}| Field | Type | Required | Description |
|---|---|---|---|
source_path |
string | Yes | Source file path |
dest_path |
string | Yes | Destination file path |
storage_id |
string | Yes | Target storage root ID |
Response: 200 OK
{
"message": "File copied to storage successfully",
"source": "/tmp/upload/document.pdf",
"destination": "/documents/archive/document.pdf",
"storage_id": "local"
}Copy a file from a remote storage (SMB) to local filesystem.
Description: Downloads a file from remote storage to a local path. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"source_path": "nas-media:movies/movie.mkv",
"destination_path": "/local/downloads/movie.mkv",
"overwrite": false
}| Field | Type | Required | Description |
|---|---|---|---|
source_path |
string | Yes | Source in host:path format |
destination_path |
string | Yes | Local destination path |
overwrite |
bool | No | Overwrite existing files (default: false) |
Errors: 400 (invalid source format), 409 (file exists and overwrite=false)
Upload a file from local filesystem to SMB storage.
Description: Uploads a file to remote storage via multipart form data. Auth: Required Rate Limit: Standard (100/min)
Content-Type: multipart/form-data
Form Fields:
| Field | Type | Required | Description |
|---|---|---|---|
file |
file | Yes | File to upload |
destination |
string | Yes | Destination in host:path format |
overwrite |
string | No | "true" to overwrite existing files |
Response: 200 OK
{
"message": "File uploaded successfully",
"filename": "document.pdf",
"destination": "nas-media:documents/document.pdf",
"size": 1048576
}Endpoints for searching and querying media at the database level.
Search media items in the database.
Description: Full-text search across scanned media items. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
query |
string | Yes | Search term |
type |
string | No | Media type filter |
limit |
int | No | Max results |
offset |
int | No | Pagination offset |
Response: 200 OK
{
"results": [...],
"total": 42,
"limit": 100,
"offset": 0
}Get aggregate media statistics.
Description: Returns counts and size totals grouped by media type. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"total_files": 25000,
"total_size": 5497558138880,
"by_type": {
"video": {"count": 5000, "size": 2748779069440},
"audio": {"count": 12000, "size": 549755813888}
}
}Get recently added or accessed media items.
Description: Returns media items sorted by recency. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
int | 20 |
Max results |
type |
string | - | Media type filter |
Response: 200 OK
Get most popular/frequently accessed media items.
Description: Returns media items sorted by popularity/access count. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
int | 20 |
Max results |
type |
string | - | Media type filter |
Response: 200 OK
Look up a media item by its file path.
Description: Resolves a file path to a media entity. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
path |
string | Yes | File or directory path |
Response: 200 OK
Analyze a media file for metadata extraction.
Description: Triggers media analysis pipeline for a specific file. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"path": "/movies/The Matrix (1999)/The.Matrix.mkv",
"storage_root_id": 1
}Response: 200 OK
Get detailed media item information by ID.
Description: Returns full media metadata including external metadata, versions, and user-specific data. Auth: Required Rate Limit: Standard (100/min)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
int | Media item ID |
Response: 200 OK
{
"id": 42,
"title": "The Matrix (1999)",
"media_type": "video",
"year": 1999,
"description": "A computer hacker learns about the true nature of reality.",
"cover_image": "https://image.tmdb.org/t/p/w500/f89U3ADr1oiB1s9GkdPOEpXUk5H.jpg",
"rating": 8.7,
"quality": "1080p",
"file_size": 4294967296,
"duration": 8160,
"directory_path": "/movies/The Matrix (1999)",
"smb_path": "//nas/media/movies/The Matrix (1999)",
"created_at": "2024-01-15 10:30:00",
"updated_at": "2024-01-15 10:30:00",
"external_metadata": [],
"versions": [],
"is_favorite": true,
"watch_progress": 0.75,
"last_watched": "2024-01-20 20:00:00",
"is_downloaded": false
}Errors: 400 (invalid ID), 404 (not found)
Update watch progress for a media item.
Description: Saves the playback position for continue-watching functionality. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"progress": 0.75
}| Field | Type | Required | Validation |
|---|---|---|---|
progress |
float | Yes | 0.0 to 1.0 |
Response: 200 OK
{
"success": true,
"message": "Watch progress updated successfully"
}Update the favorite status for a media item.
Description: Toggles the favorite flag on a media item. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"favorite": true
}Response: 200 OK
{
"success": true,
"message": "Favorite status updated successfully"
}Refresh metadata for a specific media item from external providers.
Description: Re-fetches metadata from TMDB, OMDB, MusicBrainz, etc. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"message": "Metadata refresh initiated"
}Get quality information for a media item (resolution, codec, bitrate).
Description: Returns technical quality details for the media file. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"id": 42,
"resolution": "1920x1080",
"codec": "h264",
"bitrate": 8000000,
"quality_label": "1080p"
}Get media items similar to a given media item.
Description: Uses content-based and collaborative filtering to find similar items. Auth: Required Rate Limit: Standard (100/min)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
media_id |
int | Media item ID |
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
max_local_items |
int | 10 |
Max local results |
max_external_items |
int | 5 |
Max external results |
include_external |
bool | false |
Include external API results |
similarity_threshold |
float | 0.3 |
Minimum similarity score |
Response: 200 OK
{
"media_id": "42",
"local_items": [...],
"external_items": [...],
"total_local": 8,
"total_external": 5
}Get trending media items based on recent activity.
Description: Returns media items trending in a given time window. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
media_type |
string | - | Filter by type: video, audio, etc. |
limit |
int | 20 |
Max results |
time_range |
string | week |
Time range: day, week, month, year |
Response: 200 OK
{
"items": [
{
"id": 100,
"title": "Trending Movie 1",
"media_type": "video",
"rating": 8.2,
"is_favorite": false,
"watch_progress": 0,
"is_downloaded": true
}
],
"media_type": "video",
"time_range": "week",
"generated_at": "2024-01-20T12:00:00Z"
}Get personalized recommendations based on viewing history.
Description: ML-based recommendations tailored to user preferences. Auth: Required Rate Limit: Standard (100/min)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
user_id |
int | User ID |
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
int | 20 |
Max results |
Response: 200 OK
{
"user_id": 1,
"items": [...],
"generated_at": "2024-01-20T12:00:00Z"
}Search for subtitles across multiple providers.
Description: Queries subtitle databases for matching subtitles. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
media_path |
string | Yes | Path to the media file |
title |
string | No | Media title override |
year |
int | No | Release year |
season |
int | No | TV season number |
episode |
int | No | TV episode number |
languages |
string | No | Comma-separated language codes |
providers |
string | No | Comma-separated provider names |
Available Providers: opensubtitles, subdb, yifysubtitles, subscene, addic7ed
Response: 200 OK
{
"success": true,
"results": [
{
"id": "os-12345",
"title": "The Matrix",
"language": "English",
"language_code": "en",
"provider": "opensubtitles",
"format": "srt",
"rating": 9.2,
"download_count": 150000
}
],
"count": 1
}Download a specific subtitle by result ID.
Description: Downloads and saves a subtitle file for a media item. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"media_item_id": 42,
"result_id": "os-12345",
"language": "en"
}Response: 200 OK
{
"success": true,
"track": {
"id": "sub-001",
"language": "English",
"language_code": "en",
"format": "srt",
"is_default": false,
"is_forced": false
}
}Get all subtitle tracks for a media item.
Description: Lists available subtitles associated with a media file. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"success": true,
"subtitles": [
{
"id": "sub-001",
"language": "English",
"language_code": "en",
"format": "srt"
}
],
"media_item_id": 42
}Verify if a subtitle is properly synchronized with its media.
Description: Checks subtitle timing alignment against the media file. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"success": true,
"sync_result": {
"is_synced": true,
"offset_ms": 150,
"confidence": 0.95
}
}Translate a subtitle to another language.
Description: Machine-translates subtitle content between languages. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"subtitle_id": "sub-001",
"source_language": "en",
"target_language": "es"
}Response: 200 OK
{
"success": true,
"translated_track": {
"id": "sub-002",
"language": "Spanish",
"language_code": "es",
"format": "srt"
}
}Upload a subtitle file for a media item.
Description: Uploads a custom subtitle file. Auth: Required Rate Limit: Standard (100/min)
Content-Type: multipart/form-data
Form Fields:
| Field | Type | Required | Description |
|---|---|---|---|
media_item_id |
int | Yes | Media item ID |
language |
string | Yes | Language name (e.g., "English") |
language_code |
string | Yes | ISO 639-1 code (e.g., "en") |
file |
file | Yes | Subtitle file (.srt, .vtt, .ass, .txt) |
Get the list of supported subtitle languages.
Description: Returns all languages available for subtitle operations. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"success": true,
"languages": [
{"code": "en", "name": "English", "native_name": "English"},
{"code": "es", "name": "Spanish", "native_name": "Espanol"},
{"code": "fr", "name": "French", "native_name": "Francais"},
{"code": "de", "name": "German", "native_name": "Deutsch"},
{"code": "ru", "name": "Russian", "native_name": "Russkij"}
],
"count": 19
}Get the list of supported subtitle providers.
Description: Returns available subtitle provider configurations. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"success": true,
"providers": [
{"provider": "opensubtitles", "name": "OpenSubtitles", "description": "Large subtitle database with multiple languages", "supported": true},
{"provider": "subdb", "name": "SubDB", "description": "Hash-based subtitle matching", "supported": true},
{"provider": "yifysubtitles", "name": "YIFY Subtitles", "description": "Subtitles for YIFY movie releases", "supported": true},
{"provider": "subscene", "name": "Subscene", "description": "Community-driven subtitle site", "supported": true},
{"provider": "addic7ed", "name": "Addic7ed", "description": "TV show subtitles with translations", "supported": true}
],
"count": 5
}List files in a storage path.
Description: Browse files within a specific storage backend. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
storage_id |
string | Yes | Storage root ID |
Response: 200 OK
{
"path": "/documents",
"storage_id": "local",
"files": [...]
}Get all available storage root configurations.
Description: Lists configured storage roots (SMB, FTP, NFS, WebDAV, local). Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"roots": [
{
"id": 1,
"name": "Local Storage",
"protocol": "local",
"path": "/data/storage",
"enabled": true
}
]
}Create a new storage root configuration.
Description: Registers a new storage location for scanning. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"name": "NAS Media",
"protocol": "smb",
"host": "192.168.0.241",
"port": 445,
"path": "/media",
"username": "user",
"password": "password",
"domain": "WORKGROUP",
"enabled": true
}Further fields: url (required for webdav), mount_point and options (NFS), allow_empty (default false: a scan that finds nothing fails with empty_root), max_depth. port must be 1-65535.
The accepted protocols are the ones the client factory builds (local, smb, ftp, nfs, webdav and every protocol registered at start-up); the 400 answer lists them.
GET /api/v1/storage/roots returns the url with its password redacted; GET /api/v1/scans[/:job_id] returns reason.
Response: 201 Created
Alias for GET /api/v1/storage/roots. Returns same response.
Description: Alternative path for listing storage roots. Auth: Required Rate Limit: Standard (100/min)
Get the current status of a specific storage root (online/offline, last scan time).
Description: Checks connectivity and returns scan status for a storage root. Auth: Required Rate Limit: Standard (100/min)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
int | Storage root ID |
Response: 200 OK
{
"id": 1,
"name": "NAS Media",
"status": "online",
"last_scan": "2024-01-15T10:00:00Z",
"file_count": 25000,
"total_size": 5497558138880
}All statistics endpoints are cached for 60 seconds.
Get directories sorted by total size.
Description: Returns the largest directories across storage roots. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
smb_root |
string | Yes | - | Storage root name |
limit |
int | No | 50 |
Max results |
Response: 200 OK
{
"directories": [
{
"path": "/movies/4K",
"name": "4K",
"storage_root_name": "nas-media",
"file_count": 150,
"total_size": 1099511627776
}
],
"count": 10
}Get statistics about duplicate files.
Description: Returns aggregate duplicate file counts and wasted space. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
smb_root |
string | No | Storage root name |
Response: 200 OK
{
"duplicate_groups": 42,
"total_duplicates": 125,
"total_wasted_space": 53687091200,
"smb_root": "nas-media"
}Get comprehensive catalog statistics.
Description: Returns total files, directories, sizes, duplicates, and storage root counts. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"success": true,
"data": {
"total_files": 25000,
"total_directories": 3200,
"total_size": 5497558138880,
"total_duplicates": 125,
"duplicate_groups": 42,
"storage_roots_count": 5,
"active_storage_roots": 4,
"last_scan_time": 1705312200
}
}Get statistics for a specific storage root.
Description: Returns file counts, sizes, and scan info for one storage root. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"success": true,
"data": {
"name": "nas-media",
"total_files": 15000,
"total_directories": 2000,
"total_size": 3298534883328,
"duplicate_files": 80,
"duplicate_groups": 25,
"last_scan_time": 1705312200,
"is_online": true
}
}Get file type distribution statistics.
Description: Returns file counts and sizes grouped by extension/type. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
smb_root |
string | - | Storage root filter |
limit |
int | 50 |
Max results (max 1000) |
Response: 200 OK
{
"success": true,
"data": [
{"file_type": "video", "extension": ".mkv", "count": 5000, "total_size": 2748779069440, "average_size": 549755813},
{"file_type": "audio", "extension": ".flac", "count": 12000, "total_size": 549755813888, "average_size": 45812984}
]
}Get file size distribution.
Description: Returns file counts bucketed by size range. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
smb_root |
string | Storage root filter |
Response: 200 OK
{
"success": true,
"data": {
"tiny": 500,
"small": 3000,
"medium": 8000,
"large": 10000,
"huge": 3000,
"massive": 500
}
}Size buckets: tiny (<1KB), small (1KB-1MB), medium (1MB-10MB), large (10MB-100MB), huge (100MB-1GB), massive (>1GB).
Get duplicate file statistics.
Description: Returns aggregate duplicate stats across the catalog. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"success": true,
"data": {
"total_duplicates": 125,
"duplicate_groups": 42,
"wasted_space": 53687091200,
"largest_duplicate_group": 8,
"average_group_size": 2.97
}
}Get the largest duplicate groups.
Description: Lists duplicate file groups sorted by count or size. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
sort_by |
string | count |
count or size |
limit |
int | 20 |
Max results (max 100) |
smb_root |
string | - | Storage root filter |
Get file access pattern statistics.
Description: Analyzes file access patterns over a time period. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
smb_root |
string | - | Storage root filter |
days |
int | 30 |
Analysis period (max 365) |
Get storage growth trends over time.
Description: Returns monthly file and size growth data. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
smb_root |
string | - | Storage root filter |
months |
int | 12 |
Analysis period (max 60) |
Response: 200 OK
{
"success": true,
"data": {
"monthly_growth": [
{"month": "2024-01", "files_added": 500, "size_added": 274877906944, "total_files": 25000, "total_size": 5497558138880}
],
"total_growth_rate": 12.5,
"file_growth_rate": 8.3,
"size_growth_rate": 15.2
}
}Get scan operation history.
Description: Returns historical scan results with pagination. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
smb_root |
string | - | Storage root filter |
limit |
int | 50 |
Max results (max 1000) |
offset |
int | 0 |
Pagination offset |
Response: 200 OK
{
"success": true,
"data": {
"scans": [
{
"id": 23,
"storage_root_id": 1,
"scan_type": "full",
"status": "completed",
"start_time": "2024-01-15T10:00:00Z",
"end_time": "2024-01-15T10:45:00Z",
"files_processed": 25000,
"files_added": 150,
"files_updated": 30,
"files_deleted": 5,
"error_count": 0
}
],
"total_count": 100,
"limit": 50,
"offset": 0
}
}Discover available SMB shares on a host.
Description: Scans an SMB host for available shares. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"host": "192.168.1.100",
"username": "user",
"password": "password",
"domain": "WORKGROUP"
}| Field | Type | Required | Description |
|---|---|---|---|
host |
string | Yes | SMB host address |
username |
string | Yes | Authentication username |
password |
string | Yes | Authentication password |
domain |
string | No | Windows domain |
Response: 200 OK (array of SMBShareInfo objects)
Discover SMB shares using query parameters (convenience endpoint for testing).
Description: Same as POST but with query string parameters. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Required |
|---|---|---|
host |
string | Yes |
username |
string | Yes |
password |
string | Yes |
domain |
string | No |
Test connectivity to an SMB share.
Description: Verifies that the API server can reach and authenticate to an SMB share. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"host": "192.168.1.100",
"port": 445,
"share": "media",
"username": "user",
"password": "password",
"domain": "WORKGROUP"
}Response: 200 OK
{
"success": true,
"host": "192.168.1.100",
"share": "media",
"username": "user",
"connection": true
}Test SMB connection using query parameters.
Description: Same as POST but with query string parameters. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Required | Default |
|---|---|---|---|
host |
string | Yes | - |
share |
string | Yes | - |
username |
string | Yes | - |
password |
string | Yes | - |
domain |
string | No | - |
port |
int | No | 445 |
Browse files and directories in an SMB share.
Description: Lists contents of a remote SMB share directory. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"host": "192.168.1.100",
"port": 445,
"share": "media",
"username": "user",
"password": "password",
"domain": "WORKGROUP",
"path": "movies"
}Response: 200 OK (array of SMBFileEntry objects)
Queue a new scan job for a storage root.
Description: Initiates a file system scan on a configured storage root. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"storage_root_id": 1,
"scan_type": "full"
}| Field | Type | Required | Description |
|---|---|---|---|
storage_root_id |
int | Yes | Storage root to scan |
scan_type |
string | No | full or incremental |
Response: 202 Accepted
{
"job_id": "scan-abc123",
"storage_root_id": 1,
"status": "queued"
}List all scan jobs with their status.
Description: Returns recent and active scan operations. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"scans": [
{
"job_id": "scan-abc123",
"storage_root_id": 1,
"status": "running",
"progress": 0.45,
"files_processed": 11250,
"started_at": "2024-01-15T10:00:00Z"
}
]
}Get the status of a specific scan job.
Description: Returns detailed progress for a scan operation. Auth: Required Rate Limit: Standard (100/min)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
job_id |
string | Scan job ID |
Response: 200 OK
{
"job_id": "scan-abc123",
"storage_root_id": 1,
"status": "completed",
"progress": 1.0,
"files_processed": 25000,
"files_added": 150,
"files_updated": 30,
"files_deleted": 5,
"errors": [],
"started_at": "2024-01-15T10:00:00Z",
"completed_at": "2024-01-15T10:45:00Z"
}Create a new media format conversion job.
Description: Queues a media file for format conversion. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"source_path": "/media/video.mp4",
"target_path": "/media/video.mp3",
"source_format": "mp4",
"target_format": "mp3",
"conversion_type": "audio",
"quality": "high",
"priority": 1,
"settings": "{\"bitrate\": \"320k\"}",
"scheduled_for": "2024-01-20T10:00:00Z"
}Response: 200 OK (ConversionJob object)
List conversion jobs for the current user.
Description: Returns conversion jobs with optional status filtering. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
status |
string | - | Filter: pending, running, completed, failed, cancelled |
limit |
int | 50 |
Max results (max 100) |
offset |
int | 0 |
Pagination offset |
Response: 200 OK (array of ConversionJob objects)
Get a specific conversion job by ID.
Description: Returns full details for a conversion job. Auth: Required Rate Limit: Standard (100/min)
Errors: 400 (invalid ID), 404 (not found)
Cancel a running conversion job.
Description: Cancels an in-progress or queued conversion. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"message": "Job cancelled successfully"
}Delete a conversion job record.
Description: Removes a completed or cancelled conversion job from history. Auth: Required Rate Limit: Standard (100/min)
Response: 204 No Content
Retry a failed conversion job.
Description: Re-queues a previously failed conversion job. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK (ConversionJob object with status reset)
Download the output file of a completed conversion job.
Description: Streams the converted file for download. Auth: Required Rate Limit: Standard (100/min)
Response: Binary file download with appropriate Content-Type.
Errors: 400 (job not completed), 404 (not found)
Get all supported conversion formats.
Description: Lists input and output formats by media type. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"video": {
"input": ["mp4", "mkv", "avi", "mov", "wmv", "flv", "webm"],
"output": ["mp4", "mkv", "avi", "webm"]
},
"audio": {
"input": ["mp3", "flac", "wav", "aac", "ogg", "wma", "m4a"],
"output": ["mp3", "flac", "wav", "aac", "ogg"]
},
"document": {
"input": ["pdf", "doc", "docx", "txt", "rtf"],
"output": ["pdf", "txt"]
},
"image": {
"input": ["jpg", "png", "gif", "bmp", "webp", "tiff"],
"output": ["jpg", "png", "webp"]
}
}Administration endpoints for system management. All require authentication and admin privileges.
Get system information (OS, CPU, memory, disk, Go runtime).
Description: Returns detailed system metrics and runtime info. Auth: Required (admin) Rate Limit: Standard (100/min)
Response: 200 OK
{
"version": "2.1.0",
"build_number": "16",
"os": "linux",
"arch": "amd64",
"go_version": "go1.25",
"goroutines": 42,
"memory_alloc_mb": 128,
"cpu_count": 8,
"uptime_seconds": 86400
}List all users (admin view with additional fields).
Description: Returns user list with admin-level detail. Auth: Required (admin) Rate Limit: Standard (100/min)
Update a user via admin interface.
Description: Admin-level user update (can change role, active status). Auth: Required (admin) Rate Limit: Standard (100/min)
Get storage utilization info across all backends.
Description: Returns disk space usage for all configured storage roots. Auth: Required (admin) Rate Limit: Standard (100/min)
List available backups.
Description: Returns database and configuration backup history. Auth: Required (admin) Rate Limit: Standard (100/min)
Create a new backup.
Description: Triggers a database and/or configuration backup. Auth: Required (admin) Rate Limit: Standard (100/min)
Request Body:
{
"type": "full",
"include_database": true,
"include_config": true
}Restore from a backup.
Description: Restores the system from a specified backup. Auth: Required (admin) Rate Limit: Standard (100/min)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
int | Backup ID |
Trigger a storage scan via admin interface.
Description: Admin-level scan trigger (can scan all roots). Auth: Required (admin) Rate Limit: Standard (100/min)
All user management endpoints require a JWT token and appropriate permissions.
Create a new user.
Description: Creates a user account with role assignment. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"username": "johndoe",
"email": "john@example.com",
"password": "securepassword123",
"role_id": 2,
"first_name": "John",
"last_name": "Doe",
"display_name": "John D.",
"time_zone": "America/New_York",
"language": "en",
"is_active": true
}Response: 201 Created (User object)
Errors: 400 (password validation), 409 (duplicate username/email)
List all users with pagination.
Description: Returns paginated user list. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
int | 50 |
Max results (max 100) |
offset |
int | 0 |
Pagination offset |
Response: 200 OK
{
"users": [...],
"total_count": 150,
"limit": 50,
"offset": 0
}Get a specific user by ID.
Description: Returns user profile. Users can view their own profile; viewing others requires user.view permission.
Auth: Required
Rate Limit: Standard (100/min)
Update a user's information.
Description: Updates user fields. Users can update own profile; changing role_id or is_active requires user.manage.
Auth: Required
Rate Limit: Standard (100/min)
Request Body (all fields optional):
{
"username": "newusername",
"email": "newemail@example.com",
"first_name": "John",
"last_name": "Doe",
"display_name": "John D.",
"avatar_url": "https://example.com/avatar.jpg",
"time_zone": "America/New_York",
"language": "en",
"role_id": 2,
"is_active": true,
"settings": {"theme": "dark"}
}Delete a user account.
Description: Permanently removes a user. Cannot delete own account.
Auth: Required (user.delete)
Rate Limit: Standard (100/min)
Response: 204 No Content
Errors: 400 (cannot delete own account)
Reset a user's password (admin operation).
Description: Admin-level forced password reset.
Auth: Required (user.manage)
Rate Limit: Standard (100/min)
Request Body:
{
"new_password": "newSecurePassword123"
}Lock a user account until a specified time.
Description: Temporarily disables a user account.
Auth: Required (user.manage)
Rate Limit: Standard (100/min)
Request Body:
{
"lock_until": "2024-02-01T00:00:00Z"
}Unlock a locked user account.
Description: Re-enables a previously locked account.
Auth: Required (user.manage)
Rate Limit: Standard (100/min)
Response: 200 OK
{
"message": "Account unlocked successfully"
}All role management endpoints require system.admin permission.
Create a new role.
Description: Defines a new role with a set of permissions.
Auth: Required (system.admin)
Rate Limit: Standard (100/min)
Request Body:
{
"name": "editor",
"description": "Content editor with media management access",
"permissions": ["media.view", "media.edit", "media.upload"]
}Response: 201 Created (Role object)
List all roles.
Description: Returns all defined roles with their permissions.
Auth: Required (system.admin)
Rate Limit: Standard (100/min)
Response: 200 OK (array of Role objects)
Get a specific role by ID.
Description: Returns role details including permissions.
Auth: Required (system.admin)
Rate Limit: Standard (100/min)
Update a role. System roles cannot be modified.
Description: Modifies role name, description, or permissions.
Auth: Required (system.admin)
Rate Limit: Standard (100/min)
Request Body:
{
"name": "editor",
"description": "Updated description",
"permissions": ["media.view", "media.edit", "media.upload", "media.delete"]
}Delete a role. System roles and roles assigned to users cannot be deleted.
Description: Removes a custom role definition.
Auth: Required (system.admin)
Rate Limit: Standard (100/min)
Response: 204 No Content
Get the complete permission catalog organized by category.
Description: Lists all available permissions that can be assigned to roles.
Auth: Required (system.admin)
Rate Limit: Standard (100/min)
Response: 200 OK
{
"user_management": {
"create_user": "user.create",
"view_user": "user.view",
"edit_user": "user.update",
"delete_user": "user.delete",
"manage_users": "user.manage"
},
"media_management": {
"view_media": "media.view",
"upload_media": "media.upload",
"edit_media": "media.edit",
"delete_media": "media.delete"
},
"share_management": {
"view_shares": "share.view",
"create_shares": "share.create",
"edit_shares": "share.edit",
"delete_shares": "share.delete"
},
"system": {
"system_admin": "system.admin",
"view_analytics": "analytics.view",
"export_data": "analytics.export",
"manage_settings": "system.configure"
}
}Get the current system configuration schema.
Description: Returns the configuration schema and current values.
Auth: Required (system.configure)
Rate Limit: Standard (100/min)
Test a configuration without applying it.
Description: Validates a configuration object and reports errors/warnings.
Auth: Required (system.admin)
Rate Limit: Standard (100/min)
Request Body: A Configuration object.
Response: 200 OK
{
"is_valid": true,
"errors": [],
"warnings": ["SMTP not configured"]
}Get system component health status.
Description: Returns health status of all system components.
Auth: Required (system.configure)
Rate Limit: Standard (100/min)
Response: 200 OK
{
"status": "healthy",
"version": "3.0.0",
"uptime": "24h 30m",
"components": {
"database": "healthy",
"storage": "healthy",
"authentication": "healthy",
"media_conversion": "healthy",
"sync": "healthy"
}
}Get a specific setup wizard step definition.
Description: Returns the step configuration including fields, validation rules, and defaults. Auth: Required Rate Limit: Standard (100/min)
Validate data for a specific wizard step.
Description: Validates user input for a wizard step without saving. Auth: Required Rate Limit: Standard (100/min)
Save progress for a specific wizard step.
Description: Persists the user's input for a wizard step. Auth: Required Rate Limit: Standard (100/min)
Get the current wizard progress for the authenticated user.
Description: Returns which steps are completed and the current step. Auth: Required Rate Limit: Standard (100/min)
Complete the setup wizard and apply the configuration.
Description: Finalizes wizard setup, applying all saved step data as the active configuration. Auth: Required Rate Limit: Standard (100/min)
Submit an error report.
Description: Logs an application error with stack trace and context. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"level": "error",
"message": "Failed to process media file",
"error_code": "MEDIA_PROCESS_ERROR",
"component": "media_processor",
"stack_trace": "goroutine 1 [running]:...",
"context": {"file_id": 123, "operation": "thumbnail_generation"},
"user_agent": "Mozilla/5.0...",
"url": "/api/v1/media/123/thumbnail"
}Response: 200 OK (ErrorReport object)
Submit a crash report.
Description: Logs a crash event with signal and stack trace. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"signal": "SIGSEGV",
"message": "Segmentation fault in media decoder",
"stack_trace": "...",
"context": {"media_id": 42}
}List error reports with filtering.
Description: Returns paginated error reports with optional filters. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
level |
string | Filter: debug, info, warning, error, fatal |
component |
string | Filter by component |
status |
string | Filter: new, in_progress, resolved, ignored |
start_date |
string | Start date (YYYY-MM-DD) |
end_date |
string | End date (YYYY-MM-DD) |
limit |
int | Max results |
offset |
int | Pagination offset |
Get a specific error report.
Description: Returns full details of an error report. Auth: Required Rate Limit: Standard (100/min)
Update error report status.
Description: Changes the triage status of an error report. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"status": "resolved"
}List crash reports with filtering.
Description: Returns paginated crash reports (same parameters as error reports, with signal instead of level/component).
Auth: Required
Rate Limit: Standard (100/min)
Get a specific crash report.
Description: Returns full details of a crash report. Auth: Required Rate Limit: Standard (100/min)
Update crash report status.
Description: Changes the triage status of a crash report. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"status": "resolved"
}Get error reporting statistics.
Description: Returns aggregate error counts by level, component, and resolution status. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"total_errors": 150,
"errors_by_level": {"error": 100, "warning": 40, "fatal": 10},
"errors_by_component": {"media_processor": 80, "auth": 30, "storage": 40},
"recent_errors": 15,
"resolved_errors": 120,
"avg_resolution_time": 3600.5
}Get crash reporting statistics.
Description: Returns aggregate crash counts by signal and resolution status. Auth: Required Rate Limit: Standard (100/min)
Get system health based on error and crash data.
Description: Evaluates system health by analyzing recent error and crash trends.
Auth: Required (system.admin)
Rate Limit: Standard (100/min)
All log management endpoints require system.admin permission.
Create a new log collection.
Description: Initiates log collection from specified components and time range.
Auth: Required (system.admin)
Rate Limit: Standard (100/min)
Request Body:
{
"name": "Debug Session 2024-01-20",
"description": "Investigating media processing issue",
"components": ["api", "media_processor", "storage"],
"log_level": "debug",
"start_time": "2024-01-20T00:00:00Z",
"end_time": "2024-01-20T23:59:59Z",
"filters": {"include_stack_traces": true}
}List log collections.
Description: Returns paginated list of log collections.
Auth: Required (system.admin)
Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Default |
|---|---|---|
limit |
int | 20 |
offset |
int | 0 |
Get a specific log collection.
Description: Returns metadata for a log collection.
Auth: Required (system.admin)
Rate Limit: Standard (100/min)
Get log entries for a collection.
Description: Returns individual log entries with filtering.
Auth: Required (system.admin)
Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
level |
string | Filter by level |
component |
string | Filter by component |
search |
string | Full-text search |
start_time |
string | ISO 8601 start time |
end_time |
string | ISO 8601 end time |
limit |
int | Max results |
offset |
int | Pagination offset |
Export log collection data.
Description: Exports a log collection in the specified format.
Auth: Required (system.admin)
Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Default | Options |
|---|---|---|---|
format |
string | json |
json, csv, txt, zip |
Analyze a log collection for patterns and insights.
Description: Runs pattern analysis on log entries and returns insights.
Auth: Required (system.admin)
Rate Limit: Standard (100/min)
Response: 200 OK
{
"collection_id": 5,
"total_entries": 5000,
"entries_by_level": {"error": 100, "warning": 500, "info": 3000, "debug": 1400},
"entries_by_component": {"api": 2000, "storage": 1500, "media_processor": 1500},
"error_patterns": {"connection_timeout": 45, "file_not_found": 30},
"time_range": {"start": "2024-01-20T00:00:00Z", "end": "2024-01-20T23:59:59Z"},
"insights": ["Error rate increased 40% between 14:00-16:00", "Storage component shows timeout pattern"]
}Create a shareable link for a log collection.
Description: Generates a time-limited sharing token for a log collection.
Auth: Required (system.admin)
Rate Limit: Standard (100/min)
Request Body:
{
"collection_id": 5,
"share_type": "private",
"expires_at": "2024-02-01T00:00:00Z",
"permissions": ["read"],
"recipients": ["dev@example.com"]
}Access a shared log collection via share token.
Description: Retrieves log collection data using a share token.
Auth: Required (system.admin)
Rate Limit: Standard (100/min)
Revoke a log share.
Description: Invalidates a sharing token.
Auth: Required (system.admin)
Rate Limit: Standard (100/min)
Stream live logs via Server-Sent Events (SSE).
Description: Opens a persistent SSE connection for real-time log streaming.
Auth: Required (system.admin)
Rate Limit: Standard (100/min)
Content-Type: text/event-stream
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
level |
string | Filter by level |
component |
string | Filter by component |
search |
string | Search term |
SSE Format:
data: {"id":1,"timestamp":"2024-01-20T10:00:00Z","level":"error","component":"api","message":"Request timeout","context":{}}
data: {"id":2,"timestamp":"2024-01-20T10:00:01Z","level":"info","component":"storage","message":"File scan completed","context":{"files":500}}
Get log management statistics.
Description: Returns aggregate log collection and entry statistics.
Auth: Required (system.admin)
Rate Limit: Standard (100/min)
Response: 200 OK
{
"total_collections": 25,
"total_entries": 150000,
"active_shares": 3,
"collections_by_status": {"completed": 20, "in_progress": 3, "failed": 2},
"recent_collections": 5
}Media collection endpoints for organizing media items into user-defined collections.
List all media collections.
Description: Returns user's media collections. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"collections": [
{
"id": 1,
"name": "Sci-Fi Favorites",
"description": "Best sci-fi movies",
"item_count": 25,
"created_at": "2024-01-01T00:00:00Z"
}
]
}Create a new media collection.
Description: Creates an empty collection for the user. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"name": "Sci-Fi Favorites",
"description": "Best sci-fi movies",
"is_public": false
}Get a specific collection with its items.
Description: Returns collection details and contained media items. Auth: Required Rate Limit: Standard (100/min)
Update a collection's name or description.
Description: Modifies collection metadata. Auth: Required Rate Limit: Standard (100/min)
Delete a collection.
Description: Removes the collection (does not delete the media items). Auth: Required Rate Limit: Standard (100/min)
Authenticated asset management endpoints.
Request an asset to be resolved and cached.
Description: Triggers async asset resolution (cover art, thumbnails) via the asset pipeline. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"entity_type": "movie",
"entity_id": "42",
"asset_type": "cover"
}Response: 202 Accepted
{
"asset_id": "abc123",
"status": "resolving"
}Get the asset for a specific entity type and ID.
Description: Returns the resolved asset URL/data for an entity. Auth: Required Rate Limit: Standard (100/min)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
type |
string | Entity type (e.g., movie, tv_show, music_album) |
id |
int | Entity ID |
Response: 200 OK (asset data or redirect to asset URL)
Structured media entity browsing. All endpoints are cached for 5 minutes.
List media entities with filtering and pagination.
Description: Returns paginated media entities with optional type and search filters. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
type |
string | - | Media type filter |
query |
string | - | Search term |
parent_id |
int | - | Filter by parent entity |
limit |
int | 50 |
Max results |
offset |
int | 0 |
Pagination offset |
Response: 200 OK
{
"entities": [...],
"total": 150,
"limit": 50,
"offset": 0
}Get all media entity types.
Description: Returns the list of media types with counts. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"types": [
{"name": "movie", "label": "Movie", "count": 500},
{"name": "tv_show", "label": "TV Show", "count": 150},
{"name": "tv_season", "label": "TV Season", "count": 800},
{"name": "tv_episode", "label": "TV Episode", "count": 5000},
{"name": "music_artist", "label": "Music Artist", "count": 200},
{"name": "music_album", "label": "Music Album", "count": 1200},
{"name": "song", "label": "Song", "count": 12000},
{"name": "game", "label": "Game", "count": 100},
{"name": "software", "label": "Software", "count": 50},
{"name": "book", "label": "Book", "count": 300},
{"name": "comic", "label": "Comic", "count": 75}
]
}Get aggregate entity statistics.
Description: Returns counts and totals grouped by entity type. Auth: Required Rate Limit: Standard (100/min)
List groups of duplicate media entities.
Description: Finds entities that may be duplicates based on title, type, and year. Auth: Required Rate Limit: Standard (100/min)
Browse entities by media type.
Description: Returns entities of a specific type with type-appropriate sorting and filtering. Auth: Required Rate Limit: Standard (100/min)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
type |
string | Media type: movie, tv_show, music_artist, game, software, book, comic, etc. |
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
sort_by |
string | title |
Sort field |
sort_order |
string | asc |
Sort direction |
limit |
int | 50 |
Max results |
offset |
int | 0 |
Pagination offset |
Get a specific media entity by ID.
Description: Returns full entity details including metadata and hierarchy info. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"id": 42,
"title": "The Matrix",
"media_type": "movie",
"year": 1999,
"description": "A computer hacker learns about the true nature of reality.",
"parent_id": null,
"cover_url": "/api/v1/cover/42",
"metadata": {},
"file_count": 3,
"total_size": 8589934592,
"created_at": "2024-01-15T10:30:00Z"
}Get child entities of a parent entity (e.g., seasons of a TV show, albums of an artist).
Description: Returns the entity hierarchy children. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"parent_id": 42,
"children": [
{"id": 43, "title": "Season 1", "media_type": "tv_season", "year": 1999},
{"id": 44, "title": "Season 2", "media_type": "tv_season", "year": 2000}
]
}Get files associated with a media entity.
Description: Returns the file records linked to this entity via the media_files junction table. Auth: Required Rate Limit: Standard (100/min)
Get external metadata for a media entity.
Description: Returns metadata from external providers (TMDB, OMDB, MusicBrainz, OpenLibrary). Auth: Required Rate Limit: Standard (100/min)
Get potential duplicates of a specific entity.
Description: Finds entities that may be duplicates of this one. Auth: Required Rate Limit: Standard (100/min)
Stream the primary file of a media entity.
Description: Proxies the main media file for playback. Supports range requests. Auth: Required Rate Limit: Standard (100/min)
Download the primary file of a media entity.
Description: Downloads the main media file as an attachment. Auth: Required Rate Limit: Standard (100/min)
Get installation information for a software or game entity.
Description: Returns install instructions, requirements, and file details for software/game entities. Auth: Required Rate Limit: Standard (100/min)
Refresh external metadata for a specific entity.
Description: Re-fetches metadata from all configured providers. Auth: Required Rate Limit: Standard (100/min)
Update user-specific metadata for an entity (e.g., personal rating, notes).
Description: Saves user-provided metadata that augments the entity. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"rating": 9,
"notes": "One of my all-time favorites",
"tags": ["sci-fi", "action", "classic"]
}Alias for PUT /api/v1/entities/:id/user-metadata. Same behavior.
Description: Alternative method for updating user metadata. Auth: Required Rate Limit: Standard (100/min)
Trigger bulk metadata enrichment for all entities.
Description: Starts background enrichment from external providers for entities missing metadata. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"message": "Enrichment started",
"entities_queued": 150
}Log a media access event.
Description: Records that a user accessed/viewed a media item. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"media_id": 42,
"action": "play",
"duration_seconds": 7200
}Log a generic analytics event.
Description: Records a custom analytics event with arbitrary context. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"event_type": "search",
"context": {"query": "matrix", "results_count": 15}
}Get analytics data for a specific user.
Description: Returns user engagement metrics and activity history. Auth: Required Rate Limit: Standard (100/min)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
user_id |
int | User ID |
Get system-wide analytics.
Description: Returns aggregate system usage metrics. Auth: Required Rate Limit: Standard (100/min)
Get analytics data for a specific media item.
Description: Returns access counts, popularity metrics, and engagement data for a media item. Auth: Required Rate Limit: Standard (100/min)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
media_id |
int | Media item ID |
Create an analytics report.
Description: Generates a custom analytics report based on specified criteria. Auth: Required Rate Limit: Standard (100/min)
Get a usage report.
Description: Returns system usage metrics over a time period. Auth: Required Rate Limit: Standard (100/min)
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
start_date |
string | - | Start date (YYYY-MM-DD) |
end_date |
string | - | End date (YYYY-MM-DD) |
granularity |
string | daily |
hourly, daily, weekly, monthly |
Get a performance report.
Description: Returns API performance metrics (response times, error rates, throughput). Auth: Required Rate Limit: Standard (100/min)
List the current user's favorites.
Description: Returns all entities the user has marked as favorite. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"favorites": [
{
"entity_type": "movie",
"entity_id": 42,
"title": "The Matrix",
"added_at": "2024-01-15T10:30:00Z"
}
]
}Add an entity to favorites.
Description: Marks an entity as a favorite for the current user. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"entity_type": "movie",
"entity_id": 42
}Remove an entity from favorites.
Description: Removes the favorite mark from an entity. Auth: Required Rate Limit: Standard (100/min)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
entity_type |
string | Entity type (e.g., movie, tv_show) |
entity_id |
int | Entity ID |
Check if an entity is in the user's favorites.
Description: Returns whether the entity is favorited by the current user. Auth: Required Rate Limit: Standard (100/min)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
entity_type |
string | Entity type |
entity_id |
int | Entity ID |
Response: 200 OK
{
"is_favorite": true
}List the current user's playlists.
Description: Returns all playlists owned by the user. Auth: Required Rate Limit: Standard (100/min)
Create a new playlist.
Description: Creates an empty playlist. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"name": "Road Trip Mix",
"description": "Music for long drives",
"is_public": false
}Get a specific playlist with its items.
Description: Returns playlist details and ordered items. Auth: Required Rate Limit: Standard (100/min)
Update a playlist's metadata.
Description: Modifies playlist name, description, or visibility. Auth: Required Rate Limit: Standard (100/min)
Delete a playlist.
Description: Removes the playlist (does not delete the media items). Auth: Required Rate Limit: Standard (100/min)
Add an item to a playlist.
Description: Appends a media entity to the playlist. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"entity_type": "song",
"entity_id": 123,
"position": 5
}Remove an item from a playlist.
Description: Removes a specific item from the playlist. Auth: Required Rate Limit: Standard (100/min)
Directory browsing and file information endpoints using the database file repository.
Get all storage roots available for browsing.
Description: Lists storage roots with browse-relevant metadata. Auth: Required Rate Limit: Standard (100/min)
Browse a directory and list its contents from the database.
Description: Returns files and subdirectories at the specified path. Auth: Required Rate Limit: Standard (100/min)
Get detailed file information from the database.
Description: Returns metadata for a specific file path. Auth: Required Rate Limit: Standard (100/min)
Get subdirectory sizes for a given path.
Description: Returns the total size of each subdirectory. Auth: Required Rate Limit: Standard (100/min)
Get duplicate files within a directory.
Description: Finds duplicates under the specified directory path. Auth: Required Rate Limit: Standard (100/min)
Remote synchronization endpoints (WebDAV, S3, GCS, local).
Create a sync endpoint configuration.
Description: Registers a remote sync destination. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"name": "Cloud Backup",
"type": "s3",
"config": {
"bucket": "my-backup-bucket",
"region": "us-east-1",
"access_key": "...",
"secret_key": "..."
},
"sync_direction": "push",
"filters": {"extensions": [".mkv", ".mp4"]}
}List the user's sync endpoints.
Description: Returns all configured sync destinations for the user. Auth: Required Rate Limit: Standard (100/min)
Get a specific sync endpoint.
Description: Returns endpoint configuration details. Auth: Required Rate Limit: Standard (100/min)
Update a sync endpoint configuration.
Description: Modifies sync endpoint settings. Auth: Required Rate Limit: Standard (100/min)
Delete a sync endpoint.
Description: Removes a sync destination configuration. Auth: Required Rate Limit: Standard (100/min)
Start a sync operation on an endpoint.
Description: Triggers immediate synchronization. Auth: Required Rate Limit: Standard (100/min)
Response: 202 Accepted
{
"session_id": "sync-abc123",
"status": "started"
}List the user's sync sessions.
Description: Returns sync operation history for the user. Auth: Required Rate Limit: Standard (100/min)
Get a specific sync session.
Description: Returns detailed sync session status and progress. Auth: Required Rate Limit: Standard (100/min)
Create a sync schedule.
Description: Sets up automatic recurring synchronization. Auth: Required Rate Limit: Standard (100/min)
Request Body:
{
"endpoint_id": 1,
"cron": "0 2 * * *",
"enabled": true
}Get sync statistics.
Description: Returns aggregate sync metrics (bytes transferred, sessions, errors). Auth: Required Rate Limit: Standard (100/min)
Clean up old sync sessions.
Description: Removes completed sync session records older than a threshold. Auth: Required Rate Limit: Standard (100/min)
Challenge system endpoints for running validation and testing challenges.
List all registered challenges.
Description: Returns the full challenge catalog with status. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"challenges": [
{
"id": "CH-001",
"name": "Health Check",
"category": "infrastructure",
"description": "Verify API health endpoint returns 200",
"status": "passed"
}
],
"total": 492
}Get a specific challenge by ID.
Description: Returns challenge details and last run result. Auth: Required Rate Limit: Standard (100/min)
Run a specific challenge.
Description: Executes a single challenge and returns the result. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"id": "CH-001",
"status": "passed",
"duration_ms": 150,
"assertions": [
{"name": "health_endpoint_returns_200", "passed": true}
]
}Run all challenges (synchronous, blocking).
Description: Executes the entire challenge suite sequentially. WARNING: This is blocking -- no other challenge can run until it finishes. Can take 25+ minutes for NAS scans. Auth: Required Rate Limit: Standard (100/min)
Response: 200 OK
{
"total": 492,
"passed": 490,
"failed": 2,
"skipped": 0,
"duration_ms": 1500000,
"results": [...]
}Run all challenges in a specific category.
Description: Executes challenges filtered by category. Auth: Required Rate Limit: Standard (100/min)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
category |
string | Challenge category (e.g., infrastructure, browsing, media, security) |
Get the results from the most recent challenge run.
Description: Returns cached results from the last challenge execution. Auth: Required Rate Limit: Standard (100/min)
All requests pass through these middleware layers:
| Middleware | Description |
|---|---|
| Security Headers | HSTS, X-Content-Type-Options, X-Frame-Options, etc. |
| Concurrency Limiter | Max 100 concurrent requests |
| Request Timeout | 60-second request timeout |
| CORS | Cross-Origin Resource Sharing headers |
| Prometheus Metrics | Request duration and count tracking |
| Logger | Structured request logging (zap) |
| Error Handler | Consistent error response formatting |
| Request ID | Unique X-Request-ID header per request |
| Input Validation | Request body sanitization and validation |
| Compression | Brotli (primary) with gzip fallback |
| JWT Auth | Token validation on /api/v1/* routes (except auth/public) |
| Rate Limiting | Per-user request throttling |
| Cache Headers | Cache-Control headers on static/discovery endpoints |
All error responses follow a consistent format:
{
"error": "Human-readable error message"
}Or the structured format used by subtitle and recommendation handlers:
{
"success": false,
"error": "Human-readable error message",
"code": "MACHINE_READABLE_CODE"
}| Code | Meaning |
|---|---|
| 200 | Success |
| 201 | Created (user registration, resource creation) |
| 202 | Accepted (async operation queued) |
| 204 | No Content (successful deletion) |
| 400 | Bad Request (validation error, invalid parameters) |
| 401 | Unauthorized (missing or invalid JWT) |
| 403 | Forbidden (insufficient permissions or domain not allowed) |
| 404 | Not Found (resource does not exist) |
| 409 | Conflict (duplicate resource) |
| 429 | Too Many Requests (rate limited) |
| 500 | Internal Server Error |
| 502 | Bad Gateway (upstream fetch failed, e.g., image proxy) |
| 503 | Service Unavailable (unhealthy) |
Rate limiting is applied per-user based on the JWT token. Two tiers are used:
| Endpoint Group | Limit | Description |
|---|---|---|
POST /api/v1/auth/login |
5 requests/minute | Brute-force protection |
POST /api/v1/auth/register |
5 requests/minute | Brute-force protection |
All other /api/v1/* |
100 requests/minute | Standard rate limit |
When rate limited, the server returns 429 Too Many Requests.
Optional Redis-based distributed rate limiting is available when a Redis instance is configured. Supports both fixed-window and sliding-window algorithms.