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.
Sign in to get a token:
curl -X POST http://localhost:3000/api/auth/sign-in/email \
-H " Content-Type: application/json " \
Use the token in subsequent requests:
curl http://localhost:3000/v1/movies \
-H " Authorization: Bearer <token> "
Sessions last 7 days and auto-extend every 24 hours on activity.
Convention Details Content type application/json for request and response bodiesIDs Nanoid strings (21 characters) Pagination Cursor-based via cursor query parameter Page size limit parameter (1-100, default 20)Errors { "error": "description" } with appropriate HTTP statusValidation 422 with { "error": "Validation error", "details": [{ "path": "...", "message": "..." }] }Max body 1 MB (returns 413 if exceeded)
Method Endpoint Description 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
Method Endpoint Description 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
Method Endpoint Description 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
Method Endpoint Description POST/api/auth/sign-in/emailSign in POST/api/auth/sign-outSign out
Status Meaning 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
Scope Limit General API 100 requests/minute Speedtest 3 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.
Route Description 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