Version 10 aligns the library with Spotify’s OpenAPI specification. Method names, request class names and packages now follow the specification’s operation IDs and tags instead of the names this library grew historically.
No endpoint lost its counterpart. 9.4.0 exposed 94 request builders and 10.0.0 exposes 114, every one of the 94 among them. Of the 94, 50 keep both their name and their endpoint, 40 were renamed, and 4 keep their name while something about them changed. One further request class was renamed under a method that did not change, so the rename table below has 41 rows.
Work through the tables below to fix the build, but read the next section first. It collects the handful of changes where a clean compile is not enough, or where the obvious replacement is the wrong one.
addItemsToPlaylist now posts to a different endpoint.
This is the only change that is completely silent.
The signature is unchanged, so existing code keeps compiling, but the request now targets POST /playlists/{playlist_id}/items instead of POST /playlists/{playlist_id}/tracks.
If you need the old path, addItemsToPlaylistDeprecated still calls it.
createPlaylist lost its user_id parameter.
In 9.4.0 it was createPlaylist(String user_id, String name) calling POST /users/{user_id}/playlists.
In 10.0.0 it is createPlaylist(String name) calling POST /me/playlists, which always creates the playlist for the authenticated user.
The old form lives on as createPlaylistForUser(String user_id, String name), which is deprecated.
// v9
spotifyApi.createPlaylist(userId, "My playlist").build().execute();
// v10
spotifyApi.createPlaylist("My playlist").build().execute();
followPlaylist and unfollowPlaylist lost their owner overloads.
Spotify dropped the {owner_id} path segment, so followPlaylist(String owner_id, String playlist_id, boolean public_) and unfollowPlaylist(String owner_id, String playlist_id) are gone.
The remaining overloads take the playlist ID alone, and they moved from requests.data.follow.legacy to requests.data.users.
CountryCode now comes from this library.
The com.neovisionaries:nv-i18n dependency is gone, so every market and country parameter takes the CountryCode in se.michaelthelin.spotify.enums instead.
The constant names are the same, so this is an import change and nothing else.
// v9
import com.neovisionaries.i18n.CountryCode;
// v10
import se.michaelthelin.spotify.enums.CountryCode;
Playlist item accessors were renamed.
Playlist.getTracks() and PlaylistSimplified.getTracks() are now getItems(), and PlaylistTrack.getTrack() is now getItem().
The return types are unchanged, so these are a straight substitution once you know the new name.
Update the call and the import together. ⚠️ marks a replacement that is itself deprecated because Spotify deprecated the underlying endpoint. It still works; see Deprecations.
| v9 method | 10.0.0 method | v9 request class | 10.0.0 request class |
|---|---|---|---|
addItemToUsersPlaybackQueue |
addItemToPlaybackQueue |
AddItemToUsersPlaybackQueueRequest |
AddItemToPlaybackQueueRequest |
changePlaylistsDetails |
changePlaylistDetails |
ChangePlaylistsDetailsRequest |
ChangePlaylistDetailsRequest |
checkUsersFollowPlaylist |
checkIfUserFollowsPlaylist ⚠️ |
CheckUsersFollowPlaylistRequest |
CheckIfUserFollowsPlaylistRequest |
getAlbumsTracks |
getAlbumTracks |
GetAlbumsTracksRequest |
GetAlbumTracksRequest |
getAudioAnalysisForTrack |
getTracksAudioAnalysis ⚠️ |
GetAudioAnalysisForTrackRequest |
GetTracksAudioAnalysisRequest |
getAudioFeaturesForSeveralTracks |
getSeveralTracksAudioFeatures ⚠️ |
GetAudioFeaturesForSeveralTracksRequest |
GetSeveralTracksAudioFeaturesRequest |
getAudioFeaturesForTrack |
getTracksAudioFeatures ⚠️ |
GetAudioFeaturesForTrackRequest |
GetTracksAudioFeaturesRequest |
getAvailableGenreSeeds |
getRecommendationGenres ⚠️ |
GetAvailableGenreSeedsRequest |
GetRecommendationGenresRequest |
getCategory |
getSingleBrowseCategory ⚠️ |
GetCategoryRequest |
GetSingleBrowseCategoryRequest |
getCategorysPlaylists |
getCategoryPlaylists ⚠️ |
GetCategorysPlaylistsRequest |
GetCategoryPlaylistsRequest |
getCurrentUsersRecentlyPlayedTracks |
getRecentlyPlayedTracks |
GetCurrentUsersRecentlyPlayedTracksRequest |
GetRecentlyPlayedTracksRequest |
getCurrentUsersSavedAlbums |
getUsersSavedAlbums |
GetCurrentUsersSavedAlbumsRequest |
GetUsersSavedAlbumsRequest |
getInformationAboutUsersCurrentPlayback |
getPlaybackState |
GetInformationAboutUsersCurrentPlaybackRequest |
GetPlaybackStateRequest |
getListOfCategories |
getSeveralBrowseCategories ⚠️ |
GetListOfCategoriesRequest |
GetSeveralBrowseCategoriesRequest |
getListOfCurrentUsersPlaylists |
getCurrentUsersPlaylists |
GetListOfCurrentUsersPlaylistsRequest |
GetCurrentUsersPlaylistsRequest |
getListOfFeaturedPlaylists |
getFeaturedPlaylists ⚠️ |
GetListOfFeaturedPlaylistsRequest |
GetFeaturedPlaylistsRequest |
getListOfNewReleases |
getNewReleases ⚠️ |
GetListOfNewReleasesRequest |
GetNewReleasesRequest |
getListOfUsersPlaylists |
getUsersPlaylists ⚠️ |
GetListOfUsersPlaylistsRequest |
GetUsersPlaylistsRequest |
getPlaylistsItems |
getPlaylistItemsDeprecated ⚠️ |
GetPlaylistsItemsRequest |
GetPlaylistItemsDeprecatedRequest |
getShowEpisodes |
getShowEpisodes |
GetShowsEpisodesRequest |
GetShowEpisodesRequest |
getTheUsersQueue |
getUsersQueue |
GetTheUsersQueueRequest |
GetUsersQueueRequest |
getUsersAvailableDevices |
getAvailableDevices |
GetUsersAvailableDevicesRequest |
GetAvailableDevicesRequest |
getUsersCurrentlyPlayingTrack |
getCurrentlyPlayingTrack |
GetUsersCurrentlyPlayingTrackRequest |
GetCurrentlyPlayingTrackRequest |
getUsersFollowedArtists |
getFollowedArtists |
GetUsersFollowedArtistsRequest |
GetFollowedArtistsRequest |
pauseUsersPlayback |
pausePlayback |
PauseUsersPlaybackRequest |
PausePlaybackRequest |
removeItemsFromPlaylist |
removePlaylistItemsDeprecated ⚠️ |
RemoveItemsFromPlaylistRequest |
RemovePlaylistItemsDeprecatedRequest |
removeUsersSavedEpisodes |
removeEpisodesForCurrentUser ⚠️ |
RemoveUsersSavedEpisodesRequest |
RemoveEpisodesForCurrentUserRequest |
removeUsersSavedShows |
removeShowsForCurrentUser ⚠️ |
RemoveUsersSavedShowsRequest |
RemoveShowsForCurrentUserRequest |
reorderPlaylistsItems |
updatePlaylistsItemsReorderDeprecated ⚠️ |
ReorderPlaylistsItemsRequest |
UpdatePlaylistsItemsReorderDeprecatedRequest |
replacePlaylistsItems |
updatePlaylistsItemsReplaceDeprecated ⚠️ |
ReplacePlaylistsItemsRequest |
UpdatePlaylistsItemsReplaceDeprecatedRequest |
saveTracksForUser |
saveTracksForCurrentUser ⚠️ |
SaveTracksForUserRequest |
SaveTracksForCurrentUserRequest |
searchItem |
searchForItem |
SearchItemRequest |
SearchForItemRequest |
seekToPositionInCurrentlyPlayingTrack |
seekToPosition |
SeekToPositionInCurrentlyPlayingTrackRequest |
SeekToPositionRequest |
setRepeatModeOnUsersPlayback |
setRepeatMode |
SetRepeatModeOnUsersPlaybackRequest |
SetRepeatModeRequest |
setVolumeForUsersPlayback |
setPlaybackVolume |
SetVolumeForUsersPlaybackRequest |
SetPlaybackVolumeRequest |
skipUsersPlaybackToNextTrack |
skipToNext |
SkipUsersPlaybackToNextTrackRequest |
SkipToNextRequest |
skipUsersPlaybackToPreviousTrack |
skipToPrevious |
SkipUsersPlaybackToPreviousTrackRequest |
SkipToPreviousRequest |
startResumeUsersPlayback |
startResumePlayback |
StartResumeUsersPlaybackRequest |
StartResumePlaybackRequest |
toggleShuffleForUsersPlayback |
togglePlaybackShuffle |
ToggleShuffleForUsersPlaybackRequest |
TogglePlaybackShuffleRequest |
transferUsersPlayback |
transferPlayback |
TransferUsersPlaybackRequest |
TransferPlaybackRequest |
uploadCustomPlaylistCoverImage |
addCustomPlaylistCoverImage |
UploadCustomPlaylistCoverImageRequest |
AddCustomPlaylistCoverImageRequest |
These classes kept their name and moved to another package, so only the import changes.
| Class | v9 package | 10.0.0 package |
|---|---|---|
CheckCurrentUserFollowsArtistsOrUsersRequest |
requests.data.follow |
requests.data.users |
CheckUsersSavedAlbumsRequest |
requests.data.library |
requests.data.albums |
CheckUsersSavedEpisodesRequest |
requests.data.library |
requests.data.episodes |
CheckUsersSavedShowsRequest |
requests.data.library |
requests.data.shows |
CheckUsersSavedTracksRequest |
requests.data.library |
requests.data.tracks |
FollowArtistsOrUsersRequest |
requests.data.follow |
requests.data.users |
FollowPlaylistRequest |
requests.data.follow.legacy |
requests.data.users |
GetCurrentUsersProfileRequest |
requests.data.users_profile |
requests.data.users |
GetRecommendationsRequest |
requests.data.browse |
requests.data.tracks |
GetUsersProfileRequest |
requests.data.users_profile |
requests.data.users |
GetUsersSavedEpisodesRequest |
requests.data.library |
requests.data.episodes |
GetUsersSavedShowsRequest |
requests.data.library |
requests.data.shows |
GetUsersSavedTracksRequest |
requests.data.library |
requests.data.tracks |
GetUsersTopArtistsAndTracksRequest |
requests.data.personalization |
requests.data.users |
GetUsersTopArtistsRequest |
requests.data.personalization.simplified |
requests.data.users.simplified |
GetUsersTopTracksRequest |
requests.data.personalization.simplified |
requests.data.users.simplified |
IArtistTrackModelObject |
requests.data.personalization.interfaces |
requests.data.users.interfaces |
RemoveAlbumsForCurrentUserRequest |
requests.data.library |
requests.data.albums |
RemoveUsersSavedTracksRequest |
requests.data.library |
requests.data.tracks |
SaveAlbumsForCurrentUserRequest |
requests.data.library |
requests.data.albums |
SaveEpisodesForCurrentUserRequest |
requests.data.library |
requests.data.episodes |
SaveShowsForCurrentUserRequest |
requests.data.library |
requests.data.shows |
SavedEpisode |
model_objects.miscellaneous |
model_objects.specification |
UnfollowArtistsOrUsersRequest |
requests.data.follow |
requests.data.users |
UnfollowPlaylistRequest |
requests.data.follow.legacy |
requests.data.users |
| Class | v9 getter | 10.0.0 getter |
|---|---|---|
Playlist, PlaylistSimplified |
getTracks() |
getItems() |
Playlist, PlaylistSimplified |
getIsPublicAccess() |
getPublic() |
PlaylistTrack |
getTrack() |
getItem() |
Track, TrackSimplified |
getIsExplicit() |
getExplicit() |
Episode, EpisodeSimplified |
getPlayable() |
getIsPlayable() |
The getter names now follow the JSON field names in the specification.
Chapter and ChapterSimplified are new in 10.0.0 and expose getPlayable(), because their field is playable rather than is_playable.
The specification marks these fields deprecated, so the model objects dropped them. There is no replacement.
| Class | v9 getters with no replacement |
|---|---|
Album |
getAvailableMarkets(), getPopularity() |
AlbumSimplified |
getAlbumGroup(), getAvailableMarkets() |
Show, ShowSimplified |
getAvailableMarkets(), getPublisher() |
Track |
getAvailableMarkets(), getLinkedFrom(), getPopularity() |
TrackSimplified |
getAvailableMarkets(), getLinkedFrom() |
Nothing in the library referred to these any more, in most cases because 10.0.0 dropped the getter that used them.
| v9 type | Why it went |
|---|---|
AlbumGroup |
backed AlbumSimplified.getAlbumGroup(), which the specification deprecated |
ProductType |
backed the user product getter, which the specification deprecated |
PlaylistTrackPosition |
never referenced by any request or model object |
Paging.JsonUtil, PagingCursorbased.JsonUtil |
resolved their type argument to a parameterized type rather than a class, so instantiating either always threw |
A Paging object is built through the JsonUtil of the type it contains, which is how every request already built one.
The IModelObject array helper that took an explicit element class is gone as well, having had no callers.
Album and AlbumSimplified gained getTotalTracks(), AlbumSimplified also getIsPlayable(), Episode and EpisodeSimplified getHtmlDescription(), User getAccountId() and getExplicitContent(), and SearchResult getAudiobooks().
Audiobooks and chapters are new: Audiobook, AudiobookSimplified, Chapter, ChapterSimplified, ChapterRestriction, Author and Narrator.
ExplicitContentSettings backs the new User.getExplicitContent().
Three getters that always returned null in 9.4.0 now return a value, because the parser was reading a key the API does not send.
AudioAnalysisTrack fixes getWindowSeconds() and getEndOfFadeIn(), and AudioAnalysisSection fixes getMode().
Code that null-checked them will now take the other branch.
Seven interfaces were extracted so that full and simplified objects can be handled through one type: IAlbum, IArtist, IEpisode, IPlaylist, IShow, ITrack and IHasTotal.
Audiobooks and chapters:
| Method | Endpoint |
|---|---|
getAudiobook |
GET /audiobooks/{id} |
getSeveralAudiobooks ⚠️ |
GET /audiobooks |
getAudiobookChapters |
GET /audiobooks/{id}/chapters |
getUsersSavedAudiobooks |
GET /me/audiobooks |
saveAudiobooksForCurrentUser ⚠️ |
PUT /me/audiobooks |
removeAudiobooksForCurrentUser ⚠️ |
DELETE /me/audiobooks |
checkUsersSavedAudiobooks ⚠️ |
GET /me/audiobooks/contains |
getChapter |
GET /chapters/{id} |
getSeveralChapters ⚠️ |
GET /chapters |
searchAudiobooks |
GET /search |
The unified library API, which works on Spotify URIs of any type instead of one method per content type:
| Method | Endpoint |
|---|---|
saveItemsToLibrary |
PUT /me/library |
removeItemsFromLibrary |
DELETE /me/library |
checkUsersSavedItems |
GET /me/library/contains |
// v10
spotifyApi.saveItemsToLibrary("spotify:album:id1", "spotify:track:id2").build().execute();
spotifyApi.checkUsersSavedItems("spotify:album:id1", "spotify:track:id2").build().execute();
The per-type methods (saveAlbumsForCurrentUser, saveTracksForCurrentUser and the rest) still work and are deprecated in favour of these.
Playlist items on the /items path, replacing the /tracks path:
| Method | Endpoint |
|---|---|
getPlaylistItems |
GET /playlists/{playlist_id}/items |
removePlaylistItems |
DELETE /playlists/{playlist_id}/items |
updatePlaylistsItemsReorder |
PUT /playlists/{playlist_id}/items |
updatePlaylistsItemsReplace |
PUT /playlists/{playlist_id}/items |
And getAvailableMarkets ⚠️ for GET /markets.
Model objects are deserialized reflectively by Gson. The Jackson annotations every model carried are gone, along with the Jackson dependency itself, because nothing in the library ever constructed an ObjectMapper. With nv-i18n dropped as well, the library now pulls in only Gson and HttpComponents.
This only affects you if you fed these model classes into your own ObjectMapper.
The @JsonDeserialize annotations gave you builder-based deserialization for free, and you now have to configure that yourself.
Nothing changes for code that goes through the library.
The jar is an explicit module named se.michaelthelin.spotify, replacing the Automatic-Module-Name it carried before.
The name is unchanged, so an existing requires se.michaelthelin.spotify; keeps working.
What changes is that the module now declares its dependencies, so a consumer on the module path no longer has to guess.
Gson and both HttpComponents modules are requires transitive, because types from all three appear in this library’s own public signatures.
That also means a jlink image can include the library as a real module rather than folding it into a merged one.
Nothing in this affects code on the classpath.
49 of the 114 request builders carry @Deprecated, up from none in 9.4.0, where the marker only ever sat on individual builder methods.
That number is large because it now tracks Spotify’s specification: a builder is deprecated when the endpoint behind it is marked deprecated there, not because this library plans to remove it.
None of them are scheduled for removal, and they keep working for clients whose credentials still reach the endpoint.
Each one names its replacement in the @deprecated Javadoc tag, and the example index marks them with ⚠️.