Plex Metadata API?

Hello World! I have obtained 129 episodes from online journalist Johnny Harris. I wanted to know if anyone is aware of a programmatic method I might be able to use, so that I can update all the files in Plex so that their filename is input as the episode title, and sort title. Preferably something in Python, as I’m pretty familiar with that language and have done several projects with it.

I assume this would be done via the Plex API, doing something with the metadata, but I do not know it well enough to say for sure. Here is a screenshot to show it in better detail

At the very least, I would appreciate some heads up on official documentation for the Plex metadata API, if such a thing exists.

Thanks for the suggestions.

Local metadata: https://support.plex.tv/articles/200220677-local-media-assets-movies/

Thanks for your reply, but that’s not what I’m looking for. My media is already named correctly, according to the Plex Naming Standards. I’ll keep searching for API reference material, thank you.

Local metadata != file naming. You can add poster files etc.

Right, I was looking for a programmatic way of dynamically updating/naming files.

Aside from editing the database directly (using python script) I don’t think there is any way to modify the metadata here using a script.

Using local metadata can have Plex ITSELF set the show’s metadata (including title) from files, but I believe it is limited to MP4 files.

So, I found the solution, in 3 parts:

Plex API Dev – I’m not sure if this is an official resource, but it helped out a ton

Plex Debug Logs – I renamed a few files manually and then inspected the logs to see what it was doing, and this also helped out a ton.

ChatGPT – I’m not gonna lie and say I did it all myself. ChatGPT was instrumental in helping me fix some syntax and make other suggetions. I, for one, accept and value our robot overlords, and welcome them with open arms.

Okay, so here’s how you do the thing … (my instructions apply to tv shows, but its probably similar for movies too)

Step 1:

Get the metadata ID

  • Plex WebUI > Library
  • Hover over the series and right-click to “copy link”
  • Paste the URL somewhere, and pull out the key:
  • http://10.0.0.1:32400/web/index.html#!/server/1234abcd5678efgh9012ijkl3456mnop7890qrst/details?key=%2Flibrary%2Fmetadata%2F39119&context=source%3Acontent.library~1~10
  • The part you’re interested in is the %2Flibrary%2Fmetadata%2F39119
    • aka: /library/metadata/39119
    • The id (for me) 39119 is for “Johnny Harris”

Step 2:

Craft a query URL

  • With that metadata id, prepare a URL string that we’ll use later

Step 3:

Write a script to get all the episodes

I realize that this script is slightly misleading as you’re using one ID just to fetch another, but as long as you understand that, I think you’ll be fine.

#!/usr/bin/env python3.11
import requests
import json

rating_key_url = "http://10.0.0.1:32400/library/metadata/39119/children"

headers = {
  'Accept': 'application/json',
  'Content-Type': 'application/json',
  'X-Plex-Token': '_fGHJt7-kLkk_T6hYTHL' #No, I'm not that dumb
}

rating_key_response = requests.get(url=rating_key_url, headers=headers)
rating_key_data = rating_key_response.json()

# Extract the ratingKey from the first item in the Metadata list
rating_key = rating_key_data["MediaContainer"]["Metadata"][0]["ratingKey"]

series_data_url = f"http://10.0.0.1:32400/library/metadata/{rating_key}/children"

series_data_response = requests.get(url=series_data_url, headers=headers)

series_data_json = json.dumps(series_data_response.json(), indent=2)
with open('data.json', 'w') as f:
    f.write(series_data_json)

Okay, so now you should have a file called data.json and it should look something like this.

Step 4:

Do the rename

Now you could either just do this as a one off, like I did my first time, and as a test – or I’m sure some brain-nugget on here will figure out a way to loop through it all … and I’m sure I’ll figure that out eventually too. Just takes time.

#!/usr/bin/env python3.11
import requests

episode_update_url = 'http://10.0.0.1:32400/library/sections/6/all' # '6' is the value of my 'tv.docs' library

params = {
    'type': '4', # I don't know what this is, or why its needed.
    'id': '39124', # This is the ratingId of the episode (['MediaContainer']['Metadata'][0]['ratingKey'])
    'includeExternalMedia': '1',
    'title.value': 'Why the US Sells Weapons to 103 Countries', # I typed this manually, but it'll be automated in the future
    'titleSort.value': 'Why the US Sells Weapons to 103 Countries'
}
headers = {
  'Accept': 'application/json',
  'Content-Type': 'application/json',
  'X-Plex-Token': '_fGHJt7-kLkk_T6hYTHL' #No, I'm not that dumb
}

episode_update_response = requests.put(url=episode_update_url, headers=headers, params=params)

print(episode_update_response.status_code) # Should get back '200'

And that’s the story of the time I ignored my actual job for an afternoon and just did a thing on Plex.

3 Likes

That… is beautiful. :smiling_face_with_tear:

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.