Where should you start?

Explore our catalogue or learn about our streaming API documentation, jump to our API usage and brand guidelines or check the full Open API Terms & Conditions

Like what you see?

SIGN UP TO OUR API

Guides to get you started

The 7digital API will give you access to an extensive music catalogue licensed by major and indie labels, covering every genre imaginable. This walk-through guide will help you with the steps for creating a web page that enables searching of the 7digital catalogue and streaming previews.

Access locker and download tracks

Get started - accessing your 7digital cloud locker

Any music you purchase from 7digital is stored securely in a cloud-based locker, so that you can access it anywhere. We don't believe in tying you to a particular device or platform which is why, in addition to range of 7digital Apps for different operating systems, we also provide developers with an open Locker API that allows you to access music stored in your locker from your own application.

Premium API partners can in very similar way to the walkthrough below integrated Purchasing API for a full featured download store. Have a look at all the building blocks you can play with.

This walk through will guide you through the process of creating a web page that enables retrieving a 7digital users locker and downloading music from it. It should take around 10 to 15 minutes to complete. Before starting you can check out a working example of the result. Link to the full source code be found at the end of this article.

The Locker API reference documentation will provide you with all the additional details beyond the scope of this basic usage walkthrough.

Get ready

Pre-requisites should come down to a text editor, a browser and a connection to the internet. Oh, and don't forget to sign up for a 7digital API key.

Let's begin by creating an empty html page and referencing the following libraries: jQuery, jQuery-Cookie and OAuthSimple.

<html>
  <head>
    <title>7digital Locker</title>
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script src="tools/OAuthSimple/js/OAuthSimple.js"></script>
    <script src="tools/jquery-cookie/jquery.cookie.js"></script>
  </head>
  <body>
  </body>
</html>

User authorisation - OAuth handshake

Before an application can access user's locker the user needs to grant this application a permission to act on his behalf. The 7digital API uses OAuth for delegated authentication (i.e. the user does not share their username or password with the applicaton). This often referred to as 3-legged OAuth since there's 3 parties involved - the user, 7digital and your app.

The delegated authentication process - OAuth handshake - consists of 3 steps:

  1. getting a request token
  2. user authorising the request token on 7digital
  3. exchanging an authorised request token for an access token

After successful completion of the handshake your application can start using the acquired access token to access user's resources - in our case the user's locker.

Get Request Token

The below will sign and invoke the oauth/requesttoken endpoint to get a new request token.
It will also store the new request token secret in a cookie. This will be used later when we exchange the authorised request token for an access token.

function GetRequestToken(){
  var oauthSimpleSigner = OAuthSimple('YOUR_KEY_HERE', 'YOUR_SECRET_HERE');
  var signedUrl = oauthSimpleSigner.sign({
                    action: 'GET',
                    path: 'https://api.7digital.com/1.2/oauth/requesttoken'
                  }).signed_url;

  $.ajax({
      type: "GET",
      dataType: "xml",
      url: signedUrl,
      success: function(data) {
                 var requestTokenSecret = $(data).find("oauth_token_secret").text()
                 $.cookie("7digitalApiRequestTokenSecret", requestTokenSecret);
               
                 var requestTokenKey = $(data).find("oauth_token").text();
                 RedirectToLoginPageToAuthoriseRequestToken(requestTokenKey);
               }
      });
    };

Authorise Request Token

After retrieving a new request token, the user is redirected to the 7digital accounts login page in order to authorise the newly acquired request token.
This redirect includes the newly requested token key and a return url set to the current page.

function RedirectToLoginPageToAuthoriseRequestToken(requestTokenKey) {
  var authoriseRequestTokenUrl = "https://account.7digital.com/<ConsumerKey>/oauth/authorise";
  authoriseRequestTokenUrl = authoriseRequestTokenUrl.replace("<ConsumerKey>", "YOUR_KEY_HERE");
  authoriseRequestTokenUrl = authoriseRequestTokenUrl.concat("?oauth_token=" + requestTokenKey);
  authoriseRequestTokenUrl = authoriseRequestTokenUrl.concat("&oauth_callback=" + window.location.href.split('?')[0]);

  window.location.href = authoriseRequestTokenUrl;
};

After authorising the request token, the 7digital accounts login page will redirect the user back.
The below will detect when that happens, and if the authorisation was successful it will proceed to the final step of the authorisation process.

$(document).ready(function() {
  var authorisedRequestTokenKey = getURLParameter("oauth_token");
  var authoriseRequestTokenStatus = getURLParameter("status");
       
  if (authorisedRequestTokenKey != 'null' && authoriseRequestTokenStatus != 'null') {
    ExchangeRequestToken(authorisedRequestTokenKey);
  }
});
   
