Skip to main content

Apple Music logo

Gamdl
Glomatico's Apple Music Downloader

PyPI version Python versions License Downloads

Gamdl is a command-line app for downloading Apple Music songs, albums, playlists, music videos, and uploaded videos. It combines an interactive terminal interface with configurable codecs, metadata tagging, and library organization.

Join our Discord server: https://discord.gg/aBjMEZ9tnq

Contents

✨ Features

  • 🎵 Music downloads — Songs, albums, playlists, artists, and your personal Apple Music library.
  • 🎬 Video downloads — Music videos and uploaded/post videos, with quality and stream selection.
  • 🎧 Multiple codecs — AAC, ALAC, Dolby Atmos, H.264, H.265, and more, when available for the selected media.
  • 📝 Lyrics and metadata — Embedded tags, artwork, and optional lyrics and playlist files.
  • 🖥️ Interactive interface — Full-screen selection menus and live download progress.
  • 🗂️ Library tools — Customizable paths, an optional SQLite media index, and an offline organizer.

📋 Prerequisites

  • Python 3.10 or newer. A Rust toolchain is also needed if your platform must build Gamdl's native extension from source.
  • An Apple Music account. An active subscription is generally required to access subscription playback streams.
  • An authentication method: Wrapper, browser cookies, or a Media User Token.
  • A compatible DRM backend for protected streams. Install the appropriate optional dependency as described below.

Codec and resolution availability varies by track, account, authentication method, and DRM capabilities.

📦 Installation

Recommended: Install Gamdl with the Widevine extra from PyPI. It includes a built-in Widevine L3 device, so you don't need to provide a separate device file for standard downloads:

python -m pip install "gamdl[widevine]"

If you prefer PlayReady, install its extra instead:

python -m pip install "gamdl[playready]"

PlayReady does not include a device. You must supply your own compatible .prd file using --device-path or auth.device_path in your configuration. For videos above 1080p, see Video Codec and Resolution.

The base package can also be installed with python -m pip install gamdl, but protected streams require a supported DRM setup or a compatible wrapper. After installation, check the CLI with:

gamdl --help

If a prebuilt wheel is not available for your platform, installing from source requires Rust and the native build dependencies.

🚀 First Run

After installing Gamdl, you can start a download right away:

gamdl rip "https://music.apple.com/us/album/never-gonna-give-you-up-2022-remaster/1624945511?i=1624945512"

If this is your first run, Gamdl will guide you through any settings you haven't configured yet:

  1. Authentication: Choose Wrapper, Cookies, or Media User Token. Follow the on-screen instructions to connect your Apple Music account. See Authentication for details about each method.
  2. Output directory: Choose where your downloads will be saved. Gamdl suggests your operating system's Music folder; press Enter to accept it or enter a different path.

Once setup is complete, Gamdl begins downloading and displays progress in the terminal. It saves your choices in ~/.gamdl/config.yml, so these prompts won't appear again unless you clear the corresponding settings.

You can change authentication later with gamdl auth, or override the download folder for one command with --output-dir PATH. For scripts and other non-interactive environments, configure authentication and the output directory beforehand; the setup wizards require an interactive terminal.

🚀 Usage

Gamdl uses subcommands. Run gamdl --help for the command list or gamdl <command> --help to see its options.

Download URLs (rip)

Download an Apple Music song, album, playlist, music video, or artist URL:

gamdl rip "https://music.apple.com/us/album/never-gonna-give-you-up-2022-remaster/1624945511?i=1624945512"

Multiple URLs can be downloaded in one invocation:

gamdl rip "<first Apple Music URL>" "<second Apple Music URL>"

Catalog and library sharing links, including Apple Music Classical links, are supported where their corresponding media can be resolved. For artist links, Gamdl opens the artist browser or you can specify categories automatically:

gamdl rip "<artist URL>" --artist-auto-select main-albums,music-videos

Add --select to choose album or playlist tracks interactively instead of using the default automatic selection.

ISRC Input

Download a song or music video using its 12-character International Standard Recording Code (ISRC) without looking up an Apple Music sharing URL:

gamdl rip isrc:USUM71703085

isrc: queries both the song and music-video catalogs using Apple's filter[isrc] API. An ISRC can identify multiple catalog entries; if the lookup returns more than one match, Gamdl opens its existing selection interface so you can choose which to download. A single match is downloaded directly. Multiple matches require an interactive terminal.

The lookup uses the current authenticated storefront. Apple's response may reference alternate releases in meta.filters.isrc; for now Gamdl resolves only the returned data matches, not every alternate release ID. Empty results mean no matching resource was returned in that storefront.

Browse Your Library (library)

Browse your saved albums, playlists, songs, and music videos:

gamdl library

For automatic category selection without opening the browser:

