Let’s Chat: Making Sonos Talk with the audioClip API

Last week we brought out an early, experimental version of audioClip for everyone to try. Using this namespace developers can make Sonos speakers play short clips of sound that won’t end whatever was playing on that speaker at the time. We’ve heard a lot of folks asking for this capability over the past few years and we’re glad to finally be bringing it to you. Some small details may change and there are still some things that we need to implement, but this is a great preview of what the namespace is capable of.

Of course, what good is a new API namespace if we don’t build fun things with it? Personally I’ve always wanted the ability to have my Sonos speak to me. You can imagine the uses: tell your kids on the third floor to come down for dinner. Announce the score of the football game. Say who that latest email is from. Really, the sky’s the limit. So let’s use Google Translate’s free Text-to-Speech (TTS) API, along with this new audioClip namespace, and build ourselves a browser-based Sonos TTS experience.

Getting Started

We’ll need a few things to get started:

  • A set-up and configured Sonos system, obviously. Make sure you can play some content on it.
  • The username and password associated with that Sonos system.
  • A Control Integration, complete with a Client Key and Secret, with the redirect uri set to ‘http://localhost:3001/redirect’.
  • A machine capable of running a node version that supports at least ES7. I’m using node version 8.6.0 on my Mac.
  • Some topical music. Let’s do the obvious thing and put on some Talking Heads.

We’ll also be using a few external npm packages to help us with some app infrastructure. These are things that aren’t important to learn about for this blog post, but that are still required for our final app to run:

  • google-tts-api: This puts a nice, neat, promise-ready wrapper around the Google Text-to-Speech API.
  • simple-oauth2: A handy package to simplify the process of getting and refreshing access tokens.
  • node-persist: Mimics the HTML5 localStorage API used in browsers, so it’s pretty easily understood.

These packages are all installed automatically when we execute our npm install command in the next step.

Preparing the App

In a directory of your choice clone the github repo and cd into the newly-created directory. Type npm install and wait for it to run through the install process. Next, copy the .env.sample file into a new file called simply .env. Edit this new file and fill in your Sonos client id and client secret, obtained from the developer portal. After this you should have everything set up.

I built this app using React to drive the front-end. React is pretty new to me and I’ve really enjoyed learning about how to put such an app together. I had coincidentally just read this blog post by Phil Nash over at the Twilio blog. (As an aside, you should put that blog on your RSS reader of choice. Consistently great content.) The app structure Phil lays out here seemed to meet all of the needs I anticipated for my app. I cloned his repo and used that as a base for Sonos TTS.

App Architecture

The app we’re building here today consists of a front-end App, built in React, and a back end server. The React app makes calls to the back-end server to get data needed for the front-end UX. It also sends text to the back-end to speak. The back end interfaces with the Sonos auth and API servers. It keeps track of the access tokens that get generated during auth. The front-end app has no real idea that it’s working with Sonos. All the “smarts” are consolidated in the back end.

 

We should note that the back-end server we’re building here is completely unsecured. It shouldn’t be run anywhere except on your local machine. It’ll have access to your Sonos household and will store OAuth 2.0 access and refresh tokens.

Running the App

As Phil notes in his blog post you can choose to run this app as separate back end server and front-end processes. This is useful in the case where you do plan to run the server and front-end on different machines or instances. We’re going to run everything locally, so we’ll take advantage of the script Phil made to run both server and front-end simultaneously. Type npm run dev and wait for things to spin up. Your browser should automatically be brought to the foreground and the app will start up.

If this is your first time running the app you’ll immediately be redirected to the Sonos auth servers to log in to your Sonos account. Once you’ve done so you’ll be sent back to the main app screen.

 

In the screen above you can see we’re presented with a list of speakers in our household and a box in which to type the phrase we want the Sonos to say. Go ahead and pick some speakers, type something (might I suggest “Sonos speakers sound great!”?) and see what happens. Hopefully, your Sonos just talked to you.

There are a few things to note here:

  • If you’ve got multiple households associated with your Sonos account, you’ll have an extra select list so you can choose which household to target. You can have multiple households if, for example, you’ve got Sonos set up at both your primary residence and vacation home.
  • Remember above where I said that the audioClip namespace is still experimental? Well, one of the things that isn’t fully baked yet is a capability flag, called AUDIO_CLIP. Using this flag a player indicates its ability to actually play audio clips. Until that flag is available this app will just list all speakers. If the user selects a speaker that can’t play audio clips, the app will return an error. At the time of this writing only the Sonos One and Beam support audio clips.

Now that we’ve built and run the app let’s dig into the details to see how we did it.

Authorizing the App with Sonos

There are a few interesting parts of the code to look at. First let’s examine how we set up simple-oauth2 to work with Sonos. There are two main things we need to configure: the various auth endpoints and API keys and secrets, and the redirect handler. (For a quick refresher on authenticating against Sonos’ OAuth2.0 server, see our docs.)

Luckily for us, simple-oauth2 makes this all, well, simple. They provide a nice set of convenience methods for defining the OAuth2.0 parameters and for providing the authorization URLs.

That second constant, the authorizationUri, is built by the authorizeURL method. It’s really handy because it encapsulates everything that’s important in the initial call to the authorization code endpoint. So a simple redirect to authorizationUri is all that’s needed to kick off the auth flow.

