Spotify API ColdFusion Wrapper

Having a little more fun this evening, I decided to knock up a quick little CFC wrapper to interact with the Spotify MetaData API. The full open source code can be downloaded from

Spotify MetaData API

The MetaData API allows users to explore Spotify’s music catalogue. Sadly, the API as of yet doesn't allow for interaction with playlists. For me, that would be ideal - creating and editing playlists and their content from the API. It's on my Christmas list, I guess my card didnt make it to the Spotify HQ though. :)

Until more of the content is accessible through the service, the MetaData API will hopefully provide some level of comfort to the developers aching to get started building Spotify-based applications.

The spotify object

The spotify.cfc component is incredibly simple. It has two public methods (outlined below) that allow the user to run the API calls.

At the moment, Spotify only allow XML responses from the API. The component is set by default to return the XML data as a string.

However, this can be toggled when instantiating the component by passing in a 'true' boolean value, which will return the data using the XmlParse() function, as shown below:

// instantiate the object and enable struct output
objSpotify = createObject('component',


The first of the two methods available is the search function.

The API allows you to search for albums, artists or tracks. To keep things simple, one method was created in the spotify.cfc component to cater for all searches.

The method accepts three params;

  1. searchMethod - required string. Allows you to specify either Album, Artist or Track.
  2. query - required string. The string to search for, which will be sent as a URL parameter in the remote call.
  3. page - non-required string (default 1). The page of the result set to return.

Search example

Running a simple search for an artist is fairly simple, as seen in the code below:

// instantiate the object
objSpotify = createObject('component',

// artist search for Butch Walker
result ='artist',
                query='Butch Walker');

The search method then generates the correct URL to pass through in the cfhttp GET request:

The response for this (and any call within the wrapper) is sent through another function that validates the returned status code. Anything other than a '200 OK' response will not be allowed; the process will abort, and the user will be informed of the issue.

The response returned from the search above will output as shown here:


Running a similar search, I'm now searching for one of my favourite albums, 'Sycamore Meadows'

// instantiate the object
objSpotify = createObject('component',

// album search for Sycamore Meadows
result ='album',
                query='Sycamore Meadows');

Using the same search function, by changing the searchMethod parameter, the URL generated is amended accordingly, as so:

A portion of the response is shown here:



The second of the two methods available is the lookup function, which allows you to look up information contained for a specific Spotify URI.

The method accepts two params;

  1. URI - required string. The Spotify URI.
  2. detailLevel - required string (default 'Off'). The level of data returned within the response.

Lookup example

Using the URI returned from the last search example above, let's run a lookup on the Sycamore Meadows album:

// instantiate the object
objSpotify = createObject('component',

// run a lookup on the given URI
result = objSpotify.lookup(URI='spotify:album:5vL0AkqmcSoYxwyaiOq0i8',

The detailLevel parameter was set to 'Off', so we'll receive the bare minimum response from the API.


The detailLevel has three settings:

  1. Off
  2. Low
  3. High

Changing the detailLevel on the same lookup to 'Low' will yield more information in the response:


You can now see the addition of the child node 'tracks', containing all tracks and their URI's. These URI's can then be taken and used in a further lookup to obtain more information.

Where can I get it?

The code is available to download from, here:

comments powered by Disqus