gamdl library --library-auto-select albums,playlists

Search the Apple Music catalog and interactively select results:

gamdl search "Thriller" --type song

Switch between the authenticated Apple Music catalog search (default) and Apple's public iTunes Search API:

gamdl search "Caravan Palace" --search-api itunes
gamdl search "Caravan Palace" --search-api apple-music

Set the backend in YAML to make iTunes the default:

search:
  api: itunes

Override it for a single command with --search-api. iTunes search supports songs, music videos and albums, but not uploaded videos or playlists. Its public Search API returns up to 200 results per category; Gamdl displays those in local pages without relying on undocumented iTunes pagination. Selected items are then resolved using authoritative Apple Music catalog metadata before download. Apple documents an approximate iTunes Search API limit of 20 requests/minute; changing backends doesn't remove throttling limits. Selecting an album expands its tracks through the existing Apple Music album resolver:

gamdl search "Thriller" --search-api itunes --type album

Apple Music search also offers Playlists (editorial and external curators) and User playlists (public, user-shared playlists). The latter are identified by the catalog's playlistType: user-shared field; Apple's search index may not return any for a particular term/storefront. Selecting a playlist expands its tracks for download, just like opening a playlist link:

gamdl search "Michael Jackson" --type playlist
gamdl search "Michael Jackson" --type user-playlist

The Apple Music search endpoint does not accept uploaded-videos as a search type (HTTP 400). Downloading a supported uploaded-video URL directly with gamdl rip remains available.

Use --feeling-lucky with --type to select the first result automatically:

gamdl search "Thriller" --type song --feeling-lucky

Authentication (auth)

Authentication is configured automatically during the first run if you haven't selected a method yet. To change your method later, run:

gamdl auth

The wizard validates your selected method and saves it to the YAML configuration.

Wrapper

Connect to a running Wrapper v2 service. Gamdl can use its authenticated session and compatible playback/decryption features. The default wrapper URL is http://127.0.0.1.

Cookies

Export your cookies from Apple Music in Netscape cookies.txt format while signed in. The file must contain the media-user-token cookie. You can use a browser extension such as Export Cookies for Firefox or Get cookies.txt LOCALLY for Chromium.

Media User Token

Provide your Apple Music media-user-token directly through the wizard. Treat the token and your cookies file as passwords; never post them in issues or logs.

Advanced authentication settings are described under Configuration.

Maintain the Media Database (database)

The optional SQLite index stores information about downloaded files. You can inspect, scan, and prune its records:

gamdl database info
gamdl database scan --dry-run
gamdl database scan
gamdl database prune --dry-run

scan discovers supported local files using their embedded catalog IDs. prune removes database records for missing files, not media files; it asks for confirmation unless --yes is supplied.

Organize Existing Files (organize)

Organize local media using its embedded tags and your configured filename templates:

gamdl organize --dry-run
gamdl organize

The organizer can update database paths and relative M3U playlist references. It avoids overwriting occupied destinations. Review the dry run first, especially when changing templates.

When media paths change, organize repairs their references inside existing .m3u8 playlists without changing playlist names or metadata headers. For an already-organized library, use gamdl organize --playlists-only (or add --dry-run to preview path repairs).

Sync Apple Music Playlists (sync playlists)

Reconcile existing local .m3u8 playlists with their Apple Music catalog IDs, including new, removed, and reordered tracks:

gamdl sync playlists --dry-run
gamdl sync playlists --dry-run --verbose
gamdl sync playlists
gamdl sync playlists --no-download
gamdl sync playlists --playlist 'Playlists/Apple Music/Oliver Tree_ essenciais.m3u8'

Gamdl matches tracks by catalog ID using the local SQLite index and embedded media tags. The default output shows a concise table of only playlists that need attention; use --verbose to show all playlists and individual added/removed tracks. After fetching complete playlist listings, synchronization reports the number of unique missing tracks, then downloads them with the same per-track progress bars as rip and an overall completed/total bar. It respects download.concurrent_downloads (parallel tracks) and download.segment_concurrency (media segment requests per track), reusing shared tracks across playlists. Missing tracks are downloaded with your configured codec settings unless --no-download is used. Removed playlist entries never delete local media. Duplicate occurrences and ordered entries are preserved. Failed downloads or incomplete Apple Music responses leave each affected playlist unchanged; other playlists may still succeed. The command does not rename playlist files or alter existing metadata headers. Large removals require --yes after inspecting --dry-run.

Interactive Controls

Key Action
Arrow keys Navigate options
Space Toggle an item in a multi-select menu
Ctrl + A Select all items where supported
Enter Confirm or open the selected item

⚙️ Configuration

Gamdl stores its configuration in a .gamdl folder inside your home directory (your user profile folder on Windows). For example:

