Skip to content

tomasodehnal/spotifyexport

 
 

Repository files navigation

The only modifications in this fork are the [data usage examples](#using-the-data) in this readme file.

Export your personal Spotify data: playlists, saved tracks/albums/shows, etc. as JSON.

Setting up

  1. The easiest way is pip3 install --user git+https://github.com/karlicoss/spotifyexport.

    Alternatively, use git clone --recursive, or git pull && git submodule update --init. After that, you can use pip3 install --editable ..

  2. To use the API, you need to create a new app on Spotify for Developers

    For redirect_uri: you can pick pretty much anything, e.g. https://github.com. After that you’ll get client_id and client_secret.

  3. On the first script run, you’ll be prompted to approve the script access.

    Once approved, the token is saved to cache_path (will be created if doesn’t exist). After that you won’t need to enter the password again as long as you pass the same cache_path.

Exporting

Usage:

Recommended: create secrets.py keeping your api parameters, e.g.:

client_id = "CLIENT_ID"
client_secret = "CLIENT_SECRET"
redirect_uri = "REDIRECT_URI"
cache_path = "CACHE_PATH"

After that, use:

python3 -m spotifyexport.export --secrets /path/to/secrets.py > output.json

That way you type less and have control over where you keep your plaintext secrets.

Alternatively, you can pass parameters directly, e.g.

python3 -m spotifyexport.export --client_id <client_id> --client_secret <client_secret> --redirect_uri <redirect_uri> --cache_path <cache_path> > output.json

However, this is verbose and prone to leaking your keys/tokens/passwords in shell history.

I highly recommend checking exported files at least once just to make sure they contain everything you expect from your export. If not, please feel free to ask or raise an issue!

API limitations

  • you might want to do a GDPR export in addition, just in case
  • “Recently played” API endpoint **only returns the 50 most recent tracks**, which makes it kind of useless unless you export the data every hour or so.

    If you care about them, might be a good idea to connect Spotify to Last.FM.

    GPDR export has more tracks, but also seems incomplete (e.g. my data is missing first few years).

Using the data

Note: requires the jq tool.

Albums

Get a list of albums in CSV format

jq -r '.saved_albums[].album | [(.artists | map(.name) | join(";")), .name] | @csv' output.json > albums.csv

Output:

"KOMPROMAT;Rebeka Warrior;Vitalic","ONLY IN YOUR ARMS (Live)"
"Sync24","Comfortable Void"

Get a list of albums in JSON format, with tracklist

jq '[(.saved_albums[].album | {album_type: .album_type, artists: (.artists | map(.name)), name: .name, releas_date: .release_date, tracks: [.tracks.items[] | {track_number: .track_number, name: .name}]})]' output.json > albums.json

Output:

[
  {
    "album_type": "single",
    "artists": [
      "KOMPROMAT",
      "Rebeka Warrior",
      "Vitalic"
    ],
    "name": "ONLY IN YOUR ARMS (Live)",
    "releas_date": "2025-10-08",
    "tracks": [
      {
        "track_number": 1,
        "name": "ONLY IN YOUR ARMS - Live"
      },
      {
        "track_number": 2,
        "name": "ONLY IN YOUR ARMS"
      }
    ]
  },
  {
    "album_type": "album",
    "artists": [
      "Sync24"
    ],
    "name": "Comfortable Void",
    "releas_date": "2012-06-21",
    "tracks": [
      {
        "track_number": 1,
        "name": "Comfortable Void"
      },
      {
        "track_number": 2,
        "name": "Inadvertent"
      },
      {
        "track_number": 3,
        "name": "Dance of the Droids"
      },
      {
        "track_number": 4,
        "name": "1n50mn14"
      },
      {
        "track_number": 5,
        "name": "Nanites"
      },
      {
        "track_number": 6,
        "name": "Sequor"
      },
      {
        "track_number": 7,
        "name": "Something Something"
      },
      {
        "track_number": 8,
        "name": "Oomph"
      },
      {
        "track_number": 9,
        "name": "Wake (Live Edit)"
      },
      {
        "track_number": 10,
        "name": "There Is No Spoon"
      }
    ]
  }
]

Playlists

Get a list of playlists with tracks in JSON

jq '[.playlists[] | {name: .name, description: .description, owner_uri: .owner.uri, owner_display_name: .owner.display_name, tracks: [(.tracks[].track | {artists: (try (.artists | map(.name) | join(";"))), name: .name})] }]' output.json  > playlists.json

Output:

[
  {
    "name": "Music for 2am: Session 1 (Side A)",
    "description": "Focus up. Or wind down. ",
    "owner_uri": "spotify:user:killyourfm",
    "owner_display_name": "killyourfm",
    "tracks": [
      {
        "artists": "The Inner Banks",
        "name": "Electric"
      },
      {
        "artists": "B. Fleischmann",
        "name": "Composure"
      },
      {
        "artists": "Working for a Nuclear Free City",
        "name": "The Tape"
      },
      {
        "artists": "Nightmares On Wax",
        "name": "You Wish"
      },
      {
        "artists": "Klub Rider",
        "name": "Buleria Del Alba"
      },
      {
        "artists": "Spiffy Man",
        "name": "Time for Change"
      },
      {
        "artists": "Tycho",
        "name": "Daydream"
      },
      {
        "artists": "Air",
        "name": "La femme d'argent"
      },
      {
        "artists": "Blackmill",
        "name": "Miracle"
      }
    ]
  },
  {
    "name": "Music For 2am: Session 1 (Side B)",
    "description": "Focus up. Or wind down. ",
    "owner_uri": "spotify:user:killyourfm",
    "owner_display_name": "killyourfm",
    "tracks": [
      {
        "artists": "Radiohead",
        "name": "Hunting Bears"
      },
      {
        "artists": "Exotic Animal Petting Zoo",
        "name": "A Balloon Enters Kyoto City"
      },
      {
        "artists": "The Album Leaf",
        "name": "Red-Eye"
      },
      {
        "artists": "The Deadbeats",
        "name": "Loafin'"
      },
      {
        "artists": "Cloudkicker",
        "name": "It's Inside Me, and I'm Inside It"
      },
      {
        "artists": "Groove Armada",
        "name": "Edge Hill"
      },
      {
        "artists": "Emancipator",
        "name": "With Rainy Eyes"
      },
      {
        "artists": "Massive Attack",
        "name": "Exchange"
      },
      {
        "artists": "M83",
        "name": "Steve McQueen"
      }
    ]
  }
]

About

Export your personal Spotify data: playlists, saved tracks/albums/shows, etc. as JSON

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 91.9%
  • Shell 8.1%