Skip to content
🚧 These docs are a work in progress and may contain inaccuracies. Content is being actively reviewed and validated.

REST API

Dubby provides a REST API at /v1/ for programmatic access to all server functionality. The API follows OpenAPI 3.1 conventions with auto-generated documentation.

  • OpenAPI spec: GET /v1/openapi.json
  • Swagger UI: GET /docs

The Swagger UI lets you explore endpoints, view request/response schemas, and make test requests directly from your browser.

The web client uses better-auth session cookies. Same-origin requests include the cookie automatically.

  1. Sign in to get a token:
Terminal window
curl -X POST http://localhost:3000/api/auth/sign-in/email \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]", "password": "your-password"}'
  1. Use the token in subsequent requests:
Terminal window
curl http://localhost:3000/v1/movies \
-H "Authorization: Bearer <token>"

Sessions last 7 days and auto-extend every 24 hours on activity.

ConventionDetails
Content typeapplication/json for request and response bodies
IDsNanoid strings (21 characters)
PaginationCursor-based via cursor query parameter
Page sizelimit parameter (1-100, default 20)
Errors{ "error": "description" } with appropriate HTTP status
Validation422 with { "error": "Validation error", "details": [{ "path": "...", "message": "..." }] }
Max body1 MB (returns 413 if exceeded)

The REST API has 34 route groups. Below are the most commonly used endpoints. For the complete list, use the interactive Swagger UI at /docs or fetch the OpenAPI spec at /v1/openapi.json.

MethodEndpointDescription
POST/api/auth/sign-in/emailSign in with email and password
POST/api/auth/sign-outSign out
MethodEndpointDescription
GET/v1/librariesList libraries (filtered by user permissions)
POST/v1/librariesCreate a library
GET/v1/libraries/:idGet library details
PATCH/v1/libraries/:idUpdate a library
DELETE/v1/libraries/:idDelete a library (files on disk are not deleted)
POST/v1/libraries/:id/scanStart a library scan
GET/v1/libraries/:id/statsLibrary statistics
MethodEndpointDescription
GET/v1/moviesList movies with filters and sorting
GET/v1/movies/recently-addedRecently added movies
GET/v1/movies/:idMovie details
GET/v1/movies/:id/creditsCast and crew
PUT/v1/movies/:id/watchedMark as watched
DELETE/v1/movies/:id/watchedMark as unwatched
GET/v1/movies/:id/file-statsFile codec/resolution details
MethodEndpointDescription
GET/v1/showsList TV shows with filters and sorting
GET/v1/shows/recently-addedRecently added shows
GET/v1/shows/:idShow details
GET/v1/shows/:id/seasonsList seasons
GET/v1/shows/:id/seasons/:numSeason details
GET/v1/shows/:id/seasons/:num/episodesList episodes in a season
GET/v1/shows/:id/seasons/:num/episodes/:numEpisode details
MethodEndpointDescription
POST/v1/playback/sessionsCreate a playback session
POST/v1/playback/sessions/:id/heartbeatKeep session alive, update position
POST/v1/playback/sessions/:id/seekSeek to a position
DELETE/v1/playback/sessions/:idEnd a session
GET/v1/playback/continue-watchingContinue watching list
GET/v1/playback/sessions/activeActive sessions
MethodEndpointDescription
GET/v1/searchFull-text search across all media types
GET/v1/search/suggestionsAutocomplete search suggestions
MethodEndpointDescription
GET/v1/collectionsList collections
POST/v1/collectionsCreate a collection
GET/v1/collections/:idGet collection details
PATCH/v1/collections/:idUpdate a collection
DELETE/v1/collections/:idDelete a collection
GET/v1/collections/:id/itemsList items in a collection
POST/v1/collections/:id/itemsAdd an item
POST/v1/collections/:id/items/batchAdd multiple items
DELETE/v1/collections/:id/items/:mediaType/:mediaIdRemove an item
PUT/v1/collections/:id/items/orderReorder items
POST/v1/collections/:id/refreshRefresh an auto-collection
POST/v1/collections/preview-rulesPreview rule match count
MethodEndpointDescription
GET/v1/ai/availableCheck if AI inference is available
POST/v1/ai/searchInterpret natural language search query
POST/v1/ai/suggest-collectionsAI-powered collection suggestion
POST/v1/ai/enrich-metadataSubmit AI metadata enrichment job
GET/v1/ai/usageGet inference usage and credit balance
GET/v1/ai/requestsPaginated inference request log (admin)
GET/v1/enrichment/:mediaType/:mediaIdGet AI enrichment for a media item
POST/v1/enrichment/enrichEnrich a single item
POST/v1/enrichment/enrich-libraryBulk enrich a library
GET/v1/enrichment/statsEnrichment statistics
MethodEndpointDescription
GET/v1/watchlistList watchlist items
POST/v1/watchlistAdd item to watchlist
DELETE/v1/watchlist/:idRemove from watchlist
MethodEndpointDescription
GET/v1/discoverBrowse trending/popular from TMDB
MethodEndpointDescription
GET/v1/people/:idPerson details and roles
MethodEndpointDescription
GET/v1/podcastsList subscribed podcasts
POST/v1/podcastsSubscribe to a podcast
DELETE/v1/podcasts/:idUnsubscribe
GET/v1/podcasts/:id/episodesList episodes
MethodEndpointDescription
GET/v1/migration/discoverAuto-discover media servers on network
POST/v1/migration/test-connectionTest connectivity to a source server
POST/v1/migration/previewPreview libraries and users on source
POST/v1/migration/sourcesCreate a migration source connection
GET/v1/migration/sourcesList migration sources
POST/v1/migration/importStart a migration import workflow
GET/v1/migration/gap-reportCount shell records awaiting files
MethodEndpointDescription
POST/v1/parental-controls/pinSet or update profile PIN
POST/v1/parental-controls/pin/verifyVerify a PIN
GET/v1/parental-controls/profilesList managed profiles
POST/v1/parental-controls/profilesCreate a managed profile
PATCH/v1/parental-controls/profiles/:profileIdUpdate a profile
DELETE/v1/parental-controls/profiles/:profileIdDelete a profile
POST/v1/parental-controls/switch-profileSwitch active profile
MethodEndpointDescription
GET/v1/backupsList backups
POST/v1/backupsCreate a backup
GET/v1/backups/:idGet backup details
DELETE/v1/backups/:idDelete a backup
POST/v1/backups/restoreRestore from a backup
MethodEndpointDescription
GET/v1/admin/dashboardDashboard analytics
GET/v1/admin/usersList all users
GET/v1/audit-logsQuery audit logs (admin)
GET/v1/feature-flagsList feature flags
PATCH/v1/feature-flags/:keyToggle flag default
GET/v1/jobsList background jobs
GET/v1/workflowsList workflow runs