Windows: C:\Users\<username>\.gamdl\config.yml
Linux:   /home/<username>/.gamdl/config.yml
macOS:   /Users/<username>/.gamdl/config.yml

Gamdl creates a configuration file automatically on first use when needed. To find its location, create one manually, or inspect the effective settings, use:

gamdl config path
gamdl config init
gamdl config show
gamdl config validate

CLI options override YAML values for the current command. You can specify another file with the top-level --config PATH option, or use --no-config to ignore your saved settings. Do not run config init --force unless you want to replace your existing file.

Option headings below show the YAML key / CLI flag where both exist. Options without a YAML key are marked as CLI-only.

Authentication Settings

Authentication Method (auth.mode / --auth-mode)

Choose wrapper, cookies, or media-user-token. The default is null, which opens the setup wizard when authentication is required.

Credentials and Wrapper Connection

auth.cookies_path / --cookies-path specifies the cookies file. auth.media_user_token / --media-user-token supplies a token directly. auth.wrapper_url / --wrapper-url sets the wrapper's HTTP address; auth.wrapper_decrypt_host / --wrapper-decrypt-host and auth.wrapper_decrypt_port / --wrapper-decrypt-port configure its decryption endpoint (default port 10020).

Avoid passing secrets on the command line when possible, as they may be recorded in shell history.

DRM Backend (auth.drm_backend / --drm-backend)

Choose widevine (default) or playready. For a custom provisioned device, use auth.device_path / --device-path. Widevine uses the bundled L3 device by default, while PlayReady requires a compatible .prd device file. For higher-security playback, provide an appropriately provisioned device. Protected media must also have suitable DRM signaling and licenses.

Storefront and Language (auth.storefront / --storefront, auth.language / --language)

Set the Apple Music storefront with a two-letter country code such as br, and the metadata language with a tag such as pt-BR. The storefront is normally detected from your account; the default language is en-US.

Song Downloads

Codec Priority (download.song_codec_priority / --song-codec-priority)

Select codecs in preference order. Gamdl tries the preferred formats based on the streams actually available for each track. Default: aac (AAC via HLS, compatible with Wrapper or Widevine/PlayReady).

download:
  song_codec_priority:
    - alac
    - atmos
    - aac
gamdl rip "<song URL>" --song-codec-priority alac,atmos,aac

Supported song codec identifiers are aac, aac-he, aac-binaural, aac-downmix, aac-he-binaural, aac-he-downmix, aac-web, aac-he-web, atmos, ac3, alac, alac-lossless, and alac-hires.

  • aac uses HLS and works with Wrapper or Widevine/PlayReady. aac-web uses the separate web-playback stream, which requires Widevine/PlayReady even when Wrapper is connected.
  • alac automatically chooses the highest-quality ALAC available: Hi-Res (above 48 kHz) first, then standard Lossless (up to 48 kHz). Within a tier it favors higher sample rates, then bit depths, then bitrates. Wrapper streams take precedence over Apple Music asset streams at the same tier. The actual downloaded codec is still recorded as alac-hires or alac-lossless, not alac.
  • alac-lossless and alac-hires remain available when you want to request a specific tier. The tiers are identified from HLS audio-group metadata.

Song Codec Specifications

These are typical Apple Music profiles, not guaranteed specifications. Actual bitrates, sample rates, and available streams depend on the track and its HLS manifest; Gamdl discovers the available variants instead of enforcing these values.

Codec Typical bitrate Audio characteristics
aac 256 kbps AAC, up to 48 kHz; HLS
aac-he 64 kbps HE-AAC, up to 48 kHz; HLS
aac-binaural 256 kbps AAC binaural mix; HLS
aac-downmix 256 kbps AAC downmix; HLS
aac-he-binaural 64 kbps HE-AAC binaural mix; HLS
aac-he-downmix 64 kbps HE-AAC downmix; HLS
aac-web 256 kbps AAC, typically 44.1 kHz; web playback
aac-he-web 64 kbps HE-AAC, typically 44.1 kHz; web playback
atmos 768 kbps Dolby Atmos (E-AC-3 JOC); HLS
ac3 640 kbps Dolby Digital (AC-3); HLS
alac Variable (lossless) Best available ALAC tier; typically up to 24-bit/192 kHz
alac-lossless Variable (lossless) ALAC at 48 kHz or below; HLS
alac-hires Variable (lossless) ALAC above 48 kHz; HLS

ALAC is lossless, so its bitrate varies with the audio. The alac option selects a concrete tier, not a new encoded format. --ask-song-codec opens an interactive stream selector; ask is not a codec identifier.

Gamdl warns after authentication when Apple Music reports account content restrictions, which may prevent some tracks from downloading. It also warns when ALAC is selected without Wrapper, because Apple Music may refuse Widevine/PlayReady licenses for lossless streams. These are informational warnings, not download blockers; interactive ALAC selection displays the warning when that codec is chosen.

