SOAP requests and responses

The Sonos Music API (SMAPI) is based on the Simple Object Access Protocol (SOAP) Version 1.1 specification. A client can access SOAP services over HTTP 1.1 and HTTPS, and can optionally include support for client-side certificates. The service is described using WSDL (Web Services Description Language) and XSD (XML Schema Definition).

Download the Sonos WSDL

About SOAP

Sonos uses the SOAP protocol for the Sonos Music APIs. SOAP is a platform and language independent communication protocol using XML and XML namespaces. SOAP is used in conjunction with WSDL files that also use XML to define message formats and the mechanisms Web services can use to access them; essentially the interface contract between the Web service and clients using it. Both SOAP and WSDL are defined by the World Wide Web Consortium (better known as W3C), the same group that maintains HTML and many other internet standards.

SOAP messages are contained within a SOAP envelope, which must be the root element of the XML sent over the wire. The envelope contains an optional header and a required body element. The header must be the first element within the envelope if present and contains directives related to the message. It should not be confused with HTTP headers which may also be part of the overall request. The body either contains the message content in a format defined by the Sonos WSDL file or contains fault elements conveying error information (Error handling). The general syntax of the envelope is:

<[soap]:Envelope xmlns:[soap]="http://schemas.xmlsoap.org/soap/envelope/">  
  <[soap]:header>[header]</[soap]:header>  
  <[soap]:body>[body]</[soap]:body>
</[soap]:Envelope>

The [header] is the content of the SOAP header and [body] is the SOAP body.

