A liked song can be a surprisingly good timestamp. I remember the songs I had on repeat during a particular trip or stretch of work, but finding them again inside one growing library takes some effort.
I wanted a simple record: the songs I saved in June, the ones I found in July, and so on. A playlist per month is enough structure to make that useful.
I had been using an IFTTT automation for this. When the functionality I relied on moved behind a paywall, I built a small Python alternative and scheduled it with GitHub Actions.
Keep the output where I already listen
The result is an ordinary Spotify playlist with a month-and-year name, such as Jun '23. I can find it in Spotify, play it on another device, or share it using the controls I already know.
The automation does not need its own dashboard to be useful. Its interface is the collection it leaves behind.
That made the scope fairly clear: read my saved tracks, identify the relevant months, find or create the matching playlists, and add tracks that are missing.
The date belongs to the save
Spotify includes an added_at timestamp with a saved track. The script parses that timestamp and uses it to decide which monthly playlist the song belongs in.
This is a record of when I saved a song. It does not claim to know when I first heard it, how often I played it, or whether it was my favourite track of the month.
The distinction is useful. It gives the archive a rule I can explain and inspect. If I save an old song today, it belongs to the month I rediscovered and saved it.
The default run uses a current-month threshold. Historical backfilling needs an intentional earlier start date; running the script today should not be described as automatically rebuilding years of history.
Re-running should reuse the existing work
A scheduled script will run when there is nothing new to add. That is normal.
The code fetches the account's playlists, looks for a matching name owned by that account, and checks the target playlist's tracks before adding a saved song. The ownership check matters: a title alone is not enough to identify my playlist.
Playlist listings are paginated. If the matching playlist is not found in that listing, there is also a search fallback before creating another one. The track reader likewise fetches additional pages as needed.
Those details are easy to miss in a small automation. They matter more once the account has enough music and playlists to outgrow a single API response.
The intent is to make completed repeat runs reuse their previous work. I would still check boundary and retry cases before describing the script as fully idempotent.
Let a schedule carry the habit
GitHub Actions provides the scheduled runner. Python and Spotipy handle the Spotify API work. Once authentication is configured, the useful action is simply continuing to save music in Spotify.
The script can look for new saves, add the missing songs, and finish. I do not have to remember which playlist is currently being maintained.
Authentication is part of the maintenance cost. Tokens expire, permissions change, and an unattended run can fail while the playlists appear unchanged. Before publishing a fresh setup guide, I want to revisit the existing authentication instructions, keep token material out of Git, and make a failed scheduled run easy to notice.
The current repository is the implementation behind this story, not a promise that its older setup instructions are a frictionless onboarding flow today.
What I would tighten next
The most useful next checks are ordinary ones: an empty saved library, a large collection, a run near a month boundary, and a retry after only part of the work succeeds.
The script also mixes Spotify's UTC save timestamps with a locally constructed date threshold. Making the intended timezone and the exact start-of-month boundary explicit would make the behaviour easier to reason about.
These are small improvements to a deliberately small tool. The main idea still holds: save a song once, and let the monthly archive follow from that existing action.
The Spotify Monthly Saves source is public. Spotify Ritual explores what a more expressive experience around monthly music could look like, while this script keeps the collection step in the background.