Exact Codec (download.song_codec / --song-codec)

Request one specific codec instead of a fallback list. The default is null. Use --ask-song-codec (CLI-only) to choose a stream interactively; it requires a terminal.

For example, gamdl rip "<song URL>" --song-codec alac requests the best available ALAC tier without specifying a fallback to another format.

Lyrics (output.lyrics_file_format, output.embedded_lyrics_format)

Choose the lyrics representation independently for external sidecars and embedded metadata:

output:
  lyrics_file_format: lrc
  embedded_lyrics_format: text

Use --lyrics-file-format and --embedded-lyrics-format to override these settings. Both accept lrc, srt, ttml, text, and enhanced-lrc.

Format External extension Behavior
lrc .lrc Standard line timestamps
enhanced-lrc .lrc Word/syllable timestamps when available; otherwise standard line LRC
srt .srt Subtitle cues from lines with start and end timestamps
ttml .ttml Original Apple Music TTML
text .txt Plain lyrics without timing

External files are strict: if the selected format cannot be produced, Gamdl reports the lyrics sidecar as unavailable rather than silently saving a different type. The only exception is enhanced-lrc degrading to line LRC when syllable timing is missing. Existing media is reused when only a sidecar needs to be created or refreshed; an existing sidecar with a different extension is not mistaken for the requested format.

Embedded lyrics use the standard ©lyr text metadata atom, even when formatted as LRC, SRT or TTML. If the requested embedded representation is unavailable, Gamdl falls back to line LRC when synchronized, then plain text. Some players display embedded timestamps or XML as literal text instead of synchronized lyrics, so text remains the default.

Sidecars are enabled by default (no_lyrics_file: false). Set output.no_lyrics_file: true or use --no-lyrics-file to disable external lyrics; to omit embedded lyrics, add lyrics to output.exclude_tags or use --exclude-tags lyrics. --no-tag also disables embedded lyrics. These controls are independent of the format settings.

Music Videos and Uploaded Videos

Codec Priority (download.music_video_codec_priority / --music-video-codec-priority)

Set the order for video codecs: h264 or h265. Default: h264, then h265.

download:
  music_video_codec_priority:
    - h265
    - h264
gamdl rip "<music video URL>" --music-video-codec-priority h265,h264

Video Codec and Resolution (download.music_video_codec / --music-video-codec, download.max_height / --max-height)

Select an exact video codec, or keep null to use the priority list. The maximum requested height defaults to 1080 pixels; higher resolutions depend on stream availability and your DRM capabilities. Use --ask-music-video-streams (CLI-only) to select audio and video streams interactively.

Videos above 1080p require a Widevine L1 or PlayReady SL3000 (SL3K) device. The bundled Widevine device is L3 and does not meet that requirement. Provide an appropriately provisioned device with --device-path (or auth.device_path) if you increase --max-height beyond 1080. Gamdl warns when it detects an insufficient device security level; the warning does not prevent downloading, and a higher security level alone does not guarantee a compatible license or stream.

Historically, Apple Music has offered the following music-video resolutions:

Codec Typical resolutions
h264 (AVC) 240p, 360p, 480p, 540p, 720p, 1080p
h265 (HEVC) Up to 2160p, including 1440p and 2160p variants

These are examples, not a fixed list enforced by Gamdl. Gamdl selects from the resolutions and bitrates advertised in the video's HLS manifest, respecting --max-height. The default 1080p limit excludes higher resolutions until you raise it.

Music Video Audio Selection

For music videos, Gamdl automatically selects the highest-bitrate AAC track available. If no AAC rendition is available, it falls back to the highest-bitrate HE-AAC track. It never automatically selects Dolby Atmos or AC-3, even if those are marked as the default audio tracks in the HLS manifest.

Audio may come from a different audio group than the chosen video variant. When needed, Gamdl reads audio playlist metadata to estimate bitrate without downloading media segments. If an audio bitrate cannot be determined, the playlist's default designation and stereo group are used as tiebreakers. If neither AAC nor HE-AAC is available, automatic selection reports an unavailable stream rather than choosing a surround codec. To select an audio stream manually (including Atmos or AC-3), use --ask-music-video-streams.

Music Video Container (output.music_video_container / --music-video-container)

Music videos are saved as .m4v files by default, with M4V branding. Select mp4 to save .mp4 files with mp42 branding instead; audio and video are still muxed losslessly. This setting does not affect songs or uploaded videos.

output:
  music_video_container: mp4
gamdl rip "<music video URL>" --music-video-container mp4

Uploaded Video Quality (download.uploaded_video_quality / --uploaded-video-quality)