All of the elements within a SOAP message use XML namespaces to indicate where specific elements are defined. The envelope element must include a namespace definition pointing to the universal soap namespace URI (http://schemas.xmlsoap.org/soap/envelope/) and elements within the message typically use a namespace pointing to a public, online version of the WSDL file defining the included elements or to a public namespace URI representing the elements of the namespace. In the latter case, the URI is symbolic and does not need to actually load a copy of the definitions. Both parties understand that namespaces pointing to the URI contain the elements defined in a specific WSDL file defined elsewhere.

In some cases, more than one namespace is needed to fully express the elements within the body of a single message. This is perfectly valid as long as all namespaces are defined and each element explicitly indicates the proper namespace in its declaration. The Sonos public namespace URI is http://www.sonos.com/Services/1.1. This includes the SMAPI version number (1.1).

For more information on SOAP and WSDL files, see these tutorials and the official specifications:

What to expect from a SMAPI request

Each SMAPI request consists of an HTTP method, HTTP headers, and an HTTP request body. The HTTP body will contain a SOAP envelope divided into a SOAP header and a SOAP body formatted using XML.

HTTP methods and headers

All requests are sent as HTTP POST requests. For example:

POST /AcmeMusic/ServiceTest1.asmx  
HTTP/1.1 CONNECTION: close  
HOST: 10.0.2.112:8080  
CONTENT-LENGTH: 335  
CONTENT-TYPE: text/xml; charset="utf-8"  
SOAPACTION: <http://www.sonos.com/Services/1.1#getMetadata>  
. . .

The type of API request is set in the SOAPAction HTTP header. This header specifies the address of the Sonos XML namespace definition and the SMAPI version number (1.1). Following the version number is the hash sign (#) and the name of the method being called. For example, getMetadata calls use the following header:

SOAPAction: "http://www.sonos.com/Services/1.1#getMetadata"

Your SMAPI service must be able to interpret the SOAPAction value and use it to determine how to process the supplied request body.

Accept-Language header

Sonos apps send an Accept-Language HTTP header in their SMAPI requests. The Sonos app sets the Accept-Language header to the two letter ISO 3166-1 country code and the two letter ISO 639-1 language code used to generate the request. This indicates which of the supported languages your service should use in response. For example, a Sonos app using French will set this header to fr-FR as shown below:

Accept-Language: "fr-FR"

📘

Sonos players do not send Accept-Language headers.

Your service should localize any metadata item that has text that listeners will see, for example, a “title” field. See Strings and Localization for details.

📘

Sonos sends an X-Sonos-Playback-Id header in getMediaURI requests. See Unique string for the lifetime of the playback session in Play audio for details about this header.

User-Agent header

In addition, the User-Agent HTTP header identifies the Sonos build number and the type of Sonos app or player sending the request. For example, a CONNECT:AMP™ running build 26.7-48310 will send the following header with its requests:

User-Agent: "Linux UPnP/1.0 Sonos/26.7-48310 (ZP120)"

The "(ZP120)" shows that this is a request from a Sonos player. All Sonos players send a string that starts with "ZP".

The User-Agent HTTP header that a Sonos app sends includes device and operating system information. For example, the Sonos app for iOS running on an iPhone 6 Plus with iOS version 8.2 sends the following header with its requests:

User-Agent: "Linux UPnP/1.0 Sonos/29.3-87071 (ICRU\_iPhone7,1); iOS/Version 8.2 (Build 12D508)"

Note that you can't tell one iOS device from another if the device and OS are the same from the User-Agent heading. For example, if two listeners are both using iPhone 6 Pluses with iOS version 8.2 in the same household you won't be able to identify them from the User-Agent header.

Here is a list of what different Sonos apps send to identify themselves in the User-Agent heading of a request:

Sonos appShown in User-Agent HTTP header
Sonos app for iOSICRU
Sonos app for AndroidACR
Sonos app for MacMDCR
Sonos app for PCWDCR

X-Forwarded-For header

The X-Forwarded-For HTTP header allows Sonos to properly locate where a user IP originates from. This header is used for geo-blocking or for sending region-specific content back to Sonos. For example:

X-Forwarded-For: 203.0.113.195

For more information, see X-Forwarded-For.

SOAP Envelope

In addition to being the container around the SOAP headers and SOAP body, the SOAP envelope for SMAPI requests also typically defines an XML namespace pointing to the public URI of the Sonos namespace. This URI is:

http://www.sonos.com/Services/1.1

Sonos typically assigns the prefix ns to this namespace but does not guarantee its use in all SMAPI requests.

For example, the SOAP envelope for a SMAPI request might be defined as follows:

<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="http://www.sonos.com/Services/1.1">
...
</soap:Envelope>

The following is equivalent:

...
</soapenv:Envelope>

SOAP header

The SOAP specification requires that the SOAP header is included within the SOAP envelope before the SOAP body if one is included at all. SMAPI supports one SOAP header with elements supplying credentials and context information.

<credentials> element

The credentials element contains all of the information needed to authenticate the user making the API call. It consists of the following sub-elements:

  • deviceId This is deprecated so your service can ignore it. This was an identifier equivalent to a Sonos device registered by an authenticated user when they set up their household.
  • deviceCert The X.509 certificate for the player sending the request. This is optional and requires that you turn on the "Requires Device Certificate" capability, described in Add capabilities. See Encrypt content for how to use this.
  • zonePlayerId The Sonos player ID for the player sending the request. This is optional and requires that you turn on the "Include Zone Player IDs in credentials header" capability, see Add capabilities for details.
  • deviceProvider The device provider. This value is always Sonos.
  • loginToken The authentication information for the user making the request. See Use authentication tokens for details.

The expected syntax for the credentials element is:

<[ns]:credentials>
  <[ns]:deviceId>[deviceId]</[ns]:deviceId>
  <[ns]:deviceCert>[deviceCert]</deviceCert>
  <[ns]:zonePlayerId>[zonePlayerId]</zonePlayerId>
  <[ns]:deviceProvider>Sonos</[ns]:deviceProvider>
    <[ns]:loginToken>
    <[ns]:token>[authenticationToken]</[ns]:token>
    <[ns]:key>[refreshToken]</[ns]:key>
    <[ns]:householdId>[householdId]</[ns]:householdId>
  </[ns]:loginToken>
</[ns]:credentials>

Context element

Sonos will send context in the header so that you can use it to customize the browse experience. Currently, we offer two contexts, the time zone of the player or controller, and content filtering.

The timeZone sub-element reports the time zone of the player or controller that is sending the request. With this context, your service could customize featured playlists based on the user's location and time of day.

Currently the only option we offer for contentFiltering is explicit. See Tag & filter explicit content for details.

Set the “Include SMAPI context headers with all requests” capability flag when developing or submitting your service for validation. See Add capabilities for details.

NameTypeDescription
timeZonestringHour and minute offset from UTC, such as +hh:mm or -hh:mm. If the region that the user is in uses Daylight Savings Time, we incorporate this into the time offset that we send.
contentFilteringcomplexUsed for flagging content that the listener has requested not be playable on their system. contentFiltering is only included if the associated capability flag is turned on. Currently, the only flag we offer is explicit.

explicit is a boolean that if set to true signals that the Sonos system sending the request has chosen to filter out explicit content. All filtering defaults to false/off when it is not present in the context header. Sonos players and apps will not include explicit or contentFiltering in requests if listeners have not enabled explicit filtering.

Example:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <credentials xmlns="http://www.sonos.com/Services/1.1">
      <deviceId>
        XX-BB-33-55-66-77:H
      </deviceId>
      <deviceProvider>
        Sonos
      </deviceProvider>
    </credentials>
  </s:Header>
  <s:Header>
    <context xmlns="http://www.sonos.com/Services/1.1">
      <timeZone>
        -05:00
      </timeZone>
      <contentFiltering>
        <explicit>
          true
        </explicit>
      </contentFiltering>
    </context>
  </s:Header>
  <s:Body>
    ...
  </s:Body>
</s:Envelope>

Note that while the timeZone sub-element is included in the WSDL, additional contextual elements will not be bound to the WSDL, as specified by the any element within the context complexType element. Therefore, you should design your SMAPI implementation to use or ignore any context sub-elements that Sonos sends.

SOAP body

In general, the request body of a call includes some sort of identifier indicating what the server should take the requested action against (for instance, getMetadata requests include an id element indicating a node in the item tree for the service and expects a list of direct children of that item returned in the response). Some requests that do not act directly on content may not include an id element. Requests that create new content typically return an id element for that content in the response.

Each request has its own format as defined in the Sonos WSDL file. You'll need to reference the definition of each call to determine what to expect. In general, the content is all inside an element matching the call name. For example, the SOAP body for getMediaMetadata is defined as follows:

<[soap]:Body>
  <[ns]:getMediaMetadata>
    <[ns]:id>[itemId]</[ns]:id>
  </[ns]:getMediaMetadata>
</[soap]:Body>

The itemId is the content ID of the item being requested.

The following elements are found in many SMAPI requests:

  • id The item content ID of the item being processed by the request. See the Content IDs section in content on Sonos for more information.
  • index Indicates the entry point into the 0-based list of possible responses.
  • count Indicates the maximum number of items to return in the response.

See Add pagination for more information about index and count.

What to send in a SMAPI response

Each SMAPI response consists of an HTTP status code, HTTP headers, and an HTTP response body. The HTTP body must contain a SOAP envelope with a SOAP body formatted using XML.

HTTP status code

All SMAPI responses that successfully fulfill the related request should return HTTP status code 200, success. Responses that do not successfully fulfill the related request should return HTTP status code 500 regardless of the cause of failure. Responses returning 500 for their status code should always use a SOAP body containing a fault element.

HTTP headers

Responses may be compressed using gzip software. If so, the content-encoding HTTP header must be present and set to gzip. The content-type header should be set to text/xml; charset=utf-8 to indicate that the body of the response uses XML with UTF-8 encoding (note that, unlike for JSON, UTF-8 is not the default encoding for XML so you must specify the encoding explicitly). Other standard headers should be used as appropriate to accurately describe the returned data and behaviors. For example, the response headers for a SMAPI call might look like the following:

Content-Encoding: gzip  
Content-Type: text/xml; charset=utf-8  
Content-Length: 1455  
Connection: keep-alive

SOAP header

Sonos does not expect a SOAP header in any response to SMAPI calls and will ignore it. Your SOAP envelope should only contain a SOAP body.

SOAP body

The SOAP body in the response is dependent on the SMAPI call. Your response should match the response defined in the Sonos WSDL file. In general, the following conventions are used in response formats for successful requests:

  • Responses to specific elements in the request body are returned using an element of the format [requestElementName]Response, for example, getMetadataResponse. The [requestElementName] is the name of the element in the request body requiring a response, which is typically the name of the SMAPI method being processed by your music service, such as getMetadata.
  • The [requestElementName]Response element includes an xmlns attribute pointing to the public URI http://www.sonos.com/Services/1.1, for the Sonos namespace.
  • The [requestElementName]Response element has a child element named [requestElementName]Result. Typically this will be its only child element, although there are a few exceptions.
  • The [requestElementName]Result element contains index, count, and total elements if pagination is expected for the method. See Add pagination for more information.
  • The [requestElementName]Result element contains the requested data in the structure defined in the Sonos WSDL, often as a list of repeated elements, where each represents a single item in the sorted list of possible results.

Requests that are not successfully processed should return a Fault element in the response instead of the normal response body. See error handling for more information.

A getMetadata response body might look like the following:

<soap:Body>  
  <getMetadataResponse xmlns="http://www.sonos.com/Services/1.1">  
    <getMetadataResult>  
      <index>0</index>  
      <count>4</count>  
      <total>4</total>  
      <mediaMetadata>  
        <id>Track::1</id>  
        <itemType>track</itemType>  
        <title>Gone Jazz Crazy</title>  
        <mimeType>audio/mpeg</mimeType>  
        <trackMetadata>  
          <artistId>Artist::212</artistId>  
          <artist>Richmond Starlight Quartette</artist>  
          <albumId>Album::3132</albumId>  
          <album>Gone Jazz Crazy</album>  
          <duration>185</duration>  
          <albumArtURI><http://Art44423></albumArtURI>  
          <canPlay>true</canPlay>  
          <canSkip>true</canSkip>  
          <canAddToFavorites>true</canAddToFavorites>  
          <trackNumber>1</trackNumber>  
        </trackMetadata>  
      </mediaMetadata>  
      <mediaMetadata>  
        <id>Track::2013</id>  
        <itemType>track</itemType>  
        <title>Wont Be Worried No More</title>  
        <mimeType>audio/mpeg</mimeType>  
        <trackMetadata>  
          <artistId>Artist::212</artistId>  
          <artist>Richmond Starlight Quartette</artist>  
          <albumId>Album::3132</albumId>  
          <album>Gone Jazz Crazy</album>  
          <duration>189</duration>  
          <albumArtURI><http://Art44423></albumArtURI>  
          <canPlay>true</canPlay>  
          <canSkip>true</canSkip>  
          <canAddToFavorites>true</canAddToFavorites>  
          <trackNumber>2</trackNumber>  
        </trackMetadata>  
      </mediaMetadata>  
      <mediaMetadata>  
        <id>Track::391</id>  
        <itemType>track</itemType>  
        <title>Oh, You Better Mind</title>  
        <mimeType>audio/mpeg</mimeType>  
        <trackMetadata>  
          <artistId>Artist::212</artistId>  
          <artist>Richmond Starlight Quartette</artist>  
          <albumId>Album::3132</albumId>  
          <album>Gone Jazz Crazy</album>  
          <duration>190</duration>  
          <albumArtURI><http://Art44423></albumArtURI>  
          <canPlay>true</canPlay>  
          <canSkip>true</canSkip>  
          <canAddToFavorites>true</canAddToFavorites>  
          <trackNumber>3</trackNumber>  
        </trackMetadata>  
      </mediaMetadata>  
      <mediaMetadata>  
        <id>Track::5929</id>  
        <itemType>track</itemType>  
        <title>Monkey Man Blues</title>  
        <mimeType>audio/mpeg</mimeType>  
        <trackMetadata>  
          <artistId>Artist::212</artistId>  
          <artist>Richmond Starlight Quartette</artist>  
          <albumId>Album::3132</albumId>  
          <album>Gone Jazz Crazy</album>  
          <duration>189</duration>  
          <albumArtURI><http://Art44423></albumArtURI>  
          <canPlay>true</canPlay>  
          <canSkip>true</canSkip>  
          <canAddToFavorites>true</canAddToFavorites>  
          <trackNumber>4</trackNumber>  
        </trackMetadata>  
      </mediaMetadata>  
    </getMetadataResult>  
  </getMetadataResponse>  
</soap:Body>

What’s Next

Learn about how the Sonos app displays your content.