These route groups are fully documented in the Swagger UI:

Route groupDescription
/v1/settingsServer settings CRUD
/v1/setupFirst-run setup wizard
/v1/configUnified server configuration
/v1/metadataMetadata search, identification, refresh
/v1/integrationsTMDB, Trakt, Radarr/Sonarr configuration
/v1/subtitlesSubtitle track management
/v1/audioAudio track information
/v1/playback-preferencesPer-user audio/subtitle language rules
/v1/optimizationAhead-of-time transcoding profiles
/v1/seerrSeerr integration management
/v1/healthLiveness and readiness probes
/v1/usersUser profile management
StatusMeaning
400Bad request
401Missing or invalid authentication
403Insufficient permissions
404Resource not found
409Conflict (e.g., scan already running)
413Request body too large
422Validation error
429Rate limit exceeded (check Retry-After header)
503Service unavailable
ScopeLimit
General API100 requests/minute
Speedtest3 requests/minute

Rate-limited responses include a Retry-After header indicating when you can retry.

Streaming uses separate routes outside the /v1/ prefix. See Stream Tokens for authentication details.

RouteDescription
GET /api/stream/:sessionId/master.m3u8HLS master playlist
GET /api/stream/:sessionId/:quality/playlist.m3u8Quality-specific playlist
GET /api/stream/:sessionId/:quality/:filenameHLS segment
GET /api/stream/:sessionId/fileDirect file (HTTP Range)
GET /api/stream/:sessionId/subtitles/:filenameWebVTT subtitle