Choose an uploaded video's asset variant when you need to override automatic quality selection. Use --ask-uploaded-video-quality (CLI-only) for an interactive choice.

The available identifiers, in the default preference order, are:

Identifier Apple Music asset variant
1080pHdVideo 1080p HD
720pHdVideo 720p HD
sdVideoWithPlusAudio Standard definition with enhanced audio
sdVideo Standard definition
sd480pVideo 480p SD
provisionalUploadVideo Provisional upload

These are Apple Music asset names, not guaranteed resolutions or bitrates. Gamdl uses the best available variant in this order unless you select a specific one.

Download Behavior

Download Concurrency (download.segment_concurrency / --segment-concurrency, download.concurrent_downloads / --concurrent-downloads)

segment_concurrency controls parallel media-segment HTTP requests for an individual track (default: 8); it does not directly limit Apple Music metadata or playback API requests. concurrent_downloads controls how many media items download simultaneously (default: 2). Higher parallelism can indirectly result in overlapping API calls.

Existing Files (download.overwrite / --overwrite)

Existing files are skipped by default (download.overwrite: false). Use the --overwrite flag or set download.overwrite: true to replace them. --no-overwrite overrides a YAML true value for one command. Songs use their configured filename directly; music videos can receive numbered suffixes (Title 2.m4v) to avoid filename collisions.

Error Handling (download.fail_fast / --fail-fast)

The default is to continue processing remaining items after individual failures (fail_fast: false). Set download.fail_fast: true or use --fail-fast to stop after an error.

For rip, library, search, and sync playlists, expected Gamdl errors are reported as short messages without tracebacks. Unexpected exceptions (including DRM license failures and malformed API responses) are collected and printed with full Python tracebacks after the final results, once progress bars have closed. Use --no-tracebacks (or ui.no_tracebacks: true in YAML) to suppress tracebacks while keeping concise failure messages. Tracebacks may contain signed URLs, tokens, or account details; inspect them before sharing logs.

Automatic Selection (download.artist_auto_select / --artist-auto-select, download.library_auto_select / --library-auto-select)

Choose artist categories such as main-albums, singles-eps, top-songs, and music-videos, or library categories such as albums, playlists, songs, and music-videos. CLI values are comma-separated; YAML values are lists. Both options default to empty lists, meaning their respective browsers are used.

Metadata and Artwork

Tagging (output.no_tag / --no-tag, --tag)

Metadata tagging is enabled by default (output.no_tag: false). Use --no-tag to skip writing metadata tags for one command, or --tag to enable them even when disabled in YAML.

Excluded Tags (output.exclude_tags / --exclude-tags)

Exclude specific metadata fields, including cover, without disabling all tagging. Configure a YAML list or use comma-separated names on the CLI:

output:
  no_tag: false
  exclude_tags:
    - comment
    - title_sort
    - cover
gamdl rip "<song URL>" --exclude-tags comment,title_sort,cover

See Tags and Path Templates for every accepted exclusion name, including fields that use different names in path templates.

Artwork (output.save_cover / --save-cover, output.cover_format / --cover-format)

Embedded artwork is normally included when tagging is enabled. Saving a separate artwork file is disabled by default. Choose jpg (default) or png for cover format.

Files and Folders

Output Directory (output.directory / --output-dir)

The first time you download media, output.directory is null, so Gamdl asks where to save your music and remembers your choice in config.yml. The suggested folder is the Music directory of your operating system's user profile, detected through platformdirs (including relocated Music folders on Windows and XDG music directories on Linux). Press Enter to accept it, or enter another location.

Use --output-dir PATH to bypass the prompt and override the destination for a command, or set output.directory directly in YAML. Non-interactive downloads require one of these explicit paths. output.temp_path / --temp-path optionally selects a working directory for temporary download files.

Filename Templates (output.*_template / matching CLI options)

Configure album, compilation, no-album, playlist, and filename templates. Each has a corresponding CLI flag, such as --album-folder-template or --single-disc-file-template.

output:
  album_folder_template: "{album_artist}/{album}"
  single_disc_file_template: "{track:02d} {title}"
  multi_disc_file_template: "{disc}-{track:02d} {title}"
  playlist_folder_template: "Playlists/{playlist_artist}"

The complete list of supported placeholders, their meanings, and the corresponding tag names is in Tags and Path Templates.

Use output.truncate / --truncate to limit filename component length when needed.

Playlists

Save Playlists (output.save_playlist / --save-playlist)

Enable generation of relative-path .m3u8 files for Apple Music playlists. It is disabled by default. The playlist folder and filename templates live under output.playlist_folder_template and output.playlist_file_template.

Database

Media Index (database.disabled / --no-database, database.path / --database-path)