At this point the user is sent to the Sonos authorization site. They’ll log in to their account and read about the permissions your app is asking for. After having granted those permissions, they’re sent back to the redirect URI. That URI was specified when the Control Integration was built on the dev portal, and is handled by our app. The handler for that URI takes the authorization code and exchanges it for an access token via the Sonos auth endpoints.

You can see above the simple-oauth2 method getToken which takes care of all the behind-the-scenes stuff for us. Everything is nice and straightforward since we configured simple-oauth2 at the beginning to plug directly in to Sonos’ auth server. We get the token back and save it, using node-persist, to local storage. That way we don’t have to ask the user to log in every time we restart the app. Now obviously local storage is not how you’d want to persist access tokens in a production app, but this simple method works for our purposes.

Talk To Me

Ok, we’ve got our access token and can now make calls to the Sonos Control API. You’ll note that in the code above, once a token is successfully fetched and saved, we send the user back to localhost:3000 which is the URL for our main app. They’ll see the main app screen, shown above. Behind the scenes the app has called our /households endpoint which gets a list of Sonos households associated with the authorized account:

You can see in the code above that we’ve inserted an Authorization header with our recently-fetched access token.

It’s important to note that the /households endpoint that the front-end app is calling is not the Sonos Control API command, but is to the back-end server we’ve built. Remember, the front-end app doesn’t know anything about Sonos. The back end is taking care of all the calls to Sonos as well as handling all authentication.

I’ve built a little bit of UX goodness in to the app. If there’s only one household available for the account, the household select list is not displayed. This is the case for the vast majority of accounts out there. Once the user picks a household (or the single household has been automatically selected), the app calls our /clipCapableSpeakers endpoint. Again, /clipCapableSpeakers is a custom endpoint we’ve built on our back-end server.

After making a GET /groups call to the Sonos Control API, our back-end sorts through the resulting list of players provided in the response. Normally we’d only select those players that have the AUDIO_CLIP capability flag. However, at the time of this writing, that flag has not been implemented. We’ll return all the players and let the user decide which will work with audio clips.

Now the user can select a speaker and in the text box below type something for the speaker to say. After hitting submit, we finally call our custom /speakText endpoint on our back end. The handler for this endpoint receives the text to speak and the selected speaker id. The first thing it does is call the google tts service to turn that speech text into a URL that will play the spoken text:

We take the returned URL, add it to our request body, and make a POST to /audioClip on the Sonos Control API.

If everything went well here, the user’s speaker just spoke their typed text. Imagine the possibilities!

Wrap Up

We did a few cool things here: we built a simple React app, We actually implemented authorization against the Sonos servers, and we made a few calls to the Sonos Control API. The end result of all this work is that now our speakers can talk to us.

A really neat next step here would be to secure the back-end server side of this code, put it in the cloud, and have your own private Sonos TTS service. You could hook up any kind of front-end to that you want. Maybe some IFTTT Webhooks? That’d go a long way towards implementing the “announce the football score” scenario I noted at the beginning of this post.

Again, you’ll find everything you need at the github repo. Head over and check it out.

Thanks for reading this post, and building a basic Sonos TTS app with us. We’re really excited about all the things developers and partners will do with audioClips.

– Matt Welch – Principal Developer Advocate
Currently listening to C’est La Vie No.2 by Phosphorescent

New APIs: audioClip & playlists

With the October 9th release of Sonos version 9.2, we’re excited to bring you two new namespaces with new APIs:audioClip and playlists. See Release notes for Sonos software for customer-facing features.


Audio clip

You can now play short audio clips on Sonos speakers. Check out the audioClip namespace for details.

This namespace is experimental. Some of the functionality may not yet work as documented. For example, the AUDIO_CLIP capability in the player object has not yet been released, so you won’t be able to tell which players support audio clips and which do not. Currently, the only players that support audio clips are the Sonos One and the Beam. See the groups object for details about capabilities.

We’ll let you know when we’ve added more functionality. Keep an eye on this blog for details.


Playlists

Your app or hardware integration can now get the list of Sonos playlists in a household and load one to start playback. Sonos activates the chosen playlist in the default playback session and starts playback, as if the user selected the playlist using the Sonos app. See the playlists namespace for details.


We look forward to seeing these new APIs in your apps and hardware integrations!

How Sonos Does Sound: An Introduction to Our Sound Experience Guidelines

In creating Sonos products for the last 16 years, we’ve thought a lot about how sound is experienced in the home. In fact, the company was founded on the desire to create a better home-listening experience for our customers: we thought about the experiences we wanted to create first, and then designed the hardware and software to enable them. Our platform is now open, and our team has been hard at work creating tools, guidelines, and API documentation that will help our partners build great experiences to benefit our mutual customers.

Our designs at Sonos have been informed by making prototypes and products and seeing how people interact with them to enjoy music, radio, podcasts, and other types of content in the home. We’ve learned about how they want to choose content; how they want to play different songs in different rooms or the same song in multiple rooms; and how they want to adjust the output volume in one or more rooms. To help give you a head-start with your integration, we’ve gathered many of our findings into the Sonos Sound Experience Guidelines and made them available on our portal. The guidelines are non-technical and focus on user experience rather than APIs and technical know-how. They are intended for a wide audience of designers, product managers, business owners, and developers.

