A DJ workflow: take ~9 reference playlists (Spotify + SoundCloud) → find everything on Beatport → fill the gaps with Bandcamp/vinyl → sort the rekordbox library by genre. All scripted, no clicking through 400 tracks by hand.
- Claude Code with the Chrome extension for browser automation
- Beatport API v4 (undocumented, but accessible with your session token)
- SoundCloud api-v2 (hydration data + scraped client_id)
- pyrekordbox for reading/writing the encrypted rekordbox master.db
- Discogs API + marketplace scraping for vinyl-only tracks
- Bandcamp for the long tail
Beatport's API doesn't have public docs but it's easy to talk to once you're logged in:
// From any beatport.com tab:
const session = await fetch('/api/auth/session').then(r => r.json());
const token = session.token.accessToken;
// Now hit the real API:
const r = await fetch('https://api.beatport.com/v4/my/playlists/?per_page=100', {
headers: { Authorization: 'Bearer ' + token }
});Useful endpoints:
GET /v4/my/playlists/— list your playlistsGET /v4/my/playlists/{id}/tracks/— track list (paginated, follow.next)POST /v4/my/playlists/{id}/tracks/with{track_id: N}— addDELETE /v4/my/playlists/{id}/tracks/{playlist_track_id}/— removeGET /v4/catalog/search/?q=Artist+Title&type=tracks— search
SoundCloud embeds the playlist tracklist in a global variable:
// From any soundcloud.com playlist page:
const data = window.__sc_hydration.find(h => h.hydratable === 'playlist').data;
const trackIds = data.tracks.map(t => t.id);Then batch-fetch metadata via api-v2 (you'll need to scrape client_id from their JS bundle — /client_id:"([a-zA-Z0-9]{32})"/).
Rekordbox 6 encrypts its SQLite db with SQLCipher. pyrekordbox handles the key for you:
from pyrekordbox import Rekordbox6Database
db = Rekordbox6Database()
tracks = list(db.get_content())
for t in tracks:
print(t.Title, t.Artist.Name, t.Genre.Name, t.BPM)It also supports writing — db.create_playlist(name, parent=folder), db.add_to_playlist(pl, track), db.commit(). Rekordbox must be closed for writes to stick.
Once you can read the db, sorting 250 tracks into genre playlists is a one-shot script:
from collections import defaultdict
buckets = defaultdict(list)
for t in db.get_content():
g = t.Genre.Name if t.Genre else 'Other'
buckets[g].append(t)
for name, tracks in buckets.items():
pl = db.create_playlist(name, parent=genre_folder)
for t in tracks:
db.add_to_playlist(pl, t)
db.commit()Instagram's saved-collection page exposes each post's og:title with the caption. Fetch each post URL and regex for releases / tracks names mentioned:
const html = await fetch(postUrl).then(r => r.text());
const title = html.match(/<meta property="og:title" content="([^"]+)"/)[1];Then run the extracted artist/track pairs through the Beatport search.
- Drop playlist URLs into the agent (Spotify / SoundCloud)
- Scrape tracklists via the methods above
- Fuzzy-match to Beatport with the search API (normalize punctuation, try artist+title variants)
- Flag
⚠️ low-confidence matches — these bite later when you actually listen - Dedupe against rekordbox so you don't buy what you own
- Gap-fill with Bandcamp for anything still missing (Bandcamp Discover search or direct label page)
- Sort everything by genre in rekordbox once downloaded
- Fuzzy matching lies. Generic titles like "Good Times" or "Delight" silently match wrong tracks. Always listen before committing to a set. I ended up removing 4 wrong matches after downloading.
- Beatport's Cloudflare blocks
WebFetch— use browser-sidefetch()with cookies/token instead. - JWTs get redacted by Claude's output filters. Store tokens in
window._tokand operate same-tab instead of trying to export them. - Rekordbox's master.db is locked when RB is open — writes silently fail. Quit RB, then run.
- FAT32 for DJ USB sticks — works on every Pioneer CDJ/XDJ. HFS+ does not.
- Chrome extension that wraps all this so non-coders can do it
- Auto-fill Bandcamp wishlist from a list of unfound tracks
- Track price-drops on Beatport for stuff you flagged but didn't buy
- Beatport playlists (split by source): 5 playlists, ~300 tracks total
- Bandcamp recoveries: 10 tracks across 9 small labels (~$20)
- Rekordbox Genre folder: 10 auto-sorted playlists (Deep House, House, Minimal/Deep Tech, Tech House, Electronica, Indie Dance, Techno, UK Garage, Nu Disco, Other)
Built with Claude Code. The whole thing ran in one long conversation — the agent scripted Chrome, hit the APIs, wrote the pyrekordbox code, and kept track of everything in a markdown file along the way.