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
