A Kotlin implementation of the Spotify Web API,
supporting Kotlin/JS, Kotlin/Android, Kotlin/JVM, and Kotlin/Native
(macOS, Windows, Linux).
This library has first-class support for Java and is a viable alternative for Java development.
Please see the Java section for more details.
Use this library in Kotlin, Java, JavaScript, Swift, or native code! Because this library targets both iOS and Android, it can also be used in KMM (Kotlin Multiplatform Mobile) applications as a shared source.
Note: For information on how to integrate implicit/PKCE authentication, Spotify app remote, and Spotify broadcast notifications into
your application, please see the Android README.
If you declare any release types not named debug or release, you may see "Could not resolve com.adamratzman:spotify-api-kotlin-android:VERSION". You need to do the following for each release type not named debug or release:
To successfully build, you might need to exclude kotlin_module files from the packaging. To do this, inside the android/buildTypes/release closure, you would put:
You can find a simple sample application demonstrating how to use spotify-web-api-kotlin in a modern Android app, as well as how to integrate with the Spotify app, here.
Documentation
The spotify-web-api-kotlin JavaDocs are hosted here.
Please feel free to open an issue/discussion on GitHub or Discord if you need access to one of these features
or have an interest in implementing one, as direction can be provided.
Creating a new api instance
To decide which api you need (SpotifyAppApi, SpotifyClientApi, SpotifyImplicitGrantApi), you can refer
to the sections below or the Spotify authorization guide. In general:
If you don't need client resources, use SpotifyAppApi
If you're using the api in a backend application, use SpotifyClientApi (with or without PKCE)
If you're using the api in Kotlin/JS browser, use SpotifyImplicitGrantApi
If you need access to client resources in an Android or other application, use SpotifyClientApi with PKCE
This provides access only to public Spotify endpoints.
Use this when you have a server-side application. Note that implicit grant authorization
provides a higher api ratelimit, so consider using implicit grant if your application has
significant usage.
By default, the SpotifyApi Token automatically regenerates when needed.
This can be changed by overriding the automaticRefresh builder setting.
There are four exposed builders, depending on the level of control you need over api creation.
Please see the spotifyAppApi builder docs for a full list of available builders.
You will need:
Spotify application client id
Spotify application client secret
Example creation (default settings)
val api = spotifyAppApi("clientId", "clientSecret").build() // create and build apiprintln(api.browse.getNewReleases()) // use it
Example creation, using an existing Token and setting automatic token refresh to false
val token = spotifyAppApi(spotifyClientId, spotifyClientSecret).build().token
val api = spotifyAppApi(
"clientId",
"clientSecret",
token
) {
automaticRefresh =false
}.build()
println(api.browse.getNewReleases()) // use it
SpotifyClientApi
The SpotifyClientApi is a superset of SpotifyApi; thus, nothing changes if you want to
access public data.
This library does not provide a method to retrieve the code from your callback url; instead,
you must implement that with a web server.
Automatic Token refresh is available only when building with an authorization code or a
Token object. Otherwise, it will expire Token.expiresIn seconds after creation.
Make sure your application has requested the proper Scopes in order to
ensure proper function of this library. The api option requiredScopes allows you to verify
that a client has actually authorized with the scopes you are expecting.
You will need:
Spotify application client id
Spotify application client secret (if not using PKCE)
Spotify application redirect uri
To choose which client authorization method (PKCE or non-PKCE) to use
PKCE
Use the PKCE builders and helper methods if you are using the Spotify client authorization PKCE flow.
Building via PKCE returns a SpotifyClientApi which has modified refresh logic.
Use cases:
You are using this library in an application (likely Android), or do not want to expose the client secret.
To learn more about the PKCE flow, please read the Spotify authorization guide.
Some highlights about the flow are:
It is refreshable, but each refresh token can only be used once. This library handles token refresh automatically by default
It does not require a client secret; instead, a set redirect uri and a random code verifier
are used to verify the authenticity of the authorization.
A code verifier is required. The code verifier is "a cryptographically random string between 43 and 128 characters in length.
It can contain letters, digits, underscores, periods, hyphens, or tildes."
A code challenge is required. "In order to generate the code challenge, your app should
hash the code verifier using the SHA256 algorithm. Then, base64url encode the hash that you generated."
When creating a pkce api instance, the code verifier is passed in by you and compared to
the code challenge used to authorize the user.
This library contains helpful methods that can be used to simplify the PKCE authorization process.
This includes getSpotifyPkceCodeChallenge, which SHA256 hashes and base64url encodes the code
challenge, and getSpotifyPkceAuthorizationUrl, which allows you to generate an easy authorization url for PKCE flow.
Takeaway: Use PKCE authorization flow in applications where you cannot secure the client secret.
To get a PKCE authorization url, to which you can redirect a user, you can use the getSpotifyPkceAuthorizationUrl
top-level method. An example is shown below, requesting 4 different scopes.
There is also an optional parameter state, which helps you verify the authorization.
Note: If you want automatic token refresh, you need to pass in your application client id and redirect uri
when using the spotifyClientPkceApi.
Example: A user has authorized your application. You now have the authorization code obtained after the user was redirected back to your application. You want to create a new SpotifyClientApi.
val codeVerifier ="thisisaveryrandomalphanumericcodeverifierandisgreaterthan43characters"val code:String=...
val api = spotifyClientPkceApi(
"clientId", // optional. include for token refresh"your-redirect-uri", // optional. include for token refresh
code,
codeVerifier // the same code verifier you used to generate the code challenge
) {
retryWhenRateLimited =false
}.build()
println(api.library.getSavedTracks().take(10).filterNotNull().map { it.track.name })
To get a non-PKCE authorization url, to which you can redirect a user, you can use the getSpotifyAuthorizationUrl
top-level method. An example is shown below, requesting 4 different scopes.
val url:String= getSpotifyAuthorizationUrl(
SpotifyScope.PLAYLIST_READ_PRIVATE,
SpotifyScope.PLAYLIST_MODIFY_PRIVATE,
SpotifyScope.USER_FOLLOW_READ,
SpotifyScope.USER_LIBRARY_MODIFY,
clientId ="clientId",
redirectUri ="your-redirect-uri",
state ="your-special-state"// optional
)
There are also several optional parameters, allowing you to set whether the authorization url is meant
for implicit grant flow, the state, and whether a re-authorization dialog should be shown to users.
There are several exposed builders, depending on the level of control you need over api creation.
Please see the spotifyClientApi builder docs for a full list of available builders.
Example: You've redirected the user back to your web server and have an authorization code (code).
In this example, automatic token refresh is turned on by default.
val authCode =""val api = spotifyClientApi(
"clientId",
"clientSecret",
"your-redirect-uri",
authCode
).build() // create and build apiprintln(api.personalization.getTopTracks(limit =5).items.map { it.name }) // print user top tracks
Example: You've saved a user's token from previous authorization and need to create an api instance.
In this case, if you provide a client id to the builder, automatic token refresh will also be turned on.
val token:Token=... // your existing tokenval api = spotifyClientApi(
"clientId",
"clientSecret",
"your-redirect-uri",
token
) {
onTokenRefresh = {
println("Token refreshed at ${System.currentTimeMillis()}")
}
}.build()
println(api.personalization.getTopTracks(limit =5).items.map { it.name })
SpotifyImplicitGrantApi
Use the SpotifyImplicitGrantApi if you are using the Spotify implicit grant flow.
SpotifyImplicitGrantApi is a superset of SpotifyClientApi.
Unlike the other builders, the spotifyImplicitGrantApi builder method directly returns
a SpotifyImplicitGrantApi instead of an api builder.
Use cases:
You are using the Kotlin/JS target for this library.
Your frontend Javascript passes the token received through the implicit grant flow to your
backend, where it is then used to create an api instance.
To learn more about the implicit grant flow, please read the Spotify authorization guide.
Some highlights about the flow are:
The Kotlin/JS target contains the parseSpotifyCallbackHashToToken method, which will parse the hash
for the current url into a Token object, with which you can then instantiate the api.
Takeaway: There are two ways to use implicit grant flow, browser-side only and browser and
server. This library provides easy access for both.
Example
val token:Token=...
val api = spotifyImplicitGrantApi(
null,
null,
token
) // create api. there is no need to build it println(api.personalization.getTopArtists(limit =1)[0].name) // use it
SpotifyApiBuilder Block & setting API options
There are three pluggable blocks in each api's corresponding builder
credentials lets you set the client id, client secret, and redirect uri
authorization lets you set the type of api authorization you are using.
Acceptable types include: an authorization code, a Token object, a Token's access code string, and an optional refresh token string
options lets you configure API options to your own specific needs
API options
This library does not attempt to be prescriptivist.
All API options are located in SpotifyApiOptions and their default values can be overridden; however, use caution in doing so, as
most of the default values either allow for significant performance or feature enhancements to the API instance.
useCache: Set whether to cache requests. Default: true
cacheLimit: The maximum amount of cached requests allowed at one time. Null means no limit. Default: 200
automaticRefresh: Enable or disable automatic refresh of the Spotify access token when it expires. Default: true
retryWhenRateLimited: Set whether to block the current thread and wait until the API can retry the request. Default: true
enableLogger: Set whether to enable to the exception logger. Default: true
testTokenValidity: After API creation, test whether the token is valid by performing a lightweight request. Default: false
defaultLimit: The default amount of objects to retrieve in one request. Default: 50
json: The Json serializer/deserializer instance.
allowBulkRequests: Allow splitting too-large requests into smaller, allowable api requests. Default: true
requestTimeoutMillis: The maximum time, in milliseconds, before terminating an http request. Default: 100000ms
refreshTokenProducer: Provide if you want to use your own logic when refreshing a Spotify token.
requiredScopes: Scopes that your application requires to function (only applicable to SpotifyClientApi and SpotifyImplicitGrantApi).
This verifies that the token your user authorized with actually contains the scopes your
application needs to function.
Notes:
Unless you have a good reason otherwise, useCache should be true
cacheLimit is per Endpoint, not per API. Don't be surprised if you end up with over 200 items in your cache with the default settings.
automaticRefresh is disabled when client secret is not provided, or if tokenString is provided in SpotifyClientApi
allowBulkRequests for example, lets you query 80 artists in one wrapper call by splitting it into 50 artists + 30 artists
refreshTokenProducer is useful when you want to re-authorize with the Spotify Auth SDK or elsewhere
Using the API
APIs available in all SpotifyApi instances, including SpotifyClientApi and SpotifyImplicitGrantApi:
SearchApi (searching items)
AlbumApi (get information about albums)
BrowseApi (browse new releases, featured playlists, categories, and recommendations)
ArtistApi (get information about artists)
PlaylistApi (get information about playlists)
UserApi (get public information about users on Spotify)
APIs available only in SpotifyClientApi and SpotifyImplicitGrantApi instances:
ClientSearchApi (all the methods in SearchApi, and searching shows and episodes)
EpisodeApi (get information about episodes)
ShowApi (get information about shows)
ClientPlaylistApi (all the methods in PlaylistApi, and get and manage user playlists)
ClientProfileApi (all the methods in UserApi, and get the user profile, depending on scopes)
ClientFollowingApi (all the methods in FollowingApi, and get and manage following of playlists, artists, and users)
ClientPersonalizationApi (get user top tracks and artists)
ClientLibraryApi (get and manage saved tracks and albums)
ClientPlayerApi (view and control Spotify playback)
Platform-specific wrappers and information
Java
This library has first-class support for Java! You have two choices when using this library: async-only with Kotlin
suspend functions (using SpotifyContinuation), or by using the SpotifyRestAction class. Using SpotifyRestActions are
recommended.
What is the SpotifyRestAction class and how do I use it?
Abstracting requests into a SpotifyRestAction class allows for a lot of flexibility in sending and receiving requests.
This class includes options for asynchronous and blocking execution in all endpoints. However,
due to this, you must call one of the provided methods in order for the call
to execute! The SpotifyRestAction provides many methods and fields for use, including blocking and asynchronous ones. For example,
hasRun() tells you whether the rest action has been started
hasCompleted() tells you whether this rest action has been fully executed and completed
complete() blocks the current thread and returns the result
suspendComplete(context: CoroutineContext = Dispatchers.Default) switches to given context, invokes the supplier, and synchronously retrieves the result.
suspendQueue() suspends the coroutine, invokes the supplier asynchronously, and resumes with the result
queue() executes and immediately returns
queue(consumer: (T) -> Unit) executes the provided callback as soon as the request
is asynchronously evaluated
queueAfter(quantity: Int, timeUnit: TimeUnit, consumer: (T) -> Unit) executes the
provided callback after the provided time. As long as supplier execution is less than the provided
time, this will likely be accurate within a few milliseconds.
asFuture() transforms the supplier into a CompletableFuture (only JVM)
Here's an example of how easy it is to use spotify-web-api-kotlin with a SpotifyRestAction:
varapi = SpotifyApiBuilderKt.spotifyAppApi(Const.clientId, Const.clientSecret).buildRestAction(true).complete();
varalbum = api.getAlbums().getAlbumRestAction("spotify:album:0b23AHutIA1BOW0u1dZ6wM", null).complete();
System.out.println("Album name is: " + album.getName());
Integrating with Kotlin suspend functions via Java Continuations
Unfortunately, coroutines don't play very nicely with Java code. Fortunately, however, we provide a wrapper around Kotlin's
Continuation class that allows you to directly implement onSuccess and onFailure handlers on API methods.