function getURLParameter(name) {
  return decodeURI((RegExp(name + '=' + '(.+?)(&|$)').exec(location.search)||[,null])[1]);
};

Exchange Request Token

The final step of the authorisation process is to exchange the authorised request token for an access token.
The below will sign (with the consumer and the authorised request token credentials) and invoke the oauth/accesstoken endpoint to get an access token.
It will also store the retrieved access token key and secret in cookies for future uses.

After successful completion of the authentication process, the below will also initiate the retrieval of the users locker.

function ExchangeRequestToken(requestTokenKey){
  var signedUrl = (new OAuthSimple()).sign({
path:'https://api.7digital.com/1.2/oauth/accesstoken',
parameters:"oauth_token=" + requestTokenKey,
signatures:{
  'consumer_key':'YOUR_KEY_HERE',
      'shared_secret':'YOUR_SECRET_HERE',
      'access_token':requestTokenKey,
      'access_secret':$.cookie("7digitalApiRequestTokenSecret")}
  }).signed_url;

  $.ajax({
    type: "GET",
    dataType: "xml",
    url: signedUrl,
    success: function(data) {
      var responseInternalErrorMessage = $(data).find("errorMessage").text();
      if (responseInternalErrorMessage) {
        alert("Error exchanging request token for an access token... message: " + responseInternalErrorMessage);
      } else {
        var accessTokenKey = $(data).find("oauth_token").text();
        var accessTokenSecret = $(data).find("oauth_token_secret").text()
        GetUsersLocker(accessTokenKey, accessTokenSecret);
      }
    }
  });
};

Reading user's locker

Next add the following touch to take care of getting a users locker.

function GetUsersLocker(accessTokenKey, accessTokenSecret){
  var signedUrl = (new OAuthSimple()).sign({
            path:'https://api.7digital.com/1.2/user/locker',
            signatures:{
              'consumer_key':'YOUR_KEY_HERE',
              'shared_secret':'YOUR_SECRET_HERE',
              'access_token':accessTokenKey,
              'access_secret':accessTokenSecret}
          }).signed_url;
 
  $.ajax({
    type: "GET",
    dataType: "xml",
    async: false,
    url: signedUrl,                           
    success: function(data) {
      $("#results").empty();
      $(data).find("lockerRelease").each(function(){
        var releaseId = $(this).find("release").attr("id");
        var releaseTitle = $(this).find("release").find("title").text();
        var releaseArtist = $(this).find("release").find("artist").find("appearsAs").text();
        var releaseImage = $(this).find("release").find("image").text();
       
        $(this).find("lockerTrack").each(function(){
          var trackId = $(this).find("track").attr("id");
          var trackTitle = $(this).find("track").find("title").text();
          var firstFormatDownloadUrl = $(this).find("downloadUrl").first().find("url").text();

          $('<li>'
              +'<img src="' + releaseImage + '" /><br/>'
              + '<strong>Title:</strong> <a class="preview" href="' + firstFormatDownloadUrl + '" >' + trackTitle + '</a><br/>'
              + '<strong>Artist:</strong> ' + releaseArtist + '<br/>'
              + '<strong>Release:</strong> ' + releaseTitle
            + '</li>').appendTo('#results');
        });
      });
    }
  });
};

Hook it all up!

To complete this walkthrough, we'll add a "Get Users Locker" button and a results list view.
You can drop the following snippet of html directly into the body of the page.

<input type="submit" value="Get Users Locker" id="getUsersLockerButton"/>
<ul id="results"></ul>

And hook up the "Get Users Locker" button to run through the OAuth 3-Legged process and retrieve the users locker.

$(document).ready(function(){
  $("#getUsersLockerButton").click(function(){
    GetRequestToken();
  });
});

Where next?

You can find the full source of the example on Github along with a live demo.

And make sure you read through the Locker API reference documentation which will provide you with all the additional details beyond the scope of this walkthrough.

Explore our catalogue

The 7digital API will give you access to an extensive music catalogue licensed by major and indie labels covering every genre imaginable. The Catalogue API provides you with an interface to navigate through and explore the catalogue including:

  • searching for artist, releases and tracks
  • browsing music by genres (tags)
  • artist discographies and artists' most popular tracks
  • 7digital charts
  • recommendations and similar artists
  • playing preview clips for
  • high quality official album artwork and artist pictures

Check out the API overview for a full list of functionality available.

Getting started: Searching catalogue and streaming previews

