Importing M3U Playlists to Plex & PlexAmp
A working solution as of December 2025
This guide documents a reliable method for importing M3U playlists into Plex so they appear in PlexAmp and other Plex clients. This approach uses Plex’s hidden /playlists/upload API endpoint.
Background
For years, Plex users have been asking for native M3U playlist support. The forum thread “Can Plexamp read and use m3u playlists?” has been ongoing since 2018 with various workarounds proposed. This guide documents an approach that works reliably in late 2024/2025.
What You Need
- Plex Media Server running with a Music library
- Your Plex Token (authentication)
- Your Music Library Section ID
- M3U playlist files with relative paths to your audio files
- bash, curl, and python3 (for URL encoding)
Finding Your Plex Token
Your Plex token is stored in the Plex preferences file:
# Linux (typical location)
grep -oP 'PlexOnlineToken="\K[^"]+' \
"/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Preferences.xml"
# macOS
grep -oP 'PlexOnlineToken="\K[^"]+' \
"$HOME/Library/Application Support/Plex Media Server/Preferences.xml"
The token looks something like: xYz123ABCdef456GHI
Finding Your Music Library Section ID
Query your Plex server for library sections:
curl -s "http://127.0.0.1:32400/library/sections?X-Plex-Token=YOUR_TOKEN" | grep -oP 'key="\K[0-9]+'
Or visit http://127.0.0.1:32400/library/sections?X-Plex-Token=YOUR_TOKEN in a browser and look for your Music library’s key attribute. It’s typically a single digit like 1, 2, 3, or 4.
The Hidden Upload Endpoint
Plex has an undocumented endpoint for uploading M3U playlists:
POST /playlists/upload?sectionID={SECTION_ID}&path={URL_ENCODED_PATH}&X-Plex-Token={TOKEN}
Important notes:
- The
pathmust be the absolute filesystem path to the M3U file - The path must be URL encoded
- The M3U file must be readable by the Plex server
- Paths inside the M3U should be relative to the M3U file location
M3U Playlist Format
M3U files should use relative paths and start with #EXTM3U:
#EXTM3U
Artist/Album/01 - Track One.mp3
Artist/Album/02 - Track Two.mp3
Another Artist/Song.flac
Creating M3U Playlists
Here’s a bash function to create an M3U playlist for all audio files in a folder:
#!/bin/bash
AUDIO_EXTENSIONS="mp3|MP3|flac|FLAC|m4a|M4A|wav|WAV|ogg|OGG|opus|OPUS|wma|WMA|aac|AAC|ape|APE|aiff|AIFF"
create_playlist() {
local folder="$1"
local playlist_name="$2"
local playlist_path="$folder/${playlist_name}.m3u"
# Find all audio files recursively, sorted
audio_files=$(find "$folder" -type f 2>/dev/null | grep -iE "\.($AUDIO_EXTENSIONS)$" | sort)
if [ -n "$audio_files" ]; then
echo "#EXTM3U" > "$playlist_path"
while IFS= read -r file; do
# Convert to relative path
rel_path=$(realpath --relative-to="$folder" "$file")
echo "$rel_path" >> "$playlist_path"
done <<< "$audio_files"
file_count=$(echo "$audio_files" | wc -l)
echo "Created: $playlist_name ($file_count tracks)"
fi
}
# Example usage:
create_playlist "/path/to/music/Jazz" "Jazz"
Uploading to Plex
#!/bin/bash
PLEX_URL="http://127.0.0.1:32400"
PLEX_TOKEN="your_token_here"
SECTION_ID="4" # Your music library section ID
upload_to_plex() {
local playlist_path="$1"
local playlist_name="$2"
if [ -f "$playlist_path" ]; then
# URL encode the path
encoded_path=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$playlist_path', safe=''))")
curl -s -X POST \
"${PLEX_URL}/playlists/upload?sectionID=${SECTION_ID}&path=${encoded_path}&X-Plex-Token=${PLEX_TOKEN}"
echo "Uploaded: $playlist_name"
fi
}
# Example usage:
upload_to_plex "/path/to/music/Jazz/Jazz.m3u" "Jazz"
Deleting Old Playlists
When regenerating playlists, you may want to delete old uploaded versions first. Plex assigns each playlist a ratingKey. Uploaded playlists typically have high IDs (>200000), while original smart playlists have lower IDs.
#!/bin/bash
PLEX_URL="http://127.0.0.1:32400"
PLEX_TOKEN="your_token_here"
# Get all playlist IDs and delete those with high ratingKeys
curl -s "${PLEX_URL}/playlists?X-Plex-Token=${PLEX_TOKEN}" | \
grep -oP 'ratingKey="\K[0-9]+' | while read id; do
if [ "$id" -gt 200000 ]; then
curl -s -X DELETE "${PLEX_URL}/playlists/$id?X-Plex-Token=${PLEX_TOKEN}"
echo "Deleted playlist $id"
fi
done
Complete Regeneration Script
Here’s a complete script that regenerates and uploads playlists:
#!/bin/bash
#
# Regenerate all music playlists and upload to Plex
# Run this whenever you add or move music files
#
PLEX_URL="http://127.0.0.1:32400"
PLEX_TOKEN="your_token_here"
SECTION_ID="4" # Music library section ID
AUDIO_EXTENSIONS="mp3|MP3|flac|FLAC|m4a|M4A|wav|WAV|ogg|OGG|opus|OPUS|wma|WMA|aac|AAC|ape|APE|aiff|AIFF"
echo "=== Regenerating Music Playlists ==="
# Function to create a playlist
create_playlist() {
local folder="$1"
local playlist_name="$2"
local playlist_path="$folder/${playlist_name}.m3u"
audio_files=$(find "$folder" -type f 2>/dev/null | grep -iE "\.($AUDIO_EXTENSIONS)$" | sort)
if [ -n "$audio_files" ]; then
echo "#EXTM3U" > "$playlist_path"
while IFS= read -r file; do
rel_path=$(realpath --relative-to="$folder" "$file" 2>/dev/null || echo "$file")
echo "$rel_path" >> "$playlist_path"
done <<< "$audio_files"
file_count=$(echo "$audio_files" | wc -l)
echo " Created: $playlist_name ($file_count tracks)"
return 0
fi
return 1
}
# Function to upload a playlist
upload_to_plex() {
local playlist_path="$1"
local playlist_name="$2"
if [ -f "$playlist_path" ]; then
encoded_path=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$playlist_path', safe=''))")
curl -s -X POST "${PLEX_URL}/playlists/upload?sectionID=${SECTION_ID}&path=${encoded_path}&X-Plex-Token=${PLEX_TOKEN}" > /dev/null
echo " Uploaded: $playlist_name"
fi
}
# -----------------------------
# STEP 1: Create playlists for each folder you want
# -----------------------------
echo "--- Creating playlists ---"
# Add your music folders here
MUSIC_FOLDERS=(
"/path/to/music/Jazz"
"/path/to/music/Classical"
"/path/to/music/Rock"
)
for folder in "${MUSIC_FOLDERS[@]}"; do
if [ -d "$folder" ]; then
folder_name=$(basename "$folder")
create_playlist "$folder" "$folder_name"
fi
done
# -----------------------------
# STEP 2: Delete old uploaded playlists
# -----------------------------
echo "--- Cleaning up old Plex playlists ---"
curl -s "${PLEX_URL}/playlists?X-Plex-Token=${PLEX_TOKEN}" | grep -oP 'ratingKey="\K[0-9]+' | while read id; do
if [ "$id" -gt 200000 ]; then
curl -s -X DELETE "${PLEX_URL}/playlists/$id?X-Plex-Token=${PLEX_TOKEN}" > /dev/null
fi
done
echo " Removed old uploaded playlists"
# -----------------------------
# STEP 3: Upload fresh playlists
# -----------------------------
echo "--- Uploading to Plex ---"
for folder in "${MUSIC_FOLDERS[@]}"; do
if [ -d "$folder" ]; then
folder_name=$(basename "$folder")
playlist="${folder}/${folder_name}.m3u"
upload_to_plex "$playlist" "$folder_name"
fi
done
echo "=== Done! ==="
Troubleshooting
“localhost” doesn’t work
Use 127.0.0.1 instead of localhost in the Plex URL.
Playlists upload but are empty
- Ensure the M3U file uses relative paths from its own location
- Verify the audio files exist and are already indexed in your Plex library
- Check that Plex can read the M3U file (permissions)
Permission denied errors
Some folders may be read-only. The scripts handle this gracefully by continuing to the next folder.
Finding which playlists to keep
Original Plex smart playlists (like “Recently Added”, “Recently Played”) have low ratingKey IDs. Check your playlists before bulk deleting:
curl -s "http://127.0.0.1:32400/playlists?X-Plex-Token=YOUR_TOKEN" | \
grep -oP '(ratingKey|title)="[^"]+"' | paste - -
API Reference
| Endpoint | Method | Description |
|---|---|---|
/playlists?X-Plex-Token={TOKEN} |
GET | List all playlists |
/playlists/upload?sectionID={ID}&path={PATH}&X-Plex-Token={TOKEN} |
POST | Upload M3U playlist |
/playlists/{ratingKey}?X-Plex-Token={TOKEN} |
DELETE | Delete a playlist |
/library/sections?X-Plex-Token={TOKEN} |
GET | List library sections |
Automation
Add the regeneration script to a cron job to keep playlists updated:
# Run every Sunday at 3am
0 3 * * 0 /path/to/music/regenerate-playlists.sh >> /var/log/plex-playlists.log 2>&1
Or run manually whenever you add or reorganize music files.
This guide was created in December 2024 and confirmed working with Plex Media Server. The /playlists/upload endpoint is undocumented and may change in future Plex versions.