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

Migration & Import

Dubby can import your existing media server data so you don’t have to start from scratch. The migration system supports Plex, Jellyfin, and Emby with auto-discovery, preview, and resumable workflows.

SourceLibrariesWatch historyUsersCollectionsArtwork
PlexYesYesYesYesYes
JellyfinYesYesYesYesYes
EmbyYesYesYesYesYes
  • Libraries — Mapped to existing Dubby libraries by type (movies or TV)
  • Metadata — Titles, years, descriptions, genres, content ratings, and studio info
  • Watch history — Play count, resume position, last played date, and watched status
  • Watchlist — Jellyfin/Emby favorites are imported as Dubby watchlist items
  • Collections — User-created playlists become manual collections in Dubby
  • Artwork — Custom posters and backdrops are downloaded and stored locally
  • Users — Source users can be created as new Dubby users, mapped to existing accounts, or skipped

Items are matched to your Dubby library using TMDB, IMDb, and TVDB external IDs. Items that can’t be matched are created as “shell” records — placeholders that get enriched with metadata from TMDB automatically.

Go to Settings > Import in the admin panel.

Auto-discovery: Click Scan Network to discover media servers on your local network via UDP broadcast. Select a server from the results and enter its API token.

Manual entry: Choose the server type, enter the URL and API token manually.

ServerWhere to find the API token
PlexSettings > General > X-Plex-Token (or from the URL bar)
JellyfinDashboard > API Keys > Create
EmbyDashboard > Advanced > API Keys > New API Key

Click Test Connection to verify. If successful, save the source.

Before importing, preview what will be imported:

  • Libraries — See all libraries on the source with item counts
  • Users — See all users on the source server

This lets you verify the connection is reading the right data before committing to an import.

Library mappings — Map each source library to a Dubby library. Only libraries of matching type (movies → movies, TV → TV) can be mapped.

User mappings — For each source user, choose:

  • Create — Create a new Dubby user account
  • Map — Map to an existing Dubby user (merges watch history)
  • Skip — Don’t import this user’s data

Click Start Import to begin. The import runs as a background workflow with these steps:

  1. Connect — Validate the source server connection
  2. Fetch — Pull all items, collections, and watch states from the source
  3. Match — Match source items to existing Dubby records using external IDs
  4. Create shells — Create placeholder records for items not yet in your Dubby library
  5. Import users — Create or map user accounts
  6. Import watch history — Merge watch states (keeps the most recent data from either side)
  7. Import collections — Create manual collections from source playlists
  8. Import artwork — Download custom posters and backdrops
  9. Enrich — Queue TMDB metadata enrichment for newly created shell records
  10. Finalize — Mark the import as complete with a summary

Progress is tracked in real time via the admin dashboard.

When a user has watch data on both the source and in Dubby, the import merges intelligently:

  • Play count — Takes the higher value
  • Resume position — Uses whichever is more recent
  • Watched status — Marked watched if either side says watched

Items that exist on the source but not in your Dubby library are created as shell records with ingestStatus: 'requested'. These are placeholders that:

  • Appear in your library immediately
  • Get enriched with TMDB metadata automatically
  • Fill in fully once the actual media file is scanned from disk

The Gap Report in Settings > Import shows how many shell records are still awaiting media files.

The import uses Dubby’s durable workflow engine. If the server crashes or restarts mid-import, completed steps are not re-executed — the workflow picks up where it left off.

Failed items don’t block the rest of the import. Each item is tracked individually and errors are reported in the import summary.

From Settings > Import, you can:

  • View saved sources with their status (connected, importing, completed, error)
  • Delete a source (removes the connection and tracking data — imported records are kept)
  • Re-run an import to pick up new items added since the last import
Terminal window
# Discover servers on the network
curl -H "Authorization: Bearer $TOKEN" http://localhost:3000/v1/migration/discover
# Create a source
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"type": "plex", "name": "My Plex", "baseUrl": "http://192.168.1.100:32400", "token": "your-token"}' \
http://localhost:3000/v1/migration/sources
# Start import
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"sourceId": "source-id", "libraryMappings": [...], "userMappings": [...]}' \
http://localhost:3000/v1/migration/import
# Check gap report
curl -H "Authorization: Bearer $TOKEN" http://localhost:3000/v1/migration/gap-report