Auto-Tag Your DJ Library with beets + Beatport (macOS & Windows Guide)
SetFlow's harmonic mixing, energy curves, and genre scoring are only as accurate as the tags inside your music files. Rekordbox reads those tags before it does anything else — so if your Artist, Title, Genre, Label, or Release Year are wrong, every step downstream is wrong too. This guide walks you through fixing your entire library automatically using two free open-source tools: beets and the beets-beatport4 plugin. It assumes no prior command-line experience and covers both macOS and Windows.
Why You Should Bother
If you bought your music from Beatport, Bandcamp, Juno or anywhere else, the tags you got are inconsistent. Some tracks have full metadata. Some are just Track 03.mp3. Genres are spelled five different ways (Tech-House, tech house, TechHouse). Keys are missing. Labels are blank. Promo copies have garbage in the comments.
Once that data hits Rekordbox, the rot spreads:
- Your genre column becomes useless for filtering or smart crates.
- Tracks group oddly when you sort by Artist or Album.
- The 15% genre score in SetFlow can't boost compatible tracks because the genre strings don't match.
- Search inside Rekordbox or SetFlow misses tracks because the typed metadata doesn't match what you remember.
Beets fixes this by reading every file in your library, looking each track up in an online database, and writing back clean, consistent tags — in one pass, across thousands of files.
What These Two Tools Actually Do
beets is a command-line music library manager. You point it at a folder of music; it identifies every track, fetches authoritative metadata, embeds it back into the audio files (ID3 tags for MP3, Vorbis comments for FLAC, atoms for M4A), and optionally renames and re-files them into a clean folder structure like Artist/Album/01 - Track.flac.
By default beets uses MusicBrainz — an open music database that's excellent for albums, indie, rock, jazz, classical, and most non-club music. It is, however, weaker on electronic dance music. Many DJ releases — especially singles, EPs, white labels and Beatport-exclusive edits — aren't in MusicBrainz at all.
beets-beatport4 is a community plugin that adds Beatport as a metadata source. Beatport has the most accurate metadata for electronic music on the planet: correct genre taxonomy (Tech House, Melodic Techno, Afro House and so on as Beatport defines them), key, label, catalog number, release date, and a 60-second preview URL. Once installed, beets will offer Beatport matches first for any track it recognises.
Heads-up: Beatport killed their v3 API. The stock beatport plugin bundled with beets no longer works. You must install beets-beatport4 separately — that's the whole reason this plugin exists.
Before You Start: Back Up Your Library
Beets modifies your audio files in place. It can also move and rename them. If you have years of irreplaceable promos, edits, and unreleased tracks, do not skip this step.
- Copy your entire music folder to an external drive, or zip it and drop it in iCloud / OneDrive / Dropbox.
- Export your Rekordbox collection as XML (File → Export Collection in xml format) and keep it somewhere safe. This is your fallback if anything goes sideways.
- Optionally, start with a single album or folder of 10–20 tracks the first time you run beets — not your whole 5,000-track library.
Installation on macOS
1. Install Homebrew (if you don't already have it)
Homebrew is the standard package manager for macOS. Open the Terminal app (press Cmd + Space, type “Terminal”, hit Enter) and paste this command, then press Enter:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"It will ask for your Mac password and take a few minutes. When it finishes, you may need to follow its instructions to “add Homebrew to your PATH” — just copy and paste the two commands it prints out.
2. Install Python and pipx
pipx is a tool that installs Python applications into isolated environments so they don't conflict with anything else on your system. It's the recommended way to install beets.
brew install pipx
pipx ensurepathClose your Terminal window and open a new one (so the PATH change takes effect).
3. Install beets and the Beatport plugin
pipx install beets
pipx inject beets beets-beatport4 pylast requestsThe first line installs beets itself. The second injects the Beatport plugin and the two extra dependencies our config uses: pylast (Last.fm client, needed by the lastgenre plugin) and requests (HTTP client used by several plugins).
Verify it worked:
beet --versionYou should see something like beets version 2.x.x. Skip to Configure beets.
Installation on Windows
1. Install Python 3.12
Important: Do not install “the latest” Python. As of 2026 several beets dependencies (lap, numpy) don't yet ship pre-built wheels for Python 3.14, which results in NumPy ABI mismatch errors when you run beet --version. Install Python 3.12 specifically.
- Go to python.org/downloads/windows.
- Scroll down to “Looking for a specific release?” and find the latest Python 3.12.x entry. Click Download, then on the release page download the Windows installer (64-bit).
- Run the installer. Critical: on the first screen, tick the box that says “Add python.exe to PATH”, then click Install Now.
Open PowerShell (press the Windows key, type “PowerShell”, hit Enter) and verify:
python --version
pip --versionBoth should print version numbers. If you get “command not found”, the PATH checkbox wasn't ticked — uninstall Python, reinstall, and tick the box this time.
2. Install pipx
python -m pip install --user pipx
python -m pipx ensurepathClose PowerShell and open a fresh window.
3. Install beets and the Beatport plugin
pipx install beets
pipx inject beets beets-beatport4 pylast requestsVerify:
beet --versionYou should see beets version 2.x.x. If you instead see a long traceback ending in numpy.core.multiarray failed to import, you accidentally installed Python 3.14 — uninstall it from Settings → Apps, install Python 3.12 as described above, run pipx uninstall beets, then redo the pipx install steps.
Configure beets
Beets reads its settings from a YAML file. Open it for editing:
beet config -eThis will create the file the first time and open it in your default text editor. On macOS it lives at ~/.config/beets/config.yaml; on Windows at %APPDATA%\beets\config.yaml. Replace whatever's there with the following, then change the two paths to point at your actual music folders.
macOS example:
directory: /Users/yourname/Music/DJ
library: /Users/yourname/Music/DJ/beets.db
plugins:
- beatport4
- fetchart
- embedart
- lastgenre
- scrub
import:
copy: yes
move: no
write: yes
beatport4:
art: yes
art_width: 500
singletons_with_album_metadata:
enabled: yes
lastgenre:
auto: yes
source: track
count: 1
paths:
default: $albumartist/$album%aunique{}/$track $title
singleton: Non-Album/$artist/$title
comp: Compilations/$album%aunique{}/$track $titleWindows example:
directory: C:/Users/yourname/Music/DJ
library: C:/Users/yourname/Music/DJ/beets.db
plugins:
- beatport4
- fetchart
- embedart
- lastgenre
- scrub
import:
copy: yes
move: no
write: yes
beatport4:
art: yes
art_width: 500
singletons_with_album_metadata:
enabled: yes
lastgenre:
auto: yes
source: track
count: 1
paths:
default: $albumartist/$album%aunique{}/$track $title
singleton: Non-Album/$artist/$title
comp: Compilations/$album%aunique{}/$track $titleTwo things to notice:
copy: yes+move: nomeans beets copies tracks into the clean folder structure underdirectory:while leaving your originals untouched. Once you're confident, you can flip tomove: yes.write: yesembeds the new tags into the audio files themselves — not just into beets' own database. This is what Rekordbox will read.
Save the file and close the editor.
Connect beets to Beatport
beets-beatport4 has two ways to log in. The easy one stores your Beatport username and password in the config file in plain text. If that's acceptable for your setup, append this to your config:
beatport4:
art: yes
art_width: 500
singletons_with_album_metadata:
enabled: yes
username: your-beatport-email@example.com
password: yourBeatportPasswordPrefer not to keep your password on disk? Use the browser-token method instead:
- Run your first import (the next section). When it prompts for a token, leave the terminal open.
- In your browser, open api.beatport.com/v4/docs and log in.
- Open browser DevTools (
F12on Windows,Cmd+Opt+Ion macOS), go to the Network tab, and look for a request toauth/o/token/. - Right-click that request → Copy response.
- Paste the JSON into the beets terminal prompt, or save it as
beatport_token.jsonnext to your config file (beet config --pathstells you where that is).
Tokens expire periodically — beets will prompt you again when they do.
Your First Import
With everything installed and configured, run beets against a small folder first. Replace the path with one that points at a single album or a handful of tracks you don't mind experimenting on.
macOS:
beet import ~/Music/Inbox/test-albumWindows:
beet import "C:\Users\yourname\Music\Inbox\test-album"beets will scan the folder, identify the tracks, and show you a list of candidate matches ranked by confidence. For each match you'll see options like:
- A — apply this match (the usual choice when the top result looks right).
- S — skip this album.
- U — use as-is (keep current tags, don't change them).
- T — as Tracks (treat each file as a singleton instead of an album).
- G — group albums (when one folder contains tracks from multiple releases).
- E — enter search manually if nothing matches.
- B — abort the import.
PS> beet import -s "C:\Users\you\Music\PioneerDJ\Organic House" Tagging track: Lane 8 - Sunrise (Original Mix) From: Beatport (Similarity: 98.4%) Genre: Melodic House & Techno Key: 8A BPM: 122 Label: Anjunadeep [A]pply, More candidates, Skip, Use as-is, Enter search, enter Id, aBort? █
What a single track match looks like. The green fields are what beets will write; press A to apply.
If a candidate from beatport4 appears at the top, that's usually what you want for electronic music. If you only see MusicBrainz candidates, the track isn't on Beatport — pick the best MusicBrainz match or skip and tag manually later.
For loose folders full of singles (which is most DJ libraries), tell beets upfront to treat everything as singletons. It skips the album-matching dance entirely:
beet import -s ~/Music/Inbox/singlesThat interactive flow is fine for one album. For a real library of thousands of tracks, clicking A four thousand times is misery — so don't. The next section is the one that matters.
Working With Large Libraries (4,000+ Tracks)
The trick is quiet mode (-q). In quiet mode beets automatically applies any match it's confident about and never prompts you; anything it's unsure about is skipped (and logged) rather than stopping the whole import to ask. Combine it with -s (singletons) for a DJ library of loose tracks, and -l to write a log of everything that got skipped:
macOS:
beet import -qs -l ~/beets-skipped.log ~/Music/DJ-InboxWindows:
beet import -qs -l C:\Users\yourname\beets-skipped.log "C:\Users\yourname\Music\DJ-Inbox"-q— quiet: confident matches tagged automatically, no prompts.-s— singletons: each track judged on its own (right for purchased singles and EPs).-l <file>— log: records every skipped or uncertain track so you know what didn't match.
PS> beet import -qs -l skipped.log "C:\Users\you\Music\PioneerDJ" Lane 8 - Sunrise ✓ tagged (98.4%) Yotto - The Owls ✓ tagged (96.1%) unknown_artist - bootleg_edit ╲ skipped (low match) Ben Böhmer - Breathing ✓ tagged (97.8%) ... 3,910 more ... Imported 3,914 tracks. 117 skipped → see skipped.log
Condensed view. Quiet mode auto-applies confident matches and logs the rest — you don't touch the keyboard.
The two-pass strategy
This is the practical way to clear thousands of tracks without losing your mind:
- Pass 1 — bulk. Run the quiet command above. For a Beatport-bought library, most tracks match strongly and get tagged hands-off in a single pass. Walk away and make a coffee.
- Pass 2 — mop up. Open
beets-skipped.logto see what didn't match, then re-run without-qto handle just the leftovers interactively:
Tracks already imported in pass 1 are detected as duplicates and skipped, so you only get prompted for the genuine stragglers.beet import -s ~/Music/DJ-Inbox
beet import -qs -l skipped.log /your/musicbeets tags every confident match automatically — no prompts. Walk away.
Clean tags written straight into the files. Done.
The handful of uncertain matches, logged for review.
The skipped.log tracks flow into the second pass ↓
beet import -s /your/musicSame command without -q. Already-tagged tracks are skipped as duplicates, so only the stragglers prompt you.
The two-pass strategy: bulk-tag what's certain, hand-review only what isn't.
Tuning how aggressive auto-matching is
Two config settings control how much quiet mode tags on its own. Add them to your config.yaml:
import:
quiet_fallback: skip # when unsure in quiet mode, skip rather than guess
match:
strong_rec_thresh: 0.10 # default 0.04 — raise to auto-accept looser matches
medium_rec_thresh: 0.25strong_rec_thresh is the key dial. It's a distance (lower means stricter), and in quiet mode any match below it is applied automatically. The default 0.04 only auto-applies near-perfect matches; bumping it to 0.10 lets beets tag far more of your library without asking — at the cost of occasionally accepting a slightly-off match. Start at 0.10, run a pass, spot-check the results in Rekordbox, and adjust from there.
Keep quiet_fallback: skip, not asis. skip leaves uncertain tracks untouched for your pass-2 review; asis would import them with their existing messy tags and mark them done — quietly baking the mess into your library.
Stripping Junk Tags
Downloaded music is full of metadata cruft: store watermarks, encoder strings, stale comment fields, promo tags like “downloaded from…”. beets can strip all of it. There are two tools, depending on whether you want a total wipe or surgical removal.
scrub — the clean slate (you already have this)
The scrub plugin is already in the config from earlier, and its auto option defaults to yes — so on every import beets is already stripping every tag from the file and writing back only its own clean, beets-managed tags. That's why junk disappears automatically. To scrub files you've already imported:
beet scrub artist:"Some Artist" # any query; omit the query to scrub everythingAdd -W to leave files completely bare with no tags restored at all (rarely what you want). One caution: scrub trusts the beets database, so any tag you edited outside beets and never synced back will be lost.
zero — surgical field removal
When you only want to blank specific fields, use the zero plugin. It isn't enabled by default — add zero to your plugins list. Its best feature is conditional stripping: blank a field only when it matches a pattern. For example, nuke comments that contain promo spam but leave genuine comments alone:
plugins:
- beatport4
- scrub
- zero # add this
zero:
fields: comments images # blank these
comments: [www, http, promo, 'ripped by', 'follow me'] # ...but comments only if they match
update_database: yesWith a regex list, beets blanks the field only on a match; without one, the field is always nulled. zero runs automatically on import (except for “as-is” imports), or you can run it manually over your existing library:
beet zero # apply to everything; or add a query to target tracksFor a DJ library: keep scrub on for the clean-slate baseline, and add zero with a comments regex if you've got download watermarks cluttering your comment field. Remember the comments field also feeds SetFlow's energy hints, so a clean comment field is worth the effort.
Refresh Rekordbox
beets writes the new tags directly into your audio files, but Rekordbox keeps its own copy of every track's metadata in its database. You have to tell Rekordbox to re-read the files.
- In Rekordbox, select the tracks you re-tagged (Cmd/Ctrl+A for everything).
- Right-click → Reload Tag.
- If files were moved (i.e. you set
move: yes), Rekordbox will show them in red as “missing”. Right-click any one → Relocate, point at the new beets directory, and Rekordbox will re-link the whole batch automatically. - Right-click the tracks again → Analyze Track to re-run BPM/key analysis on the freshly-tagged files. This is optional — Rekordbox's analysis is generally fine — but if you imported keys from Beatport, you can also enable Preferences → Analysis → Key → Use ID3 tag if available to keep Beatport's key reading.
Bring It Into SetFlow
Now that Rekordbox sees clean, consistent metadata:
- In Rekordbox: File → Export Collection in xml format.
- In SetFlow: Library → Import Library → Rekordbox, then drop the XML in.
The genre normalisation table in our Rekordbox tagging guide shows how SetFlow maps the most common Beatport genre strings to its internal genre families. Because beets-beatport4 uses Beatport's canonical strings (always exactly Tech House, never tech-house or Tech-house), the mapping rate jumps significantly — which directly improves your energy curve and harmonic mixing results.
Are There Better Solutions?
Honest answer: beets is the most powerful free option, but it isn't the easiest. If the command line gives you hives, here are the alternatives, ranked by how DJ-focused they are.
If you're a working DJ with hundreds of dollars riding on every gig and you hate terminals, Lexicon is probably the right answer — it's purpose-built for our workflow, and the round-trip features across Rekordbox / Serato / Traktor are genuinely excellent. If you mostly care about getting keys right and your other tags are already clean, Mixed In Key is the gold standard.
But beets + beats-beatport4 will take a library of 5,000 chaotic tracks and return you a library of 5,000 consistently-tagged tracks for $0 — with the trade-off that you have to learn five terminal commands.
Quick Reference
The five commands you'll actually use
beet config -e— open your config filebeet import /path/to/folder— tag an album folder interactivelybeet import -qs -l skipped.log /path— bulk auto-tag a whole library, logging skips (the big-library command)beet scrub /path-or-query— strip junk tags and rewrite clean beets metadatabeet ls genre:"Tech House"— list every track in your beets library tagged Tech Housebeet modify -a artist:"Old Name" artist="New Name"— bulk rename / fix a tag across many tracks
Spend an evening on the install + first import. The next time you drop a new promo pack into your inbox folder, you'll run one command, click A twenty times, and your library is clean — ready to be re-imported into Rekordbox and turned into a better SetFlow set.
Ready to build better sets?
Import your Rekordbox, Traktor, or Serato library and generate perfectly mixed DJ sets in seconds.
Try SetFlow Free