Sonos Music API - Getting Started Guide

Browse and search

Users can browse your service’s catalog using the Sonos app. This should feel like it does when they browse content in your app or on your website. For browsing to work on SMAPI, arrange your catalog into a hierarchy of containers and media.

  • Containers are collections of playable items (such as tracks or radio streams), or collections of other containers (such as a list of albums). Users can select a container to browse into it.
  • Media is playable, such as a track or radio station. Your service can use <canPlay> to make specific media items or containers not playable in SMAPI. See SMAPI object types for details. Users can’t browse into media, but they can browse a container with media in it.

If a container of media, such as an album, is playable, the Sonos app shows users playback actions when browsing it. Playback actions are Play Now, Play Next, Add to Queue, and Replace Queue. A playable container can’t be home to other containers (both playable and non-playable containers), only media items.

The first container a user sees when they browse your service on a Sonos app is the “root” container. This is like your service’s homepage in SMAPI. This is what a root container looks like in the Sonos app when a listener browses into a service:

The Sonos app can display each container in different ways, depending on its <itemType> and <displayType>. Each <itemType> has a different default display mode, see SMAPI object types for details. See Customizing display of albums, tracks, and other items for more information about display modes.

In SMAPI, playable items are <mediaMetadata> items. Collections of playable items or are <mediaCollection> items. Generally, <mediaMetadata> objects are media, and <mediaCollection> objects are containers.

Sonos apps browse your catalog by sending getMetadata requests. Your service responds to these requests by returning <mediaCollection> and <mediaMetadata> objects. This is what a “root” container looks like in a getMetadata response:

...
  <s:Body>
    <ns:getMetadataResponse>
      <ns:getMetadataResult>
        <ns:index>0</ns:index>
        <ns:count>5</ns:count>
        <ns:total>5</ns:total>
        <ns:mediaCollection>
          <ns:id>user-likes:5555000</ns:id>
          <ns:itemType>albumList</ns:itemType>
          <ns:displayType>editorialView</ns:displayType>
          <ns:title>Your Likes</ns:title>
          <ns:canPlay>false</ns:canPlay>
          <ns:albumArtURI>https://example.com/icons/likes_legacy.png</ns:albumArtURI>
        </ns:mediaCollection>
        <ns:mediaCollection>
          <ns:id>browse:new</ns:id>
          <ns:itemType>trackList</ns:itemType>
          <ns:title>New Arrivals</ns:title>
          <ns:canPlay>false</ns:canPlay>
          <ns:albumArtURI>https://example.com/icons/new_legacy.png</ns:albumArtURI>
        </ns:mediaCollection>
      ...
      </ns:getMetadataResult>
    </ns:getMetadataResponse>
  </s:Body>
...

The example above shows the "Your Likes" container above the "New Arrivals" container. For this response, the Sonos app will display "Your Likes" before "New Arrivals" in this service's root browse. This is because the Sonos app displays content in the way that your service returns it. You should sort content in a way that is consistent and understandable to your listeners.

Generally, requests come from user actions such as browsing your service. However, users can save their favorite content from your service to My Sonos for easy access later. When users browse My Sonos, Sonos sends getMetadata requests for any content that they've saved to it.

Each item in the browse hierarchy must have an object ID

As mentioned above, your service assigns every item in the browse hierarchy its own identifier. Object IDs must obey certain rules so that your service can map them to real content and Sonos apps can browse or cache the hierarchy. See Identifiers for details. 

Sonos uses getLastUpdate to check your content catalog for changes

Sonos apps poll your service for changes via the getLastUpdate method. This is how you can keep the content for your entire catalog and personalized content for your users in sync. See getLastUpdate  for details.

Send metadata with your content

You should provide metadata with every container and media item in your catalog. Containers show different kinds of metadata than media items do. See SMAPI object types for more information.

The following is an example of a <mediaMetadata> object and its associated metadata.

...
  <ns:mediaMetadata>
    <ns:id>track:555</ns:id>
    <ns:itemType>track</ns:itemType>
    <ns:displayType>editorialViewTracks</ns:displayType>
    <ns:title>This is a song</ns:title>
    <ns:mimeType>audio/mp3</ns:mimeType>
    <ns:trackMetadata>
      <ns:artistId>artist:555</ns:artistId>
      <ns:artist>The Artist Name</ns:artist>
      <ns:duration>191</ns:duration>
      <ns:albumArtURI>https://example.com/albumArt.jpg</ns:albumArtURI>
      <ns:canPlay>true</ns:canPlay>
      <ns:canSkip>true</ns:canSkip>
      <ns:canAddToFavorites>true</ns:canAddToFavorites>
    </ns:trackMetadata>
  </ns:mediaMetadata>
...

IMPLEMENT SEARCHING ON EACH SONOS APP

Listeners should be able to search for content in the Sonos app just like they can using your service's app or website. This is very important for your users on Sonos. A good search implementation helps users find the content that they want to play. SMAPI uses two types of searching, one for the Sonos app on mobile devices, and another for the Sonos app on a Mac or PC. For the best user experience, your service should implement both types of search. See Implementing universal search for details.

IMPROVE PERFORMANCE BY LIMITING THE NUMBER OF ITEMS RETURNED IN YOUR RESPONSE (OPTIONAL)

Browsing and search calls allow for your service to return getMetadata results in increments. This is to better support devices with low memory footprints. For example:

A user searches for all albums containing the string “Hits”. The SMAPI call will specify a starting <index>  and <count> for the search, as well as the search <term>.  For example, a call with an <term> of "hits", an <index> of 100, and a <count> of 20 will be saying, "search for all 'hits' and return 20 results starting at the 100th result.

See Pagination for details. 

Localize metadata text (optional)

SMAPI uses the Accept-Language HTTP header for localization. This lets the listener’s Sonos app specify the language for any text data returned by a SOAP call. Your service should localize any metadata item that has text that listeners will see. This text could be something like a “title” field. See Customizing strings and localization for details.

SIMPLIFY BROWSING LARGE COLLECTIONS WITH ALPHABETICAL SCROLLING (Optional)

Alphabetical scrolling uses getScrollIndices to optimize content enumeration for large collections of metadata. Alphabetical scrolling allows a listener to scroll through the alphabet and select a letter. This initiates a getMetadata request on a collection at a particular index.

Listeners use My Sonos to play their favorite media items

Listeners can access content from your service in an area of the Sonos app called My Sonos:

Users can save content from your service to My Sonos. This content used to be called Sonos Favorites. My Sonos is organized by content type. For example, the My Sonos screen has a row for podcasts, a row for playlists, and an area for radio stations. If a user hasn’t saved any of a type of content, for example podcasts, then the podcasts row won’t show up on the My Sonos screen. 

You don't need to do anything special to enable My Sonos, but it is only available for Sonos apps for iOS and Android. It is not available for Sonos apps for Mac and PC. Most of the time, when a user saves content to My Sonos on a mobile app, it will appear in Sonos Favorites in the Sonos app for Mac or PC. However, users on a mobile app can save non-playable containers such as a recommendations container to My Sonos. These containers aren’t available from Sonos Favorites in the Sonos app for Mac or PC.

With My Sonos, it is possible for listeners to save temporary content to My Sonos. This could be something like a holiday-themed playlist or radio station. When it expires, users will see a blank item on their My Sonos screen. Your service should use the <isEphemeral> element to prevent users from saving a temporary stream to their My Sonos screen.