spotify-web-api-java

You and me
Spotify has a history of pushing considerable breaking changes to their API and documentation without prior notice. Additionally, Spotify is known for not responding to developers’ inquiries.
This can suddenly render development on top of their platform useless, reportedly putting university projects and job applications at risk. Be encouraged to share your feedback with Spotify on a platform of your choice.
[1] [2]
Android Developers
You cannot use this library for Android app development. Have a look at adamint/spotify-web-api-kotlin, kaaes/spotify-web-api-android and Spotify’s Android SDK and see why.

Spotify Web API Java

CI codecov

This is a Java wrapper/client for the Spotify Web API.

Table of Contents

  1. Installation
    1. Jitpack
  2. Documentation
  3. Migration
  4. General Usage
    1. Authorization
  5. Examples
  6. Support
  7. Contributions

Installation

The artifact is available through Maven Central via Sonatype. Or to use a snapshot of the latest commit you can use jitpack.io as described further down below.

The library requires Java 9 or later. It is an explicit Java module named se.michaelthelin.spotify, so on the module path add requires se.michaelthelin.spotify; to your module-info.java; on the classpath nothing is needed.

Maven

Latest official release:

<dependency>
  <groupId>se.michaelthelin.spotify</groupId>
  <artifactId>spotify-web-api-java</artifactId>
  <version>10.1.0</version>
</dependency>

Latest snapshot:

<dependency>
  <groupId>com.github.spotify-web-api-java</groupId>
  <artifactId>spotify-web-api-java</artifactId>
  <version>main-SNAPSHOT</version>
</dependency>

Gradle

Latest official release:

implementation 'se.michaelthelin.spotify:spotify-web-api-java:10.1.0'

Latest snapshot:

implementation 'com.github.spotify-web-api-java:spotify-web-api-java:main-SNAPSHOT'

Jitpack

In order to use Jitpack you need to add their repository to your build:

Maven

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

Gradle

allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}

Documentation

See this project’s Javadoc.

A huge thanks to c-schuhmann for his amazing work on the documentation!

Migration

Upgrading from an earlier major version? See the migration guide.

General Usage

// For all requests an access token is needed
SpotifyApi spotifyApi = new SpotifyApi.Builder()
        .setAccessToken("taHZ2SdB-bPA3FsK3D7ZN5npZS47cMy-IEySVEGttOhXmqaVAIo0ESvTCLjLBifhHOHOIuhFUKPW1WMDP7w6dj3MAZdWT8CLI2MkZaXbYLTeoDvXesf2eeiLYPBGdx8tIwQJKgV8XdnzH_DONk")
        .build();

// Create a request object with the optional parameter "market"
final GetSomethingRequest getSomethingRequest = spotifyApi.getSomething("qKRpDADUKrFeKhFHDMdfcu")
        .market(CountryCode.SE)
        .build();

void getSomething_Sync() {
  try {
    // Execute the request synchronous
    final Something something = getSomethingRequest.execute();

    // Print something's name
    System.out.println("Name: " + something.getName());
  } catch (Exception e) {
    System.out.println("Something went wrong!\n" + e.getMessage());
  }
}

void getSomething_Async() {
  try {
    // Execute the request asynchronous
    final CompletableFuture<Something> somethingFuture = getSomethingRequest.executeAsync();

    // Do other things...

    // Wait for the request to complete
    final Something something = somethingFuture.get();

    // Print something's name
    System.out.println("Name: " + something.getName());
  } catch (Exception e) {
    System.out.println("Something went wrong!\n" + e.getMessage());
  }
}

Authorization

Please see Spotify’s authorization guide too!

For authorization requests the API object requires at least to have your application’s client ID and client secret set as its properties. When using the authorization code flow, the application’s redirect URI is required too. Those properties will then be automatically used by functions that depend on them.

SpotifyApi spotifyApi = new SpotifyApi.Builder()
  .setClientId("<your_client_id>")
  .setClientSecret("<your_client_secret>")
  .setRedirectUri("<your_redirect_uri>")
  .build();

There are three ways to retrieving an access token:

Client Credentials Flow

Use the client credentials flow when the requests don’t require permission from a specific user. This flow doesn’t return a refresh token and is useful for simple requests, like fetching albums or searching for tracks.

Example: ClientCredentialsExample.java

Authorization Code Flow

Using the authorization code flow to retrieve an access token is necessary if the requests are bound to a specific user. Using this flow returns a refresh token, which can be used to renew the access token before it expires. This is how it works:

  1. The authorization code flow requires a code, which is part of the redirectUri’s query parameters when the user has opened a custom URL in a browser and authorized the application.

    Example: AuthorizationCodeUriExample.java

  2. When the code has been retrieved, it can be used in another request to get an access token as well as a refresh token.

    Example: AuthorizationCodeExample.java

  3. Now, the refresh token in turn can be used in a loop to retrieve new access and refresh tokens.

    Example: AuthorizationCodeRefreshExample.java


When you’ve fetched an access and refresh token, you have to add them to your API properties for automatic usage in requests. The implementer has to handle the access token’s expiration.

spotifyApi.setAccessToken("<your_access_token>");
spotifyApi.setRefreshToken("<your_refresh_token>");

Authorization Code Flow with Proof Key for Code Exchange (PKCE)

The authorization code flow with PKCE is quite like the Authorization Code Flow except that no client secret is necessary (therefore, it is a good option for mobile and desktop applications). Instead, your application should generate a code verifier and a code challenge before each authentication request.

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. To generate the code challenge, your app should hash the code verifier using the SHA256 algorithm. Then, base64url encode the hash that you generated.

This flow provides your app with an access token which can be refreshed, too. The steps are similar as above:

  1. The authorization code flow with PKCE requires a code, which is part of the redirectUri’s query parameters when the user has opened a custom URL in a browser and authorized the application. The code challenge is supplied to this request as a query parameter.

    Example: AuthorizationCodePKCEUriExample.java

  2. When the code has been retrieved, it can be used in another request to get an access token as well as a refresh token. The code verifier is supplied to this request a query parameter.

    Example: AuthorizationCodePKCEExample.java

  3. Now, the refresh token in turn can be used in a loop to retrieve new access and refresh tokens.

    Example: AuthorizationCodePKCERefreshExample.java


When you have fetched an access and refresh token, you have to add them to your API properties for automatic usage in requests. The implementer must handle the access token’s expiration. The refresh token can be exchanged for an access token only once, after which it becomes invalid.

Examples

Endpoints that Spotify deprecated are marked with ⚠️. They keep working for clients whose credentials still reach them and none of them are scheduled for removal. See the @deprecated Javadoc tag on the corresponding request class for the recommended alternative.

Support

Please ask questions about using the library in help networks like StackOverflow with the tag spotify-web-api-java, where they get quick and helpful answers.

Issues are for bug reports and for questions about this project’s source code.

Contributions

Contributions are very welcome. CONTRIBUTING.md describes how the code is organized, how to build and test it, and what a pull request needs to be accepted.