Get started quickly with your Spotify App by following these guidelines.

Register for a Developer Account

To be able to create a Spotify App and load it in the Spotify Desktop Player, you will first need to register with us as a developer. Simply log in using your Spotify username and password and request a developer account.

Creating a Spotify App

Developing an app is very easy. First, create a workspace folder in which to store your apps:

  • ~/Spotify (on Mac OS X and Linux)
  • My Documents/Spotify (on Windows)

Next, download our boilerplate app, which contains the basic structure for an app.

App Folder Name

Every app within the Spotify workspace folder has its own folder. The folder name must match the $BUNDLE-IDENTIFIER in the application manifest (see below).

If you have multiple apps with the same bundle identifier within your Spotify workspace folder, the Spotify Desktop Player will use the most recent one according to the version number declared in the application manifest.

Application Files

The basic files for all applications are:

  • index.html — this file is required in all applications, and is the first page that will be displayed when your application is loaded.
  • manifest.json — this is the application manifest file. It is a JSON file containing properties such as the name of your app and its version number.
  • license.html — this optional file can contain a custom license agreement for your application, if required.

IMPORTANT! All file names must be lowercase for your app to work correctly.

Loading a Spotify App

To load a Spotify App (for example, the boilerplate app), do the following:

  1. Put the app in the Spotify workspace folder.
  2. Start the Spotify Desktop Player.
  3. In the Desktop Player’s Search field, enter: spotify:app:$BUNDLE-IDENTIFIER
    (where $BUNDLE-IDENTIFIER is the identifier in the application manifest). The Desktop Player will load the index.html page from within your application’s folder.

Application Manifest

Every application must contain a file called manifest.json at the root level of the application. This file should contain a JSON dictionary, providing details about the application and its requirements. Make sure that the encoding of this file is UTF–8, or it won’t parse correctly.

