Jellyfin Forum
Python script to migrate watched status and watched progress between servers - Printable Version

+- Jellyfin Forum (https://forum.jellyfin.org)
+-- Forum: Support (https://forum.jellyfin.org/f-support)
+--- Forum: Guides, Walkthroughs & Tutorials (https://forum.jellyfin.org/f-guides-walkthroughs-tutorials)
+--- Thread: Python script to migrate watched status and watched progress between servers (/t-python-script-to-migrate-watched-status-and-watched-progress-between-servers)



Python script to migrate watched status and watched progress between servers - Ozymandyaz - 2025-09-28

I wanted to migrate from one docker instance of Jellyfin to another with a clean DB but I also wanted to try and migrate the watched status (and watched progress) for each user in my setup. I found the really nice script Emby2Jelly (https://github.com/Marc-Vieg/Emby2Jelly) on the Jellyfin website, but found that while it does most of what I want, it does not carry over in-progress percentages, i.e. partially watched progress...

So... I forked and modified the script to include watched progress as well Smiling-face

https://github.com/Ozymandyaz/JellySync

With this script you can:
  • Copy watched and in-progress status from one Jellyfin instance to another
  • Create users on the destination if they do not already exist (Script also works if users are already there)
  • Run in “to file” mode and generate a backup of the source items and progress in a JSON file
  • Run in “From File” mode to import the watched status from a JSON file
  • It might be able to migrate from Emby as well, but I don’t use Emby…

The key to making this work however is that both instances need to be up and running, and they need to be pointed at the same media. The folder structure does not need to match, but the provider IDs in the source and destination need to match (i.e. the TVDBID, IMDB, etc… As a last ditch it will try title.) Basically as long as you have scanned the media library on both instances, the script should be able to figure it out.

Here is how I use it:
  • Have an existing Jellyfin instance up and running
  • Generate or use an existing API key
  • This will be the Source
  • Setup a new instance of Jellyfin
  • Login and create a user (I create a generic admin that I delete later)
  • Setup the destination libraries so that they cover all the same media as the existing instance
  • Complete a full Library scan
  • Generate an API key on the new instance
  • This will be the Destination
  • Grab the jellysync.py and example jellysync.ini and put in the same folder.
  • Modify the INI to point to the correct IP/URL of your Source and Destination servers
  • Add the API keys
  • Optionally add any users that you DO NOT want copied to the new instance in the ignore users section
  • Run the script: $python3 jellysync.py

If no users are setiup on the destination, run with the optional —pw flag and add a password that will be used for each user created:
$python3 jellysync.py —pw pa$$word

If run without —pw, the script will ask for a password for each user seen on the source (and not explicitly ignored…) If the user exists already on the destination you must enter the current password for that user (the script needs to login as the user so it needs the password… If the user does not exist, you will enter any new password for the user and the script will create the user and assign the password that was entered. It is acceptable hit enter with no input to make a blank password.
After that, it takes a few minutes to grab all the source media and compare it to the destination. If a match is found, the destination UserData section will be updated to match the source.

When run in tofile mode, the script will just do the first part and dump the source data to a JSON file.

When run in from file mode, the script will read from the supplied JSON file and only do the Destination portion.

Running in tofile mode is an excellent way to do daily backups of just watched status.

I hope this is useful!

-Oz