The SQLite index is enabled by default. It tracks downloaded files with portable paths relative to output.directory, their codecs and their most relevant album/playlist source. Disable it with database.disabled: true or --no-database. The database defaults to media.sqlite3 in the same .gamdl folder as config.yml, and database.path remains configurable. The first creation of each file is reported as Created config at … or Created database at …. Custom configuration paths are supported through --config or GAMDL_CONFIG.

With the index enabled, rip checks existing catalog IDs before fetching per-track tags, playback streams, lyrics, or decryption information. With overwrite disabled (default), an indexed file that still exists within the output library can be reused directly. Existing cover/lyrics sidecars are also reused without network requests; missing sidecars can still be fetched, and playlist entries are finalized normally. Explicit codec selections, single-codec priorities without a verified matching codec, and --overwrite bypass the early skip so codec changes are not silently mistaken for existing matches. The same indexed ID information is used for local track resolution in sync playlists.

database:
  disabled: false
  save_metadata: false

Set save_metadata: true (or --save-metadata) to also store resolved tags in separate songs, music_videos, and uploaded_videos tables. Metadata writes reuse tags already resolved during downloading and do not save artwork or lyrics in SQLite. gamdl database scan indexes existing local media, checks local M3U playlists and complete albums to reconstruct source membership, and fills any missing metadata from embedded tags when save_metadata is on; it never downloads media or contacts Apple Music.

Interface

Progress Display (ui.no_progress / --no-progress)

Live progress is enabled by default (ui.no_progress: false). Set ui.no_progress: true or use --no-progress to disable it. ui.max_visible_tracks / --max-visible-tracks controls the number of track rows shown at once (default: 5).

Error Tracebacks (ui.no_tracebacks / --no-tracebacks)

Unexpected errors print full tracebacks at the end by default. Set ui.no_tracebacks: true or pass --no-tracebacks to hide them. Known, expected conditions remain concise. Review tracebacks before sharing, as exception messages may contain sensitive URLs or account information.

🏷️ Tags and Path Templates

Gamdl separates path placeholders (used in filenames and folders) from tag exclusions (used to omit embedded metadata). Some names differ between the two. This reference lists every supported name.

Path Template Placeholders

Use these placeholders in the output.*_template settings or their CLI equivalents:

Placeholder Value Corresponding tag for --exclude-tags
{album} Album title album
{album_artist} Album artist album_artist
{album_id} Apple Music album ID album_id
{artist} Track or video artist artist
{artist_id} Apple Music artist ID artist_id
{composer} Composer name composer
{composer_id} Apple Music composer ID composer_id
{date} Release date, normally a YYYY-MM-DD string release_date
{disc} Disc number disc_number
{disc_total} Total discs disc_total
{media_type} Numeric media type identifier media_type
{playlist_artist} Playlist curator or artist —
{playlist_id} Apple Music playlist ID —
{playlist_title} Playlist title —
{playlist_track} Track position in the playlist (1-based) —
{title} Song or video title title
{title_id} Apple Music song or video ID title_id
{track} Track number track_number
{track_total} Total tracks track_total

For example, {track:02d} {title} produces 01 Song Title when a track number is available. Standard Python format specs for numeric fields work; arbitrary expressions, attribute access, and indexing are not allowed.

The {date} placeholder uses the original release-date text. To select part of a date, use strftime specifiers such as {date:%Y} (year), {date:%Y-%m} (year and month), or {date:%d} (day). ISO-formatted dates and timestamps are supported; year-only and year-month values are also accepted, with missing month/day components assumed to be January/1 when formatting. Missing or invalid dates use the Unknown Date fallback.

Playlist placeholders are populated when playlist context is available; otherwise, fallback text is used. Missing metadata also uses readable fallbacks such as Unknown Artist or Unknown Album, or an empty string for missing numbers. Gamdl sanitizes invalid filename characters and restricts path components to safe lengths. Excluding an embedded tag does not remove its value from filename formatting.

Excludable Metadata Tags

These are all 32 valid names for output.exclude_tags and --exclude-tags:

Tag name Metadata omitted from the saved file
title Song or video title
artist Track artist
album Album title
album_artist Album artist
title_id Apple Music song or video ID
artist_id Apple Music artist ID
album_id Apple Music album ID
track_number Track number (template: {track})
track_total Total tracks
disc_number Disc number (template: {disc})
disc_total Total discs
release_date Release date (template: {date})
genre Genre text
genre_id Apple Music genre ID
isrc International Standard Recording Code
xid Apple Music external identifier
title_sort Title used for sorting
artist_sort Artist used for sorting
album_sort Album title used for sorting
composer Composer name
composer_id Apple Music composer ID
composer_sort Composer used for sorting
copyright Copyright notice
comment Comment text
compilation Compilation flag
gapless Gapless playback flag
explicit Explicit-content flag
storefront Numeric Apple Music storefront ID
media_type Numeric media type identifier
rating Content/parental rating
lyrics Embedded plain-text lyrics
cover Embedded cover artwork