Over the years, we’ve also seen how people use different interfaces to interact with Sonos, such as voice, screen-UI, gestures, and physical controls. We’ve learned that the use of one interface type over another isn’t based purely on user preference but can change during the course of a day. The types of interface a user chooses might be based on convenience, the number of people listening (or watching), the type of content being played, and the activities of people in the house. People expect these different interfaces to work in concert, seamlessly and without technical hiccup. We call this seamless interaction continuity of control and we talk about it in our guidelines. We really want our partners to build on this continuity of control, and we believe that our own Sonos products are just the start.

Obviously, some pretty elaborate technology is needed to enable multi-room interaction and to ensure a seamless experience for our users. However, we believe it is essential to remember that people want to focus on their lives, their family, and their friends, and not be distracted by technology. It is therefore critical that technical complexity does not translate into difficult, time-consuming, or frustrating experiences. To this end, we’ve created a chapter in our guidelines that discusses some key principles of designing with simplicity in mind. We use these principles ourselves and encourage you to consider them for your integration.


People want to enjoy their lives, not be distracted by technology

 

We think you’ll find the Sound Experience Guidelines useful and informative, and we’re looking forward to seeing what you create. We’re hoping to see a few products and features that we’ve considered at Sonos, but more importantly, we’re excited about seeing partner implementations we’ve never imagined. Good luck with your integration, have fun with the Sonos platform, and let us know if you have any feedback.

Regards,
Rob Lambourne
Distinguished Designer, Sonos Platform Team

Currently listening to: Big Red Machine
First concert: The Wedding Present, Derby, UK

Put Some Music On: Your First Sonos Platform Calls with Postman

The Sonos Control API has been used to build some really great experiences. These range from big and ambitious, to smaller and more straightforward. But what if you want to start smaller still? What if you just want to dip your toe in, and get a feel for how things fit together? We’ll find out one way to do that in this post.

Postman is a configurable REST client, used to test and experiment with APIs. We’ll use it to set up authentication, and build some Control API calls. Let’s forget the UX and presentation and everything else associated with a full-fledged app. We’re going to focus on nothing but getting the music playing.

If you’re the type that likes to read the last page of a good book, scroll to the bottom, where I’ve included all the work done here in a pre-packaged project for you to use. But you should still read the rest of the post!

Getting Started

First, let’s collect our materials:

  • A set-up and configured Sonos system, obviously. Make sure you can play some content on it.
  • The username and password associated with that Sonos system.
  • A few Sonos Favorites saved and showing up in My Sonos.
  • A Control Integration, complete with a Client Key and Secret.
  • An installed copy of Postman, the REST client.
  • Some good hacking music. I’d suggest something by Matthew E. White.

Fire up Postman and look around. We’ll build the required Environment and Collection to generate Sonos API calls.

Set Up the Environment

Before we get started on actual API calls, we need to set up an Environment for our collection to use. An environment, in Postman, is a collection of variables that any collection has access to. So, for instance, you can use {{auth_url}} instead of api.sonos.com. This lets you use the variable in multiple places, and only change the variable value in the environment definition if that value ever needs to change.

Let’s get our Environment set up. Click on the “Manage Environments” button in the upper right of the Postman window. It looks like a gear icon. Then, click on the big, orange “Add” button. Fill it out such that it looks like this:

 

Let’s go over each of the environment variables we’ve specified.

auth_host – The host that handles Sonos authorization calls.
api_host – The host that handles Sonos Control API calls.
client_key – The client key provided when you create a new Control Integration.
client_secret – The client secret provided when you create a new Control integration.

Once you’ve gotten everything set up as noted above, click on “Update”, then close the Environment window. We’re ready to start actually making calls.

Authorization

The next thing we’re going to want to do is create a new collection. A Postman collection is, well, a collection of related REST calls that can share resources. In our case, we’re going to build the authorization handling right in this collection. We’ll let the REST calls contained inside the collection use this authorization so we don’t have to reconfigure for every call.

Click the “New Collection” button in the left column of the Postman window.

 

Give your collection a name, and a description of you’d like.

 

Click on the “Authorization” tab. This is where we do the first really meaty, interesting part. Before we go any further, it’s a good idea to read over the Authorize section of our documentation. That’ll explain the details behind what we’re doing here, and will help make things more clear when you’re building an actual implementation and don’t simply have form fields to fill in.

On the “Authorization” window, select “OAuth 2.0” for the type, and “Request Header” for “Add auth data to”. As noted in our documentation, we employ a standard OAuth 2.0 3-legged OAuth flow, and require that the acquired token is included in request headers.

 

Now we’re going to click on the big orange “Get New Access Token” button on the right side of the window. Here, we’ll fill in the information required to actually get an access token. Fill in everything, so that it looks like this:

 

You’ll note a bunch of orange values, surrounded by double curly brackets. Those are the Postman environment variables, which you set up in the previous section.

Let’s run through these fields, one at a time.

