1.000 2026-09-05 10:34:19Z
[BREAKING CHANGES]
- Remove the 30 methods whose Spotify endpoints were deleted in the
November 2024 and February 2026 API changes, along with the
once-per-process deprecation warning. Replacements:
albums, artists, tracks, get_several_shows, get_several_audiobooks,
get_several_chapters -> call album/artist/track/get_show/
get_audiobook/get_chapter per id
remove_user_saved_tracks, save_shows_for_current_user,
save_audiobooks_for_current_user, remove_users_saved_audiobooks,
follow_artists_or_users, unfollow_artists_or_users
-> save_library_items / remove_library_items
check_users_saved_tracks, check_users_saved_shows,
check_users_saved_audiobooks, check_if_user_follows_artists_or_users,
check_if_user_follows_playlist -> check_library_items
get_track_audio_features, get_several_tracks_audio_features,
get_track_audio_analysis, get_recommendations,
get_available_genre_seeds, browse_featured_playlists,
browse_new_releases, get_categories, get_category,
artist_top_tracks, artist_related_artists, user,
user_playlist -> no replacement (use get_current_user_playlists
for the authorized user)
- Drop WWW::Mechanize: the ua attribute is now a plain LWP::UserAgent
(a WWW::Mechanize object still works). The custom_request_handler
callback now receives the HTTP::Response instead of the Mechanize
object
- Every request now sends the bearer token. force_client_auth and the
second (client_auth_required) argument to query_full_url are gone
- Removed result_format, grab_response_header's IO::CaptureOutput
capture (response_headers is now the plain header string),
get_oauth_authorize, current_oath_code, build_url_base, call_type,
uri_domain_path, problem and join_ids
- POST/PUT/DELETE set last_error on any non-2xx status (POST
previously flagged a successful 201 Created as an error)
[OTHER]
- Data::Dumper and IO::CaptureOutput are no longer dependencies
- Remove the dead Travis CI config and the duplicate ci.yml workflow;
test.yml no longer runs the Windows matrix or the (never uploading)
coverage job, and tests one Perl on macOS
- Test mocks live in t/lib/MockUA.pm instead of being copied per file
0.017 2026-08-30 12:24:03Z
[SECURITY]
- Re-enable TLS hostname verification: the PERL_LWP_SSL_VERIFY_HOSTNAME=0
overrides in _send_request, get_oauth_authorize and
get_client_credentials are gone
- oauth_token_url must now be an https://accounts.spotify.com/ URL
before client credentials are sent to it
- query_full_url() refuses non-https://api.spotify.com/ URLs whenever a
bearer token would be attached, so a poisoned paging URL in an API
response can no longer receive the token
- uri_scheme and uri_hostname are read-only
- Path-segment placeholders (IDs and similar) are uri_escaped when URLs
are built
- Invalid JSON in token and API responses now dies instead of quietly
continuing (previously could send an empty bearer token)
[OTHER]
- get_oauth_authorize() returns the authorize URL instead of fetching
the login page server-side
- GitHub Actions CI workflow (perl 5.24-5.38 on Linux, 5.38 on macOS)
0.016 2026-08-30 02:30:39Z
- Fix t/01 failing without SPOTIFY_CLIENT_ID: its live requests now sit
behind a credential SKIP gate again, so installs and smokers no
longer fail the test suite (broken in 0.015)
- Raise minimum perl to 5.24, matching what CI can actually test
(the cpm dependency installer requires it)
0.015 2026-08-30 02:00:23Z
[BREAKING CHANGES]
- create_playlist() drops the user_id argument; it now takes
($name, $public, $description) and posts to /v1/me/playlists
(the old /v1/users/{user_id}/playlists endpoint returns 403)
- get_access_token() now takes an authorization code and returns
true/false, storing the tokens on the object (it previously posted
the literal string 'code' and could never succeed)
[NEW FEATURES]
- Working OAuth authorization-code flow: authorize_url() builds the
browser login URL, get_access_token() exchanges the code,
refresh_access_token() renews via the stored refresh_token attribute
- unfollow_playlist() - DELETE /v1/playlists/{id}/followers
[BUG FIXES]
- User playlist methods send the Authorization header even with
force_client_auth disabled (previously 401 on every call)
- add_items_to_playlist() sends uris as a JSON array as the API
requires; a bare string or arrayref is accepted
- search terms and extra query parameters are URI-escaped
- Endpoint migrations for the Spotify February 2026 API changes,
including playlist /tracks -> /items and consolidated
/v1/me/library endpoints; removed endpoints warn once per method
[OTHER]
- Reverted the 0.014 split into WWW::Spotify::Client, ::Endpoint, and
::Response; the module is a single file again with the request
machinery consolidated into shared _send_request/_build_url helpers.
0.014's fixes (SSL verification bypass removal, URI encoding,
client_auth_required placement) are preserved in this line
[TESTING]
- Mocked offline test suites for request building, the OAuth flow, and
catalog methods (no credentials needed)
- Developer-only interactive live test (xt/author/live-user.t) that
performs a real browser OAuth login and exercises user endpoints;
skipped everywhere unless SPOTIFY_INTERACTIVE_TESTS=1
0.014 2025-01-18
- Refactored module into smaller focused units (Client, Endpoint, Response roles)
- Added explicit use strict/warnings/5.010 to all modules
- Fixed HTTP status code handling for POST/PUT/DELETE requests
- Added URI encoding for path parameters
- Improved test organization (separated user auth tests)
- Security: Removed SSL verification bypass, fixed token leak in debug output
- Fixed client_auth_required nesting in playlist and artist methods
0.013 2024-01-01 00:00:00Z
- Internal release for refactoring
0.012 2022-10-19 16:30:23Z
- Improved options for error handling (GH#11)
- Improved last_error
- Added die_on_response_error
- Added custom_request_handler
- Added custom_request_handler_result
- Added response_content_type
- Added response_status
- Removed all XML related code - Spotify API no longer supports XML
0.011 2022-10-18 10:10:00Z
- Change useragent base class from WWW::Mechanize to LWP::UserAgent (GH#13)
(Olaf Alders)
- Tidy imports and drop support for perl 5.8 (GH#12) (Olaf Alders)
0.010 2020-09-17 21:21:55Z
- Fix credentials (GH#8) (trs-80)
0.009 2017-02-16 23:18:10-05:00 America/Toronto
- Require rather than use XML::Simple.
0.008 2016-08-07 00:00:18-04:00 America/Toronto
- Adds LWP::Protocol::https to dependencies.
0.007 2016-08-06 01:50:04-04:00 America/Toronto
- Allow users to provide their own useragents via "ua" arg to new().
- Remove unused is_valid_json() method.
0.006 2016-08-04 23:49:44-04:00 America/Toronto
- Switch from Moose to Moo + Type::Tiny
0.005 2016-07-28 22:23:03-04:00 America/Toronto
- GitHub repo url is now in metadata.
0.004 2014-11-23
- Enhanced documentation
- Added query_full_url to help work with playlist results
0.003 2014-10-23
- Changed album_tracks to albums_tracks to better match actual API call
- Added browse_feature_playlist method
- Added browse_new_releases method
- Enhanced documentation
- Improved tests
0.002 2014-06-24
- Resolved issue with undefined item which caused tests to fail on some platforms
- Minor changes to documention
0.001 2014-06-23
- Initial releasee