This walk through will guide you through the process of creating a web page that enables searching of the 7digital catalogue and streaming previews. It should take around 5 to 10 minutes and will look like this working example. If you have any troubles following along, please see the full source code listing at the the end of this article.

Before starting you can check out a working example of the final result.

The Catalogue API reference documentation will provide you with all the additional details beyond the scope of this basic usage walkthrough.

The 4 steps required to search and stream are:

  1. Make a request to the track search endpoint with a search term
  2. Select the ID of a track from the response to stream
  3. Make a request to the track preview endpoint with the selected track's ID
  4. Use the URL from the track preview response to stream a preview of the track

 

There is also an optional section at the bottom of this walk-through that shows how to display the image of the album the selected track belongs to along side a list of all the tracks on the album. This consists of two extra steps:

  1. Take the "releaseId" for the selected track from the initial track search response
  2. Use the releaseId to query the release tracks endpoint

This process will be wired-up and made interactive with short snippets of JavaScript and HTML5. All you will need for this tutorial, then, is a text editor (sublime text, notepad++, etc), and a recent version of your favourite browser if you want to play MP3 using HTML5.

Getting started

Pre-requisites should come down to a text editor, a browser and a connection to the internet. Oh, and don't forget to sign up for a 7digital API key.

Let's begin by creating an empty html page with JQuery imported:

<!Doctype html>
<html>
    <head>
        <title>Searching and streaming with 7digital's API</title>
        <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
  </head>
  <body>
  </body>
</html>

Add search capability

Let's focus on searching the 7digital catalogue for now and add preview playback later. A number of search endpoints are available, but track search is perfect for this example - it returns a list of tracks that match a search term.
To add a search bar, button and results view, drop the following snippet of html directly into the body of the page:

<input type="text" id="term">
<input type="submit" value="search" id="search"/>
<ol id="results"></ol>

Now add this touch of JavaScript (below the JQuery script) that takes the search term from the search box, makes the track search request and populates the page with the results when the button is clicked:

<script type="text/javascript">
    $(document).ready(function(){
        // call 7digital's track search api using value from search box as search term
        $("#search").click(function(){
            $.getJSON("http://api.7digital.com/1.2/track/search",  // ask API to return json (accept header = application/json)
                {
                    q: $("#term").val(),
                    oauth_consumer_key: "YOUR_KEY_HERE",
                    pageSize: 4
                })
             .done(function(json){
                 $("#results").empty(); // clear previous result
                 $.each(json.searchResults.searchResult, function(key, sr) {
                     var track = sr.track;
                     $('<li><a class="preview" href="#" >' + 'Title: ' + track.title + '</a><br/>'
                                        + 'Artist: ' + track.artist.name + '<br/>'
                      + 'Release: ' + track.release.title + '<br/>'
                      + '<input type="hidden" class="trackId" value="' + track.id + '" />'
                      + '</li>')
                     .appendTo('#results');   
                });
             });
        });
    });
</script>

Most API endpoints support JSON or XML depending on the value supplied in the accept header. The above example uses JSON to request the following url: http://api.7digital.com/1.2/track/search?q=YOUR_SEARCH_TERM_HERE&pageSiz.... If you paste this URL into a browser and replace the search term, you can see the full response format.
After making the request, the second part of the example (line 11) takes each search result and displays the track, release and artist name as a list item. Notice the track title is a link, whilst there is hidden field containing the track's ID - this will be explained shortly.

Add previews playback

To add streaming of previews, some JavaScript will be added to intercept clicks on a track's title, take the track's ID from the hidden field next to it, and make a request to the track preview endpoint. This will return a URL to the mp3 file. In this example it will be streamed using a HTML5 audio tag and touch of JavaScript.
First add a HTML5 audio tag to the bottom of the page's body (below the results list):

<audio id="player" style="width:550px; margin: 0 auto; display:block;" type="audio/mp3" controls></audio>