Token Name – You can use whatever you want. This is just so that you can remember the token you fetched. I just leave it at the default
Grant Type – Sonos employs an Authorization Code flow, so you should select that here.
Callback URL – This is the URL that is called when the Sonos auth servers want to send the user back to your integration. This callback URL should be prepared to receive data involved in the auth flow, as described in our Authorization docs. This Callback Url must match the redirect uri you specified when you created your Control Integration on the developer portal. The “http://localhost” value included in this screenshot is for my specific integration, and should be changed to match your setup. Note that, while Postman calls it a Callback URL, it is more commonly referred to as a redirect uri. Sonos uses this name, and in fact has a separate, unrelated Control Integration parameter called “Callback URL” which is for player eventing.
Auth URL – This is the URL that an integration will call to get the initial Authorization Code
Access Token URL – An integration will call this URL, with the authorization code, to get access and refresh tokens.
Client ID – The client ID that was generated for you when you created your Control integration.
Client Secret – The client secret that was generated for you when you created your Control integration
Scope – The types of abilities your integration is requesting on behalf of the user. At the time of this writing, the only available scope for Sonos is “playback-control-all”.
State – A value built in the OAuth spec that is used to prevent cross-site forgeries. The {{$guid}} value in the screenshot is a random value generator (more or less) provided by Postman.

Once this is all filled out, click on the big orange “Request Token” button. This will initiate an actual OAuth flow against the Sonos servers, exactly as a user would see inside an actual integration. You’ll be directed to the Sonos login page, told a bit about how to prepare your Sonos system to integrate with third parties, and then be prompted for your username and password.

 

Once you’ve successfully supplied your credentials, you’ll be told about the capabilities the integration is asking for. These are defined by the “scope” parameter in your Authorization calls.

 

Once you click “OK” here, the user is sent back to the redirect/callback URI specified above. Normally, your hypothetical integration would take over at this point, getting the authorization code, then exchanging it for the access token. In this case, though, Postman scrapes the redirect call, gathers the required data, and completes the OAuth flow itself, eventually presenting you with a token that you can choose to use.

Congratulations! You’ve successfully authenticated against the Sonos platform!

Making Your First Call

Now that Postman has the authentication information the Sonos requires for any API call, we can start building those calls. Before we can get to the really fun stuff, like music playback, we have to understand a bit about the user’s system. The user, in this case, is whoever logged in to the Sonos authorization page in the section above. We’ll want to get a list of available households first. Usually, there will be only a single household per user, but it’s quite possible for a user to have more than one. In either case, we need to get a householdId to use to make further calls. You can read a more high level description of this flow in the “Discover” section of our documentation.

Click on the ellipsis (“…”) button on the bottom right of your collection in Postman, then select “Add Folder”. I like to create folders for each namespace in the Sonos API, so I’ll call this one “households”. On the description tab, enter “households” as the Name.

Next select the Authorization tab. This is where Postman really comes in handy. Instead of rebuilding our authorization flow from scratch, we’ll simply select “Inherit Auth from parent” for the type.

Click the orange “Create” button to create the folder and to close this window. Now, let’s add our first request. Click the ellipsis button on the “households” folder. Sometimes you need to hover the mouse over the folder name for this menu to appear. Then, click the “Add Request” menu item. Let’s call this one “households”, since we’ll be doing a simple GET /households request.

You’ll notice that when you save it, it is conveniently labeled right inside the parent folder, with the http method (GET, in this case) helping us identify it. Select the request in the column on the left, and notice that request details page that becomes visible. This is where we’ll specify the command endpoint, as well as any body elements that are required. Fill out the request details as noted below

Notice again that we’re using environment variables, this time {{api_host}}, to build our request. Note also that we’ve once again specified that the request should inherit its auth from its parent. Auth flow from the top level collection is being passed down to the “households” folder, then down to this GET /households request.

For a simple GET /households request, this is all that’s required, so let’s make our very first call! Click on the big blue “Send” button. You should get back a JSON body that looks something like this:

There you go! You’ve got your list of Sonos households available to the authenticated user. Note the household id returned above, as we’ll need that for the next section. If you’ve got more than one household available, just pick one of the ids returned.

Finding Out What Groups and Players are Available

Most commands on the Sonos Control API require either the householdId or the targeted groupId. We’ve got the hhid, so let’s make a call and get a target groupId. We’ll build a GET /groups request to return what we’re looking for. Just as above, we’ll make a new folder, this time for the “groups” namespace, and then a new request inside that new folder for the actual GET /groups call. To summarize:

  1. Create a new “groups” folder.
  2. Create a new “groups” command.
  3. Set the auth type to “inherit”, and enter the URL as such: https://{{api_host}}/control/api/v1/households/<< householdId from above >>/groups

If you click “Send” now, you should get back a groups response object that contains all of the players in the household, as well as a listing of how those players are currently grouped. It’ll look something like this

Just like before, we’re going to want to grab a groupId from one of these, so pick a group that looks interesting from the groups object in the response. Note the associated groupId. In the example above, there are two groups returned, so I might choose the “Office Speakers + 1” group, with the RINCON_11111:12345 id.

Get the Sonos Favorites

So we’ve gotten all the boring housekeeping out of the way; now it’s time to actually make our Sonos speakers do something. Let’s put a Sonos Favorite on the group you just selected. If you haven’t done so yet, make sure you’ve added something to “My Sonos”, which is the Sonos app container for favorites and playlists. We’ll use the favorites namespace to look for saved favorites, then play one back.

The first thing we’ll want to do is execute a GET /favorites command. You know the drill at this point:

  1. Create a new “favorites” folder underneath the top level collection.
  2. Create a new “favorite” command.
  3. Set the auth type to “inherit”, and enter the URL as such: https://{{api_host}}/control/api/v1/households/<< householdId from above >>/favorites