This is an overview of the manifest file:

    // Required for development
    "AppName": { ... },
    "BundleIdentifier": "",
    "BundleType": "Application",
    "BundleVersion": "0.0.1",
    "Dependencies": { ... },
    "SupportedDeviceClasses": [Desktop],

    // Required for submission
    "AppDescription": "",
    "AppIcon": "",
    "SupportedLanguages": [
    "VendorIdentifier": "",

    // Add any of these that you need
    "AcceptedLinkTypes": [],
    "AcceptedViewDropTypes": [],
    "AppURL": "",
    "BundleCopyright": "",
    "DefaultTabs": [],
    "RequiredPermissions": []

This is the list of attributes you can use in your manifest file:

Application manifest key
AcceptedLinkTypesNOA list of Spotify link types that the application accepts, e.g. when dropping files onto the application in the sidebar. Can contain the following types: album, artist, playlist, track and user.
AcceptedViewDropTypesNOA list of external drag items that the application accepts (i.e. items dragged from some other application into Spotify).
AppDescriptionYESA dictionary with localized short descriptions (max 60 chars) of your application. It must be localized.
AppIconYESA list of application icons relative to your application’s root directory. Must contain the following keys:

A 36x18px icon in PNG format. The left half of the image (18x18) will be used in the sidebar when the application is not highlighted, the right half when it is. Within each 18x18 part, icons should be centered with one pixel of margin around them.

A 64x64px icon in PNG format. This icon will be presented in the “App Finder” view inside Spotify along the description for your application.

A 128x128px icon in PNG format. This icon will be presented to the user while the application is being downloaded, as well as on (when the user browses to the URL of your app from an external web page).

A 300x300px icon in PNG format.
AppNameYESA dictionary with localized user-displayable names for your application, e.g. My Application. It must be localized. Please note that we do no longer approve of app names with the prefix spot- or the suffix -ify. The app name can consist of a-z, A-Z and 0–9. No dots are allowed. Giving your app a great name increases the use of the app. Ideally the app’s name will give some indication of its functionality or features.
AppURLNOAn http URL to your application’s home page, if any.
BundleCopyrightNOYour application’s copyright statement.
BundleIdentifierYESA unique string identifier for your application. For example, myapp. This identifier will be used in your application’s URI, like “spotify:app:$IDENTIFIER”. The characters allowed in the manifest are a-z, 0–9 and ‘-’.
BundleTypeYESMust be “Application”.
BundleVersionYESA unique version number that should follow semantic versioning conventions, e.g. “1.2.0”. It must increase for each new version submitted.
DefaultTabsNOIf your application requires tabs, specify them in the manifest file as a list (see Tabs). It must be localized.
DependenciesYESA list of Frameworks that the app is dependent on.
RequiredPermissionsNOA list of hosts that your application needs to communicate with. Note that all RequiredPermissions should be in https. See Permissions.
SupportedDeviceClassesYESA list of supported devices. At the moment “Desktop” is the only option available.
SupportedLanguagesYESA list of languages to which your application has been localized. All languages listed needs to be IETF tags (see localization for details). If you specify languages here, only these languages will be valid for your localized application name, tab names etc.
VendorIdentifierYESA unique string identifier for your organization in reverse domain name notation, e.g. com.spotify.

If you are developing for the desktop client and you make changes to the manifest, the client must be restarted to see the effect as the manifest file is cached.

Spotify Frameworks

Spotify Frameworks are libraries that provide APIs to access Spotify entities, as well as widgets to add players, track lists and more. We currently have two frameworks available: api and views.

Your app should always depend on a specific version of a framework. To define this, in the Dependencies key of the manifest, add:

"Dependencies": {
    "api": "1.38.0",
    "views": "1.0.0",
    "resources": "0.6.1"

Note: Older versions of Spotify Apps API used a different set of frameworks (i.e. “api”: “0.1.0”, “resources”: “0.1.0”, “util”: “0.1.0”). See the documentation for the 0.x API.

Using the frameworks in your JS code is done by using the require function:

], function(models, Image) {

To include the stylesheets needed for the views framework, add the following in your HTML’s <head> tag:

<link rel="stylesheet" href="$views/css/image.css">

You have more information about the available stylesheets on the views framework documentation.

Views framework

These are the components the Views framework provides:

  • Buttons: Buttons to share Spotify content, subscribe to a playllist, start a radio and other functionality.
  • Images: Covers and players.
  • List: Lists of tracks.
  • Popup: A popup/tooltip that is shown inside the application with an arrow pointing towards an element.
  • TabBar: A bar with several tabs that is placed on top of a container.
  • Throbber: * Used to indicate some content is loading.

To see an app showcasing these UI components, go to the Spotify desktop client and open the Views tutorial.

Spotify URIs

All Spotify entities you’ll be dealing with have a unique ID in the from of a Spotify URI, for example, a valid track URI is spotify:track:2toEICLQiCx8twlZw21eBB. You can send the user to Spotify entities in the client by exposing that URI in, for example, the href attribute of an a element.

In addition, track URIs support linking to a particular point in the track by adding a timestamp as an anchor at the end of the URI, for example: spotify:track:2toEICLQiCx8twlZw21eBB#2:30 will cause the Spotify client to start playing back the track from the 2:30 mark.

Application URIs

For interacting with the outside world, your application will be given a Spotify URI similar to that of other Spotify entities. This URI is constructed in the following manner:


Let’s use a non-real example instead, such as spotify:app:mycoolapp.

This URI scheme supports passing arguments to your application from external sources such as your website. To do this, simply add values separated by colons to the end of your URI. For example:


This URI will cause the Spotify client to load the application with the URI spotify:app:whatsnew, or fire the arguments event if it is already loaded, at which point the application can call models.application.arguments to get the value [name, daniel] (see api/models Application).

Please note that you cannot access another application’s resources, even if you know its application ID.

Integrating with the Spotify Application’s History

When your application is launched, Spotify will load its index.html from within the application bundle and push it onto the global history stack. To load subsequent pages/sections, use the full URI of the resource you are going to load:

<a href="spotify:app:$APPNAME:argument">Section</a>

You can also navigate to a specific uri using the openURI function:


Avoid history.pushState() for pushing new pages onto the stack. On the desktop client you will get a security exception if you try to do so.


Spotify provides automatic localization to your applications with no extra programming effort required on your part – just specify what languages you support in the application manifest.

To provide the actual localized content, create a directory in the root of your application named after the IETF tag for your desired locale ( en for English, or fr for French and so on), followed by .loc. At runtime, Spotify will try to resolve resources within localized folders before falling back on resolving the resource in the root folder. You can only use application codes that are supported by the Spotify client. Currently these are: arb, de, el, en, es, es-419, fr, id, it, ja, nl, pl, pt-BR, ru, th, tr, zh-Hant,and zsm. If your application is only available in another language (such as Swedish sv), please use en as the supported language.

Please note that all resources available through URLs will be resolved using this method, except for the manifest.json file, which must always be placed in the root of the application. Even the icon for the sidebar will be localizable in this way, but the placeholder icon for applications that have not yet been downloaded will be the version for the English version.

For example, if the system is running in the “French” locale (fr), the index.html URL will be resolved by looking for files in the following locations in the following order:

  1. /fr.loc/index.html
  2. /index.html

The first file to be found will be used. If no files are found in the given sequence, a standard http 404 error will be generated.

You can also use this to get localized strings, using the Lang module. Having a folder structure such as the following one:

+-- de.loc
¦   +-- strings
¦       +-- main.lang
+-- en.loc
¦   +-- strings
¦       +-- main.lang
+-- es.loc
¦   +-- strings
¦       +-- main.lang
+-- index.html
+-- manifest.json
+-- scripts
    +-- main.js

where main.lang files are a JSON dictionary like this one (i.e. ~/Spotify/my-app/en.loc/strings/main.lang):

    "greeting": "Hello and Welcome!",
    "personal-greeting": "Hello {0}, and Welcome!"

you can retrieve localized strings using this:

require('strings/main.lang', function(mainStrings) {
    // Returns 'Hello and Welcome!'

    // Returns 'Hello Mark, and Welcome!'
    mainStrings.get('personal-greeting', 'Mark');

    // Non-existent key, returns 'non-existent'

    // Non-existent key, returns 'non-existent but still interpolated'
    mainStrings.get('non-existent but still {0}', 'interpolated');

User Tracking and Analytics

Tracking user behavior within your Spotify App using Google Analytics can be done in the same way as you would track a regular website. Use a Classic Analytics tracking account and select “Website” (not “Mobile app”). Instructions from Google can be found at the Google Analytics site.

IMPORTANT! Ask your user explicitly for permission before you track any personal data or track user behavior associated with a user identity. See also: User Tracking & Analytics in the Spotify Apps Integration Guidelines.

Your app needs to use SSL to communicate with Google Analytics, so the tracking code used in the app should look something like this:

<script type="text/javascript">

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-XXXXX-X']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = '';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); 


(Make sure that you replace 'UA-XXXXX-X' with your unique UA tracking number, otherwise tracking will not work.)

To be able to communicate with Google Analytics, its domain must be added to the required permissions in your application manifest (manifest.json):

"RequiredPermissions": [""]


You can use your browser developer tools to debug your web app. Please know that the web inspector will only show errors/warnings in HTML/JS land – more errors may lurk behind the scenes.

Use the console log to find out if your application is violating the sandbox, exceptions are thrown, etc. If you are using the desktop client, open the Inspector. You can do it right-clicking and clicking on Show Inspector or opening the Develop > Show Inspector menu item. If you are developing on a browser, it is likely that it will have a console integrated in its Developer Tools. Please check the documentation for your particular browser.

Security and Encoded Strings

To ensure that applications do not use strings in potentially unsafe ways, all strings given by the Spotify APIs are encoded so that accidental misuse will not cause injection vulnerabilities. If the application does not decode these strings, using the two methods described below, the strings will display as garbage to the user. The only exception to this is URIs, which are never encoded and thus require no decoding. The API documentation states for each method which strings must be decoded or not.

Two methods have been added to the JavaScript strings: decodeForText() and decodeForHTML(). If the string is intended to be used in a safe manner, such as setting the innerText or creating a text node using document.createTextNode(), the decodeForText() should be used. It will return a raw non-escaped string, so make sure it is never inserted into any context where will be interpreted as HTML. If the string is intended to go into an innerHTML or in any piece of code that will be intepreted as HTML, then decodeForHTML() must be used. It will ensure that < and > are encoded as &lt; and &gt; etc. For example:

document.getElementById('song-title').innerHTML = track.title.decodeForHTML();
document.getElementById('song-title').innerText = track.title.decodeForText();

Applications that do not use these methods will a) not be able to display metadata or any other data from the Spotify API, and b) will be rejected in the upload process. Also, ensure that you properly escape unsafe HTML strings from wherever they happen to come from, e.g., your backend servers.


As with any HTML5 application, you can apply web performance optimization techniques to deliver the best experience to the users of your app:

  • Load CSS before Javascript files.
  • Write performant CSS and Javascript. For instance, use efficient CSS selectors and minimize DOM manipulation.
  • Try to make the most out of browser capabilities, being sensible when using libraries.
  • Try to minimize the size of your bundle by only including the needed resources.
  • Optimize the bundled images.

We recommend you to use the developer tools that come built-in with browsers to measure performance.

Loading and unloading of apps

Once an app is opened, it will stay loaded as long as it is open or has started playback. For example, if a user opens the app, starts playback using a List view component in the app, and switches to a different app without starting to play music from there, the first app will still be loaded and able to listen to events.

The app will unload after the user has navigated away from it without app playback, or after another app has taken over playback. Note that there is no way to prevent an app from being unloaded.

Browser capabilities

In general, the built-in browser supports every feature supported by its equivalent Chrome version.

To find out the browser version, open an Inspector and run this in the Console:


A sample return value would be:

"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.80 Safari/537.36"

There are handy sites like Can I use that report what features are supported per browser. In this case, if the feature is reported as supported by Chrome 29.0 it is supported in the built-in browser.

Some features are not supported at the moment:

  • Geolocation
  • Session history management (HTML5 History API)
  • Audio element
  • Web Audio API
  • getUserMedia/Stream API
  • Flash

Drag and drop of content

The user can pass data to your application by drag-and-dropping tracks, artists, albums, playlists and more from elsewhere in the Spotify desktop client either onto your application’s view or its sidebar icon.

Dropping items onto the application’s view will trigger standard HTML5 drop actions, while items dropped onto the sidebar icon will trigger a dropped JavaScript event. You can subscribe to it using:

models.application.addEventListener('dropped', function() {
    models.application.load('dropped').done(function (dropped) {
        /* Do whatever you like using the 'dropped' variable */

If you like your app to accept dropped elements on the sidebar icon, you should specify the types in the “AcceptedLinkTypes” array in the app’s manifest. You can give items “back” to the client in the form of Spotify URIs. For example, if your application presents a link with a href containing a Spotify track URI, the user will be able to drag that to a playlist in the Spotify client sidebar to add that track to a playlist.

You can read more about models.application on its documentation page.


If the application needs to use a tab bar at the top to switch between different areas, it must use the tab bar provided by Spotify. The application can specify what tabs it wants in the manifest file, in the DefaultTabs attribute. The attribute must be a list of records. Each record must contain the attributes arguments and title. The title can, and should, be localized by making it into a record with attributes for each language (for example: "en", "fr" and "es").

When the application is started, it can call models.application.arguments to get the current tab and its arguments. When switching between tabs, the arguments event will be sent to the listeners of that property:.

models.application.addEventListener('arguments', function() {
    models.application.load('arguments').done(function (arguments) {
      /* Do whatever you like using the 'arguments' variable */

Please be aware that if your application uses the DefaultTabs key (and hence is given a tab bar by Spotify) it will always have a tab selected – there’s no concept of a section within your application that does not belong to a tab in the tab bar. This means that if you try to navigate to a URI like spotify:app:appname:awesomesection:subid and you do not have a tab with the argument awesomesection in your manifest, you will end up on the current tab with its arguments plus awesomesection:subid appended at the end.

Read more about models.application here.

Internal Resource URLs

In the Desktop client, all resources within your application will be supplied to your application through the sp:// URL scheme. The root URL for your application will always be sp:// followed by your application’s identifier. These URLs can be used anywhere an http URL might be used.

URL File Location, relative to application root level
sp://whatsnew/index.html /index.html
sp://whatsnew/css/whatsnew.css /css/whatsnew.css
sp://whatsnew/images/album.png /images/album.png

However, take into account that for this to work in other platforms you should use relative URLs.


You need to set the RequiredPermissions key in the manifest if you wish to request external resources from within your application. Spotify will block any requests for external resources from hosts not present in this list, and an error message will be appended to the Spotify application log.

The below example highlights how you specify that you want to request stuff from any subdomain, itself, as well as the test subdomain on

"RequiredPermissions": [

The domain must be belong to a valid top-level domain (e.g.,, not localhost nor an IP address). The individual permissions should be specific to a subdomain or set of subdomains. Do not use broad wildcards like *.com.

You must restart Spotify after modifying your manifest file.

Debugging in the Desktop Client

When using your developer-enabled Spotify account, you have access to a menu item in Spotify desktop client called Develop. This menu provides access to the main view’s current application:

  1. Name/origin/version information
  2. Web Inspector
  3. Reload option

The very same menu contains additional links to:

  1. The application bundle overview application – lists all applications (including any local application on disk) that the Spotify desktop client has identified
  2. The HTML5 test application that showcases what functionality the built-in web browser engine supports

You can also right click anywhere within your application to bring up the very same developer contextual menu.

The Spotify application’s console can be viewed by on Mac OS X, and using Spotify’s internal console on Windows (press Ctrl+Alt+Home when Spotify is in focus to invoke it).