Then add this JavaScript directly below the search request (the end of the "$("#search").click.." block) inside the same document ready handler. This time the example shows an XML request (the default content-type):

// when a track is clicked, get the preview URL and start to play it
$("body").on("click", "a.preview", function(event){ // using on because link dynamically created
    event.preventDefault(); // cancel the normal follow link behaviour
    $.get("http://api.7digital.com/1.2/track/preview",
        {
            trackId: $(this).siblings(".trackId").val(), // get track id from hidden field next to link in dom
            redirect: false, // we don't want to be redirected to the file
            oauth_consumer_key: "YOUR_KEY_HERE"
        })
     .done(function(xml) {
         var url = $(xml).find("url").text();
         $("#player").attr("src", url); // set url of song on player
         $("#player").get(0).load(); // load song on player
         $("#player").get(0).play(); // start player
     });
});

When you click on a track title the preview should now start streaming inside the browser. If it doesn't, compare your page with example at the bottom of this page. Also check your browser does support MP3 playback using HTML5 Audio (For browsers with lack of MP3 support, notably Firefox, a fallback to Adobe Flash player will need to be implemented, e.g. using jPlayer, which is beyond the scope of this simple walkthrough)

Bonus: Display album artwork and list of tracks

To improve user experience and make related tracks discoverable, the image of the selected track's album will now be displayed with a list of all the other tracks on the album.
This can be achieved by updating the JavaScript that handles the search button click event to add two hidden fields for each search result - one with the release's ID and one with the a url for the release's image (add them next to the hidden field with the track's ID):

$('<li><a class="preview" href="#" >' + 'Title: ' + track.title + '</a><br/>'
    + 'Artist: ' + track.artist.name + '<br/>'
    + 'Release: ' + track.release.title + '<br/>'
    + '<input type="hidden" class="trackId" value="' + track.id + '" />'
    + '<input type="hidden" class="releaseId" value="' + track.release.id + '" />'
    + '<input type="hidden" class="releaseImage" value="' + track.release.image + '" />'
    + '</li>'
)

Now the release's ID can be used to retrieve the album's track listing by calling the release tracks endpoint when a user streams a preview.

// when a track is clicked, get the preview URL and start to play it
$("body").on("click", "a.preview", function(event){ // using on because link dynamically created
    event.preventDefault(); // cancel the normal follow link behaviour
   
    // clear previously-selected track list and image
    $('img.relImg').remove();
    $('div.trackListTrack').remove();
 
    // add the image below the player
    $("audio").after('<img class="relImg" src="' + $(this).siblings(".releaseImage").val() + '" />');
 
    // grab the list of tracks from the release/tracks endpoint
    $.get("http://api.7digital.com/1.2/release/tracks",
        {
             releaseId: $(this).siblings(".releaseId").val(),
             shopId: 34,
             oauth_consumer_key: "YOUR_KEY_HERE",
             pageSize: 4 // change to suit your needs
         })
         .done(function(xml){
            // add a link to each track below the album's image
             $.each($(xml).find("track"), function(key, track){
                $("img.relImg").after('<div class="trackListTrack" >'
                                     + '<a href="' + $(track).find("url") + '">'
                                     + $(track).find("title").text() + '</a></div>');
                });
            });
 
    $.get("http://api.7digital.com/1.2/track/preview",


Above is the first part of the updated body click handler, notice how the the hidden field containing the release's image is used to add an image, whilst the hidden field containing the release's ID is used to query release tracks.
All that's special inside the callback passed into the done method (at the bottom) is how a link is created to each track from the response using the "url" and "title" fields available on each "track" element.

Where next?

You can find the full source of the example on Github along with a live demo.

And make sure you read through the Catalogue API reference documentation which will provide you with all the additional details beyond the scope of this walkthrough.

As well as searching for tracks, you might want to investigate searching for artists using the artist search endpoint, then artist releases or artist toptracks. Alternatively, have a look at the release search and release tracks endpoints to search and explore music albums.

Streaming

In addition to providing high quality downloads 7digital also offers range of streaming services. These typically fall into one of these categories:

  • Locker streaming - allows users to stream previously purchased music directly from their cloud locker without the need to download the audio files first. Check out our walkthrough on accessing a 7digital locker for an example how to get started with the Locker API.
  • On demand, Interactive streaming - our platform supports full interactive on demand streaming where the user has access to our entire catalogue in the cloud, and we hold both label and publishing licenses.  These rights are generally quite expensive, the infrastructure is highly complex, and the business model requires large-scale adoption in order to succeed.
  • Radio streaming - you can use our licensed catalogue to create a radio stream that complies with the limited-interactivity rules of the US Digital Millennium Copyright Act (DMCA). See our getting started example of how to build such a radio.

But with our API you're certainly not limited just to the above use cases and we can support practically any streaming service (e.g. collaborative radio, music jukeboxes, etc). Please contact us for further information on licensing and technical guidance.

Take a look at our full streaming API documentation.

API implementation best practices

Building music services is fun and challenging and we've been doing it for over 10 years so we've gotten it down to a science. Based on our experience here are some of the best practices you should follow to build a robust and easy to maintain app:

Parsing API responses

Our API is under constant development and new functionality is released regularly. As a result of this new fields might be added to API responses without advance notice. Your app should not be affected by this and we do not consider it to be a breaking change.

When reading an API response always access the elements by their full hierarchy and name within the response (e.g. using full XPath for XML) as sometimes elements with the same name can appear in the same response under different parent elements. Unless dealing with an array never access elements in the response by their index, for example as in elements[0], instead always access them by name e.g. elements[“name”]. The order of elements can change at any time.

Example:   

Original
<release id="12345">
    <title>Greatest Hits</title>
    <artist>
        <name>Random Band</name>
    </artist>
    <version>Remastered</version>
    <image>http://7dg.tl/x.jpg</image>
</release>

Non-breaking change

<release id="12345">
<title>Greatest Hits</title>
<version>Remastered</version>
<artist>
<name>Random Band</name>
<image>http://7dg.tl/y.jpg</image>
</artist>
<image>http://7dg.tl/x.jpg</image>
</release>


We also recommend you only parse fields you’re making use of in your application and ignore the ones you don’t need. This will minimize the amount of breaking changes that might affect you. Use undocumented fields at your own risk.

OAuth

We strongly recommend for you to use standard OAuth libraries (e.g. see http://code.google.com/p/oauth/) rather than implementing your own OAuth clients from scratch. But in case you decide to ignore our advice or you’re using a really obscure language with no OAuth library available you might find our OAuth reference page useful for debugging all those little issues you’re likely to come across: http://7digital.github.io/oauth-reference-page/.

When linking 7digital accounts to user accounts of your application you do not need to go through the entire OAuth authentication flow each time you need to access an endpoint, that requires 3-legged OAuth. OAuth sets up a trust relationship between you (the API consumer) and a 7digital user, who authorises you to make requests on their behalf. This needs to be set up only once. The access token and secret obtained during this process can be re-used. Though you still need to gracefully handle scenarios when the access token stored by you has been revoked by the user who authorised it.

Keeping your API credentials secure

It is your responsibility to ensure your API credentials are not misused. We recommend to keep them secure and store encrypted (especially if they’re stored directly on client side). 7digital reserves the right to revoke API access for any API key that has been compromised. You should make sure you can update your application with a new set of credentials in case your credentials were compromised  (see also “Application upgrades” paragraph below.)

Due to the fact that API credentials permanently or temporarily stored on client side (e.g. within an app on a mobile device) can never be 100% immune to reverse engineering some API endpoints can only be used in server-to-server integrations (e.g. stream/catalogue, user/devliveritem). This also applies to integrations where user authentication is handled by 3rd party, i.e. using 2-legged OAuth instead of 3-legged.

Keep your time in sync

OAuth signed responses require a timestamp provided with each request. When building applications for devices where correct time cannot be guaranteed (e.g. user can change system time on mobile phone) the application needs to maintain it’s own timer and synchronize it either with trusted 3rd party time server or preferably with the time provided by 7digital API servers. You can use the HTTP “Date” header returned with every API response or the “/status” API endpoint.

Application upgrades

As the 7digital API evolves we’re often forced to make “breaking” changes to it’s behaviour (e.g. no longer relevant elements might be removed from API responses or entire API methods might be deprecated). You must be able to accommodate such changes by publishing an application update and ensure your users are notified of the need to upgrade. This also applies for apps embedded directly onto devices (e.g. wireless speakers, etc). We provide advance notice and transition periods for any breaking changes.

Error handling

Whilst we strive to make our API as robust as possible we do run into issues from time to time. To minimize impact of any downtime always try to catch and handle all 7digital API errors and do so for individual calls in isolation, e.g. if you’re displaying a chart on your homepage and the release/chart endpoint starts failing for some reason it should only affect your chart feature and not bring your entire homepage down. Please see our documentation [http://api.7digital.com/1.2/static/documentation/7digitalpublicapi.html#Error_responses] for explanation of different error code types.

Local caching

All API responses will return appropriate HTTP cache headers. Make use of them. Your application will be more responsive if you don’t make unnecessary server calls.

Placing a proxy server, such as Squid, between your application and the API, will give you caching quite easily and send requests to the server only when the cached item has expired.

The provided expiry times are generally recommended values adjusted for each API method but you are free to use your own caching strategy should it suit your application better. (E.g. whilst for download stores we wouldn’t recommend caching a list of tracks on an album for more than 15mins as the price of these track can change at any time, if your application doesn’t even display the prices you can cache the response for multiple hours or even days since the actual track listing is very unlikely to ever change)

Bugs and unexpected behaviour

If you come across unexpected API responses or discrepancies between documentation and the actual API behaviour don’t work around these. Please get in touch and let us know about the problem and we’ll do our best to fix the issue or advise you on the correct way to resolve.