That’s it. If you hit “Send” now, you should get back a JSON body containing all of the Sonos Favorites you’ve saved. It should look something like this:

Pick your favorite Favorite, and note the id. We’ll be using that in the next section.

Finally, Let’s Play Some Music

We’ve gotten the household id. We’ve used that to get the list of available groups, and then picked a group id. We’ve gotten a favorite id. Not let’s put it all together and play that favorite on that group.

Inside the existing “favorites” folder, let’s create a new request, and call it “loadFavorites”. Have it inherit its parent’s auth, of course. But here’s where things get a little different. The first thing we’ll do is change the HTTP method from the default GET to POST. This means we’re sending data to the request endpoint instead of just asking for data. Check out the following screenshot of how you should get things configured.

You’ll note that this time, we’ve included a request body by clicking on the “Body” tab in the request. The JSON in that body tells Sonos which favorite id to play, and how to queue it up. Obviously, if the favorite you’ve selected is a streaming radio station, setting the play mode shuffle to TRUE doesn’t make any sense, and is ignored.

Hitting “Send” on this request should result in your selected Sonos Favorite playing on your selected Sonos group. Congratulations! You’ve built your first Sonos app. Of course, there’s no UX around it, and you’re doing all the heavy lifting instead of letting code do it, but make no mistake, this is an integration.

Wrap Up

We’ve learned here how to use Postman to authenticate against Sonos’ servers, and how to make requests to find out about the state of a user’s system. And finally, we actually made music play. From here, some great next steps would be to implement more commands, like volume or playback control, inside Postman. Get a feel for how things fit together.

A couple notes:

  1. Obviously, you can’t subscribe to any eventing with Postman.
  2. For whatever reason, Postman doesn’t implement support for refresh tokens, so you’ll have to go back in to the top collection’s Authorization screen and request a new token every 24 hours.

And finally, here’s a special treat. Clicking this button will import a new Postman Collection and Environment, all set up with a number of Sonos namespaces. In addition, I’ve created a number of post-request scripts that will parse the results, and do things like automatically populate groupIds into calls. All you need to do is open the enclosed Environment and set “target_player” to the name of a player in your household, and add your client key and secret. After that, every time you run the GET /groups command, Postman will look for your player in the response, find its current group, and use that groupId in other requests, like loadFavorite.

Thanks for reading, and we’re so excited that you’re building great things with us.

Meet Your Sonos Sound Platform Dev Advocates

Welcome to the Sonos Sound Platform. We’d like to take a couple minutes of your time to introduce ourselves. We’re the developer advocates for the Sonos platform, and we can’t wait to help you build incredible experiences for our listeners.

Matt

I’m Matt Welch, and I’m the lead dev advocate for the platform. My sole goal is to help devs and partners build incredible things on our platform. I’ve been a Sonos owner for about 8 years, and was actually hacking on Sonos before I even joined the company. I wrote a lot of blog posts on the subject in that unofficial capacity. I’m looking forward to writing a lot of posts here in my more official capacity.

Currently listening to: Great Thunder, the latest Waxahatchee record
First Concert: Adam Ant at the Norfolk Boathouse

Nancy

I’m Nancy Hernandez, a developer advocate here to support you through your journey on the Platform. I’ve been at Sonos for over 4 years now and enjoying every minute. Look forward to connecting with you through this blog.

Currently listening to: Rock This
First Concert: Wango Tango at the Rose Bowl

Of course, we’re just the public representatives of the platform. There’s a big team that has built this platform over the past few years. We are deeply grateful to and proud of them. We’ll be introducing them to you all on this blog as we grow the platform together.

Welcome. Let’s Build Great Things

We won’t keep you any more, as we know you’re anxious to start making things. Dig in to our docs, read about everything you can do, and build great experiences for our listeners. We’ll leave you with a playlist of tunes, selected by the men and women who built the Sonos Sound Platform. This was the fuel that drove our team as we put this all together. We hope it helps you make great things.

Introducing the Sonos Sound Platform: Building the Future of the Sonic Internet

We’re opening up our developer platform and APIs to make it easier than ever to partner with Sonos and build new sound experiences for the home.

To most, we make speakers. But when you think about the unique experience you have with Sonos, it owes just as much to the magic of the underlying software as it does to hardware. It’s through our platform that, together with partners, we can bring new experiences to listeners, ultimately providing unparalleled freedom of choice across music services, audiobooks, television and video content, podcasts, voice service and home automation.

When Sonos first got started 16 years ago, the technology landscape looked very different. For one thing, on-demand streaming music services didn’t even exist. Fast forward to today and the pace of innovation has been profound; the rise of streaming media, cloud computing, artificial intelligence and Internet of Things (IoT) technology are now pervasive, allowing developers to rapidly bring innovation to market.