For example, --exclude-tags lyrics,cover,comment omits those embedded fields while keeping the remaining tags. cover affects embedded artwork; separate artwork files are controlled by --save-cover. Likewise, excluding lyrics does not disable external lyrics files—use --no-lyrics-file for that.

Use --no-tag to disable embedded tagging altogether. Only metadata provided for a given item can be written, even when a tag is not excluded.

🔄 Migrating from Gamdl 3.x

Gamdl 4.x introduces several changes to its CLI and configuration:

  • Subcommands: Use gamdl rip URL instead of passing URLs directly to gamdl.
  • YAML configuration: Replace your old INI configuration with the new YAML settings. Run gamdl config init to generate a reference configuration.
  • Authentication: Configure Wrapper, Cookies, or Media User Token with gamdl auth; the old --use-wrapper flag is replaced by an authentication method.
  • Codec selection: The default is now HLS aac instead of aac-web. The generic alac preference automatically selects the best ALAC tier. Interactive stream selection has dedicated flags such as --ask-song-codec; codec-priority lists accept comma-separated CLI values or YAML lists.
  • Date templates: Strftime-style placeholders such as {date:%Y} and {date:%Y-%m} continue to work. Release dates are now stored as strings internally, but the path formatter parses them when a date specifier is requested.
  • Excluded tags: The old all special value is no longer accepted in --exclude-tags; use --no-tag instead. Some path placeholders use different names from tag exclusions (for example, {date} versus release_date).
  • Download concurrency: Use download.segment_concurrency / --segment-concurrency for media segment requests. Previous concurrency option names are not supported.
  • Playlist organization: organize can repair playlist paths, but restoring missing metadata headers in legacy playlists remains a separate, manual task.
  • Database format: Older SQLite indexes cannot be opened by 4.x. Gamdl does not overwrite or upgrade them automatically; move the old database aside or set a fresh database.path. Your downloaded media files are not touched.
  • Native processing: The native muxing/decryption layer replaces the old external downloader and muxer workflow. Review removed 3.x flags rather than copying them directly.
  • Python API: The modules and classes have been reorganized. Applications embedding Gamdl 3.x should update their imports and integration code.

Keep a backup of your old configuration until you have verified your new settings and output templates.

🐍 Python API

Gamdl also provides asynchronous Python APIs for catalog access, media resolution, downloading, and media processing. For example, to fetch a song's metadata using an exported Apple Music cookies file:

import asyncio

from gamdl.api import AppleMusicApi
from gamdl.media import MediaResolver


async def main():
    api = await AppleMusicApi.from_cookies("cookies.txt")
    async with api:
        resolver = MediaResolver(api)
        async for song in resolver.from_song("1228739609"):
            metadata = await song.get_metadata()
            print(metadata["attributes"]["name"])


asyncio.run(main())

The API is asynchronous; use context managers to close connections. More advanced applications can use Downloader, Drm, Streamer, Muxer, and PathFormatter directly.

HTTP Transports

gamdl.transport provides ApiHttpClient and RequestPacer for private/API requests (authentication, pacing, and retries), alongside PublicTransport for public HTTPS resources such as streaming manifests, initialization segments, and artwork. The public transport uses isolated requests at every redirect hop, so credentials and cookies from a caller-supplied HTTPX client are not forwarded. It rejects insecure redirects and preserves the lifetime of borrowed clients. HLS parsing stays in media.stream.StreamTransport, which uses PublicTransport for network requests. Existing gamdl.api and gamdl.api.http imports of ApiHttpClient / RequestPacer remain supported.

🛠️ Troubleshooting

Authentication fails: Check that your session is valid, your cookies include media-user-token, or your wrapper is reachable. Retry gamdl auth.

A codec or stream is unavailable: Not every track offers every codec. Try --ask-song-codec, --ask-music-video-streams, or the default aac HLS codec. You can still try aac-web with Widevine/PlayReady when appropriate.

DRM initialization fails: Verify that the relevant extra (widevine or playready) is installed, that a required device file is available, and that the stream supports the selected backend.

A download is skipped: The default is download.overwrite: false. Use --overwrite if you intentionally want to replace the existing file.

The library has unexpected paths: Check your filename templates and use gamdl organize --dry-run before applying changes.

For additional support, use GitHub Issues or the Discord server. When sharing error tracebacks, remove cookies, tokens, and signed URLs.

🤝 Contributing

Bug reports, feature requests, and pull requests are welcome. Please check existing issues before opening a new one.

For source development, install uv, Python, and Rust. Then run:

uv sync
uv run python -m unittest discover -s tests
cargo test --manifest-path native/Cargo.toml