Today, we begin the next chapter of partnering at Sonos by introducing the Sonos sound platform, which brings together new APIs, developer tools and documentation. In launching the new platform, we have three specific objectives in mind.

  1. Create new opportunities for our partners

    • Three trends are transforming the home audio market: the rise in paid streaming, rise of voice assistant speakers and the rise of the smart home. The Sonos sound platform will be the gateway through which partners can harness this growth with their own innovative solutions.
    • New cloud APIs allow us to deliver advanced capabilities for partners to build upon. Similarly, enhanced LAN-based APIs support solutions that demand low latency or the local network.
    • We will introduce capabilities to the sound platform on a regular cadence so that our joint-customers continue to get new experiences over time. We will listen carefully to our partner community and customers to make sure we are prioritizing the right investments.
  2. Making the platform more approachable for developers

    • The sound platform’s modernized APIs allow more developers than ever to bring their solutions to market. We will also invest in samples, SDKs and libraries to make it easier and faster for developers to build against the new platform.
    • Our new developer portal (https://developer.sonos.com), provides one place to create, configure and monitor integrations. Our developer advocates will be active in the community on Stack Overflow and GitHub so developers can get support with development. This blog will serve as one place to learn about new platform innovations as well as technical posts from developer advocates and product team members at Sonos.
    • Finally, our documentation has been written from the ground up with comprehensive content for developers of all experience levels, with getting started guides and technical reference docs. In addition, our Sound Experience Guidelines capture the essence of the Sonos “experience”, helping developers craft solutions that delight the user.
  3. Provide customers more personalized experiences and confidence through certification

    • We are working to add intelligence to the sound platform so customers can enjoy more natural and personal experiences on Sonos and will enable our partners to complement with their own smarts, over time.
    • The “Works with Sonos” badge allows customers to confidently identify partner solutions that work seamlessly with the Sonos system. We will continue to invest in ways for customers to more easily discover and engage with partner solutions. More details on the Works with Sonos program will be shared in a future blog post.
    • Finally, in addition to new capabilities, we will continue to invest in the reliability and security of our platform to ensure customers receive predictable experiences they expect from Sonos and our partner integrations.

With today’s launch, we are releasing a set of new control APIs that allow developers to observe and control Sonos players. Coming later this year in October, we will be following up with additional capabilities:

  • Notifications/Audio Clips – Play short, discrete sounds and notifications on a player without fully interrupting the music. The song or audio will lower in volume and resume following the notification.
  • Sonos Playlists – The ability to list and start playback of Sonos Playlists within a third-party interface.
  • Max Volume and Volume Pass-through – Partner integrations will be able to set the maximum volume of Sonos players, as well as subscribe to volume events for fixed-volume players. This will allow, for example, an A/V receiver to have its volume controlled via the Sonos app when connected to a Sonos Connect.

Thank you for your ongoing partnership as we help the world listen better, together.

James Senior
Director of Product, Platform & Partnerships, Sonos
@jsenior

An Overview of the Sonos Platform

We’re proud of the documentation we’ve created to help our partners build great experiences on the Sonos Sound Platform. But one thing we’ve heard is that newcomers to the platform can sometimes struggle to get their bearings as they try to decide which parts of our platform are relevant to their integration.

Today we’re happy to announce a significant improvement to our documentation the will help put the various capabilities of the platform into context. We’ve built a “choose your own adventure” path to guide you towards developing the best experience for your integration with Sonos.

Starting on the Plan & Build page, you can learn more about the Sonos system and the Sonos Sound Platform, then choose which kind of integration you are working on. From there, we describe the features and architecture relevant to you.

We thank you for the continuing feedback about our platform and about the support we provide. We made these changes as a direct result of that feedback. We can’t wait to see what great things you’ll create next.

Voice (and more!) Comes to Sonos

This is a post we’ve been looking forward to writing for a while now. We’ve been hard at work over the past few years on the platform you all have been working with, and we’ve been thrilled to see the ways in which it’s been put to use. Today, at an event in New York City, we finally got to tell the world about the Sound Platform for the Connected Home, and talk about some of the incredible experiences that we’re all building, together, on top of it.

Our CEO, Patrick Spence, spoke about the “Sonic Internet”, how voice and sound is changing how the internet is perceived and controlled, and how Sonos will be central to that shift. Our platform, announced today, is key to our ability to lead in this time of change, and everything we talked about today has been enabled by it. Here’s a quick run down.

Alexa Integration with Sonos

Starting today, Sonos owners will be able to control their systems with an Amazon Echo, Dot, or other Alexa device. Ask for the Beatles in the Bedroom, or your local radio station in the kitchen. Sonos with voice control makes it easier and faster to enjoy great sounding music in your home. Using this beta integration, any Sonos speaker can be controlled simply by speaking to your Alexa device.

The Platform

You all have been developing on our platform for almost two years, and have helped us as we’ve grown and improved it. We were thrilled to announce today that in 2018 Sonos will officially open its developer platform and deliver APIs to any developer who wants to integrate with Sonos. This means that, starting next year, all kinds of new innovative integrations will start appearing for Sonos, with the experiences you’re building now leading the way. If you’ve built something great on our platform and want to release it, please don’t hesitate to reach out.

Today we also rolled out a certification program so the highest quality experiences will have the ability to earn the “Works with Sonos” badge. This badge will help highlight to consumers the highest quality experiences on Sonos. As we grow our understanding of and capacity for certification, we won’t be able to certify a large number of partners. The goal to eventually make certification a submission-based process.

AirPlay 2.0

Sonos is bringing AirPlay 2.0 to its platform, available in 2018. You will be able to play sounds from devices in the Apple ecosystem on apps that support AirPlay, including content from YouTube and Netflix, in any or every room of the home. Having access to all the music and content in the world goes beyond on-demand services. Sonos listeners want to send all manner of sounds from their devices to the Sonos speakers, and we’re thrilled that we’ll give them that option next year.

Sonos One

Sonos One is the smart speaker for music lovers, unlocking voice control for your entire Sonos system. Start the music playing with voice, add songs to your playlist from the Sonos app, play music in a different room from your Spotify app —the experience is seamless. Amazon Alexa comes built-in, with support for multiple voice services coming in the future, including the Google Assistant in 2018.

As you can see, this was a big event for us, and we’re thankful for your patience and the help you’ve provided that has led to this moment.

We’re all just getting started.

Create client credentials

Use client credential keys to identify and authorize your integration on Sonos.


Company/Organization administrators and members

When you first sign up to the developer portal, if you are the first in your company or organization to sign up, you’re added as the administrator of your company. Administrators can:

  • Invite other users to collaborate.
  • Promote users to administrators.
  • Remove users.
  • Create integrations and client credentials.

If you’re a user in a company or organization, you can view the list of other users, but you can’t invite other users or manage users. You can also view integrations and client credentials, but you can’t create or manage them.


Invite others to collaborate

As an administrator, you can invite others from your company to join the site to collaborate on your Sonos integration.

users

To invite users:

  1. Click My Account in the top-right of the screen and choose Users.
  2. Enter an email address and click Send invite.

The user will receive an email invitation with a link to sign up. Once they sign up they’ll be able to see you in the Users list and you’ll be able to see them.

To manage users:

  • Select the check box in the Admin? column to promote them to an administrator.
  • Click Remove to remove a user. Users can remove themselves as well.

Note: You can’t invite users that are already on the developer portal as part of another group.


Create an integration

As an administrator, you can also create an integration.

add integration

To create an integration:

  1. Click My Account at the top-right of the page.
  2. Click Integrations.
  3. Click New control integration.
  4. Fill out the fields described below. To make changes, edit the field and click Save to save changes.

To delete an integration, click Delete.

Note: Fields are required unless marked optional.

Display name and description

Enter a display name and description for your integration.
integration description

Name Description
Display name… Enter a name for your integration. Sonos displays this name to users in the Sonos login service, when asking if they want to give permission to your integration.
Briefly describe your integration Provide a brief description of your integration to help us understand what you will be providing to users and how it will work.

Credentials

Create your client credentials.

integration credentials
Name Description
Key name Enter a name for your client credential key. This can be the name of your product, product family, or SKU. You may also want to use the key name to differentiate between different environments or locales. For example, you may have one key for your test environment and one key for your production environment.
Key The client credentials key generated by Sonos.
Secret The client credentials secret generated by Sonos.
Redirect URIs Enter redirect URLs so the Sonos login service can send the user back to your client with an authorization code. You can enter multiple redirect URLs. The redirect URL in your authorization API call must match one of the redirect URLs that you provide here. See Authorize and Authorization API for details.
Event Callback URL (Optional) Enter an endpoint that Sonos can use to send events. You can only enter one. See Subscribe for details.

Operations

The Operations tab provides the opportunity to supply information about your company to help Sonos better support our customers when your integration goes live. You are welcome to fill this information out now, but it is not required to begin development.

Debugging Your Cloud Queue with Wireshark

You’ve read our documentation and built a fantastic cloud queue implementation. You’ve got your contexts and queue versions all set up. You fire up the cloud queue (CQ) server, point loadCloudQueue at it, and… nothing. The music doesn’t play. What next?

The first step to seeing what’s going on is to understand what the player is asking for from the cloud queue server, and what the server is telling it. Now, you could build all kinds of logging in to your server (you should probably be doing that anyway!), but it’s often a very iterative, time consuming process to arrive at exactly what kind of logging you need. And even then, it’s difficult to display all logged data in a way that’s easily digestible.

Enter Wireshark.

Wireshark is a robust app, but with that extensive capability comes some complexity, at least for those of us who aren’t networking savants. But if we can arrive at the right settings, Wireshark is a fantastic tool for looking at cloud queue traffic.

Important Caveat

The techniques we’re about to talk about here will be really valuable for debugging cloud queue implementations, but they’re predicated on observing traffic over insecure HTTP. If you try to observe the traffic over secure connections, you can’t see what’s being sent and received. So: develop on insecure endpoints, deploy to production after you’ve debugged, and with secure endpoints.

Hardware Setup

Wireshark can most easily examine network traffic to and from the local machine, so you’ll have to run your cloud queue server locally. There are some tricks we can employ that’ll let us look at traffic between a player and a remote server. We’ll look at those a bit later.

I’ve got our cloud queue sample server running on my dev machine, along with Wireshark. This machine is connected via Wi-Fi to the same network as my Play:5. Hardwired Ethernet would be fine, too.

Example Sonos Player and Computer IP Addresses

Once we’ve gotten the IP addresses for the two devices, we can begin to configure Wireshark to examine CQ traffic. I’ll leave it to you to get the IP address of your computer, but to get that of your target Sonos speaker, simply open the “About My Sonos System” section of the Sonos App.

Wireshark Setup

In the above setup, we can see that the Sonos player is at IP address 192.168.55.190. That means we’ll want to tell Wireshark to look at all traffic to and from this address. To do this, we want to “Capture …using this filter” on the opening screen of Wireshark.

Wireshark Capture Settings

First, select the network interface you’ve connected to your Wi-Fi network. It’s usually pretty easy to figure out which one to select, as the active interface will have a small activity waveform after its entry in the list.

In the filter text field, we’ve specified that we want to examine traffic from a “host” with an IP address of 192.168.55.190. If we wanted to only examine traffic in one direction, we could prepend the above input with either “src” or “dest”. We want it all, so we’ll leave those off.

Once you’ve got everything the way you want it, hit “Enter” to be taken to the Wireshark Capture screen.

Wireshark Capture

We’re capturing cloud queue packets between the player and the server! That’s great, but the problem is, we’re capturing a bunch of other, distracting stuff as well. (This stuff is useful information, but not when you’re looking to debug your CQ server.) Things are just really hard to sort, so we’re going to apply a display filter.

First, let’s talk about what we’re interested in capturing. We know that the cloud queue server receives HTTP callouts from the player, things like GET /itemWindow or POST /timePlayed. And we know the CQ server responds with JSON bodies. So those are the two things we’re really interested in here. Luckily Wireshark has some display filters that meet our needs.

Let’s start with our first type of captured data: HTTP requests from the player. It turns out that Wireshark has a display filter called, simply, http. We could just use that, and we’d get all the HTTP callouts, both from the player and from the CQ server (though we know the server won’t be making any callouts). The problem with simply using http by itself is that the player makes a lot of other HTTP callouts that are unrelated to cloud queue activity. All this extra information clutters our results.

So let’s drill in a bit on that http display filter. It turns out we can do things like look at the URL, or even the path. That last part is interesting to us. As I noted, I’m using our CQ sample server, which has a default path of http://ip.address/musicqueue/1.0. We can reference that “musicqueue” part when we specify an HTTP URL path to examine.

The second type of data we’re looking for is the JSON responses from the CQ server to the player. You won’t be surprised to find out that Wireshark has a json display filter. It also has a bunch of neat filters, like the ability to filter by keys. We pretty much want all the JSON data going back and forth between our two devices under observation, so we’ll just stick with json.

Putting the two together, using the boolean operator support in Wireshark, we come up with something like http.url.path contains "musicqueue" || json. Once we put that in the display filters text box, our traffic becomes more readable.

Examining Cloud Queue Traffic

Taking a look at the example image below, the first thing we can see is an HTTP callout, as noted in the “Protocol” column. This callout is from 192.168.55.190, our player IP address, to 192.168.55.174, our CQ server. Looking at the “Info” column, you can see that it was a callout to the GET /itemWindow endpoint, with various itemWindow request variables, like itemId, included as URL parameters. You can click on the image to open a bigger version in a new window.

Cloud Queue Traffic Between Server and Player

The very next line is the response from the server. This request/response relationship is noted by Wireshark in the far left column with the light grey outgoing and incoming arrows. If you click on the response entry, as I’ve done in the image, you can examine specifics about the HTTP response. What we’re interested in is the JSON response body, which I’ve expanded. In there, you can see many of the expected GET /itemWindow response values, like our items array, and the individual item objects inside.

Congratulations! Now go fix that cloud queue bug, and bring the joy of music to your listeners’ homes.

Cloud Queue Debugging Extra Credit

Remember above where I mentioned that we were limited to running the CQ server on the same machine as Wireshark, due to the fact that only traffic to and from the local machine is visible on a network interface? Well, that’s not exactly true. There’s a technique we can use to examine traffic between a player and a remote server. Doing so requires just a little bit of network understanding.

Modern networks are switched, which means that a network interface (like the ethernet port on your computer) will only get traffic that is meant for that IP address. Stuff happening elsewhere never makes it to that ethernet port. Routers and switches take care of all that stuff for us, and our networks are vastly better off for their efforts.

But we want ALL the traffic, right? It turns out, we can get it all. Back in the early days of networking, a lot of intranets were built with simple ethernet “hubs”, which basically just broadcast anything coming into the hub out to everything connected to the hub. Packet chaos, sure, but a “feature” that we can exploit, if we configure our network correctly.

Both the Sonos player you want to examine and the computer running Wireshark will need to be wired via an Ethernet connection to the hub. Your setup will look something like the image below.

Wireshark “Spying” Hardware Setup

As you can see, the player and the CQ server are free to communicate as usual. The difference is that the Wireshark machine is able to “spy” on all that traffic. To do that, we’ll want to set up Wireshark to gather the appropriate communications. Using what we learned, above, we can either target all traffic coming from and going to the player, or the server. In this case, it’s actually easier to target the traffic to and from the server, as it’s pretty certain that we’re interested in all of it.

So we set up the Capture page in Wireshark with “host server.ip.address.or.hostname”. Below, I’ve substituted the fake IP address “w.x.y.z” for the real one I was using. (Security through obscurity!)

Wireshark “Spying” Capture Setup

Once we’ve got this set up, and then apply our display filters on the capture page, we can easily see traffic between a cloud queue server and a player.

Wireshark “Spying” Capture

Wrap Up

Wireshark can be a valuable tool in your Sonos Platform dev toolkit. It provides the ability to not just see data in context, but to save an entire capture to a Wireshark format to distribute for education or support purposes.