Some media-related tests also require FFmpeg and FFprobe.

Releasing to PyPI

The publishing workflow builds a source distribution and precompiled ABI3 wheels for Linux (x86_64/ARM64), Windows (x86_64/ARM64), and macOS (universal2). Every wheel is installed and smoke-tested, and the full artifact set is checked before publication.

Run Publish Python Package manually from GitHub Actions to build and inspect artifacts without publishing. Publishing occurs only when a GitHub Release is published with a tag matching pyproject.toml (for example, v4.0.0). The workflow must be present on the repository's default branch for the release trigger to work.

PyPI Trusted Publishing must be configured for repository glomatico/gamdl, workflow python-publish.yml, and GitHub environment pypi. No long-lived PyPI token is needed. Configure GitHub environment protection rules as desired before publishing a release.

📄 License

Gamdl is released under the MIT License.

Metadata

Release files for gamdl 4.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gamdl 4.0.0
File Size Uploaded Provenance Actions
gamdl-4.0.0.tar.gz 237.2 kB With provenance Details for gamdl-4.0.0.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for gamdl 4.0.0
File Actions
gamdl-4.0.0-cp310-abi3-win_arm64.whl CPython 3.10 abi3 Windows ARM64 Details for gamdl-4.0.0-cp310-abi3-win_arm64.whl
gamdl-4.0.0-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details for gamdl-4.0.0-cp310-abi3-win_amd64.whl
gamdl-4.0.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details for gamdl-4.0.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
gamdl-4.0.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details for gamdl-4.0.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
gamdl-4.0.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl CPython 3.10 abi3 macOS 10.12+ universal2 (ARM64, x86-64), macOS 10.12+ x86-64, macOS 11.0+ ARM64 Details for gamdl-4.0.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl

Total release size: 14.8 MB

Release files / gamdl-4.0.0.tar.gz

Download URL gamdl-4.0.0.tar.gz
Size 237.2 kB
Tags Source
SHA-256 checksum
How to use checksums
d4fed3c5dc9b62bbc756ee4644252b13cf2b3c97fb752054eeb9c50fb33f3486
BLAKE2b-256 checksum
How to use checksums
9252718e7219c5b8f4063e148734ab7b80531ee8319c8460affa412d321dc3e2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 12, 2026.

Transparency log

Release files / gamdl-4.0.0-cp310-abi3-win_arm64.whl

Download URL gamdl-4.0.0-cp310-abi3-win_arm64.whl
Size 2.2 MB
Tags CPython 3.10 Windows ARM64 abi3
SHA-256 checksum
How to use checksums
edc555117080c4fe4465455876278584646d71ea83a1c5cb0c9a7175906f515d
BLAKE2b-256 checksum
How to use checksums
98df2f4a09fc5b151d91ef5f8b75cfa577d362796f23f003a4113ebbff89b717
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 12, 2026.

Transparency log

Release files / gamdl-4.0.0-cp310-abi3-win_amd64.whl

Download URL gamdl-4.0.0-cp310-abi3-win_amd64.whl
Size 2.3 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
d34e8eec2117018304a1b033b7ff2052d1755f4b71255ead5da3dfc5d76e028e
BLAKE2b-256 checksum
How to use checksums
03fe97b00116c37434badd36bb182902c1ec5125e686063c61158e33bf6d815e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 12, 2026.

Transparency log

Release files / gamdl-4.0.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL gamdl-4.0.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 2.7 MB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
0b22af9a0f6b8e1c3144a835ff6473d6373e6b06b3eb3b6f68ee21e57e83b969
BLAKE2b-256 checksum
How to use checksums
f24dc52f80fdeb5926d0202506f2fb0a9f3ed8dbde9dee2a440975bfd21592b0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 12, 2026.

Transparency log

Release files / gamdl-4.0.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL gamdl-4.0.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 2.7 MB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
d3a48e8eecc87576133cde2f444e43e56392d7f180bffedfde2f605682a602cc
BLAKE2b-256 checksum
How to use checksums
4b74c41d3c5971688d24f83d32b384b9b2059791e6f6a6747117c59eba34068a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 12, 2026.

Transparency log

Release files / gamdl-4.0.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl

Download URL gamdl-4.0.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Size 4.7 MB
Tags CPython 3.10 abi3 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
8f38c9f1105133541e7e0f28805bdccd5810aa1c413464a1e09f7f28fdf765b0
BLAKE2b-256 checksum
How to use checksums
e48b21f76812e144766352e0a9a467bf46e453bdead095aa6b6066493533db65
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 12, 2026.

Transparency log

Security for gamdl 4.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 6 files in this release have been uploaded with provenance metadata.

Select from 6 files

Attestation for gamdl-4.0.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 12, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

4.0.0 This release

6 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page