Skip to content

Spotify Connect Zeroconf Troubleshooting

Todd Lucas edited this page Aug 4, 2024 · 28 revisions

This page is devoted to troubleshooting Spotify Connect Zeroconf API issues. There are so many different Spotify Connect manufacturers out there that support the Zeroconf API; some of them do it well, while others leave much to be desired. Regardless of my opinion, let's dive right into it!

I'm a Windows OS kind of guy, so all OS command-line examples in this document are being ran on a Windows 11 (ESXi VM) machine.

This page is fairly lengthy, so use the following index to get to where you want to be:

Discovering Devices on the Local Network

The DNS Service Discovery (DNS-SD) protocol identifies and discovers devices on the network that are enabled with the zero configuration standard. DNS-SD uses multicast DNS (mDNS). mDNS sends packets to every node on the network to resolve duplicate host names and to query the network for services.

As stated in the Spotify Zeroconf API guide:
The hardware device must use mDNS/DNS-SD in a way compatible with Apple's Bonjour, to advertise its IP address, the port of its HTTP service, and the path to the ZeroConf API implementation on the web server.

To do this, the manufacturer's device (Speaker, TV, AVR, etc) must register and advertise its service(s) with a service type of _spotify-connect._tcp.. This will indicate to any interested party that the device supports the Spotify Connect Zeroconf protocol.

DNS-SD Service Discovery Tool

From a Windows command line, you can use the dns-sd command to browse for services that are being broadcast on the local network by mDNSResponder (a Bonjour system service that uses Multicast DNS Service Discovery for discovery of services on the local network).

The following topics explain the details of how to use this tool to discover and identify Spotify Connect devices on your local network.

DNS-SD Service Browse

So let's explore what Spotify Connect devices can be discovered on our network.

To do this, we will issue a DNS-SD command to browse for all services that support the Spotify Connect Zeroconf API.

Issue the following command (from an MS-DOS prompt) to browse for Spotify Connect device instance names are available on the local network:

dns-sd -B _spotify-connect._tcp. local.

Command Output: DNS-SD Service Browse

C:\Users\thluc>dns-sd -B _spotify-connect._tcp. local.
Browsing for _spotify-connect._tcp..local.
Timestamp     A/R Flags if Domain                    Service Type              Instance Name
13:54:33.369  Add     3  5 local.                    _spotify-connect._tcp.    Bose-ST300
13:54:33.369  Add     3  5 local.                    _spotify-connect._tcp.    Bose-ST10-1 + Bose-ST10-2 (L+R)
13:54:33.369  Add     3  5 local.                    _spotify-connect._tcp.    Bose-ST10-2
13:54:33.369  Add     2  5 local.                    _spotify-connect._tcp.    Bose-ST10-1
13:54:33.417  Add     2  5 local.                    _spotify-connect._tcp.    HAVM-SpotifyConnect

Per the command output, I have five different Spotify Connect device instance names on my network:

  • Bose-ST300
  • Bose-ST10-1 + Bose-ST10-2 (L+R)
  • Bose-ST10-2
  • Bose-ST10-1
  • HAVM-SpotifyConnect

DNS-SD Service Lookup

Now that we have a list of device instance names, we can query each device for its specific details. These details include the IP Alias of where the device can be reached on the network, the IP Port number that the device is listening on for Zeroconf API requests, as well as the CPath value that points to the ZeroConf implementation on the server.

Issue the following command (from an MS-DOS prompt) to display the device instance details for instance name Bose-ST10-1:

dns-sd -L "Bose-ST10-1" _spotify-connect._tcp local.

Command Output: DNS-SD Service Lookup

C:\Users\thluc>dns-sd -L "Bose-ST10-1" _spotify-connect._tcp local.
Lookup Bose-ST10-1._spotify-connect._tcp.local.
14:44:38.719  Bose-ST10-1._spotify-connect._tcp.local. can be reached at Bose-SM2-341513fbeeae.local.:8200 (interface 5)
 CPath=/zc VERSION=1.0

Per the command output, this device instance has the following attributes:

  • Instance Name = Bose-ST10-1
  • IP Alias = Bose-SM2-341513fbeeae.local.
  • IP Port = 8200
  • CPath = /zc
  • VERSION = 1.0

You can then repeat the dns-sd -L ... command for each instance name found in the listed devices output.

Armed with the above details about the device instance, we can now issue calls to the device to obtain more detailed information, logout of the device, and login to the device. All of these actions are done via the Spotify Zeroconf API services that are hosted on the device itself.

Zeroconf API Services: Spotify Connect

The Spotify Zeroconf API guide contains specifics on each of the service endpoints available.

To summarize, there are 3 service endpoint actions supported:

  • getInfo - retrieves detailed information about the device and what it is capable of.
  • addUser - logs a user into the device and makes it available to Spotify Player clients.
  • resetUsers - logs a user out of the device, and makes it unavailable to Spotifu Player clients.

These actions are supported by making an HTTP request to the service endpoint url for the desired action. Service endpoint url's can be formulated using the DNS-SD Service Lookup details, combined with the service action that you want to call.

Zeroconf API Service: Endpoint URL

A service endpoint url is comprised of the following parts:

http://<ipalias>:<port><cpath>?action=<action>&<version>=<versionvalue>

  • <ipalias> - DNS-SD Lookup IP Alias value (e.g. Bose-SM2-341513fbeeae.local.)
  • <port> - DNS-SD Lookup Port value (e.g. 8200)
  • <cpath> - DNS-SD Lookup CPath property value (e.g. /zc)
  • <action> - Service action to execute (e.g. getInfo)
  • <version> - DNS-SD Lookup Version property name (e.g. version)
  • <versionvalue> - DNS-SD Lookup Version property value (e.g. 1.0)

Using the above example values for the Bose-ST10-1 instance name and an action of getInfo, we come up with a service endpoint url value of:

http://Bose-SM2-341513fbeeae.local.:8200/zc?action=getInfo&version=1.0

The following topics explain each action in detail.

Zeroconf API Service: getInfo Action

The getInfo action returns specific information about a Spotify Connect device instance name. Refer to the Endpoint URL section above for how to formulate the service endpoint request url for this action, as well as how to interpret its output.

Issue the following request (from your desktop browser of choice) to execute this action for instance name Bose-ST10-1:

http://Bose-SM2-341513fbeeae.local.:8200/zc?action=getInfo&version=1.0
you could also specify the direct IP address of the device, if it's a static (or DHCP reserved) address:
http://192.168.1.81:8200/zc?action=getInfo&version=1.0

Endpoint Results: getInfo Action

{ 'status': 101,
  'statusString': 'OK',
  'spotifyError': 0,
  'version': '2.7.1',
  'deviceID': '30fbc80e35598f3c242f2120413c943dfd9715fe',
  'remoteName': 'Bose-ST10-1',
  'activeUser': '31l77y2123456789012345678901',
  'publicKey': 'zd0izOw8jx ...',
  'deviceType': 'SPEAKER',
  'libraryVersion': '3.88.29-gc4d4bb01',
  'accountReq': 'DONTCARE',
  'brandDisplayName': 'Bose',
  'modelDisplayName': 'Soundtouch',
  'resolverVersion': '0',
  'groupStatus': 'NONE',
  'tokenType': 'accesstoken',
  'clientID': '12345678901234567890123456789012',
  'productID': 70001,
  'scope': 'streaming',
  'availability': '',
  'voiceSupport': 'YES'
}

Zeroconf API Service: resetUsers Action

The resetUsers action should issue a call to SpConnectionLogout. The currently logged in user (if any) will be logged out of Spotify Connect, and the device id removed from the active Spotify Connect device list.

Refer to the Endpoint URL section above for how to formulate the service endpoint request url for this action, as well as how to interpret its output.

Issue the following request (from your desktop browser of choice) to execute this action for instance name Bose-ST10-1:

http://Bose-SM2-341513fbeeae.local.:8200/zc?action=resetUsers&version=1.0
you could also specify the direct IP address of the device, if it's a static (or DHCP reserved) address:
http://192.168.1.81:8200/zc?action=resetUsers&version=1.0

Endpoint Results: resetUsers Action

{
  'status': 101, 
  'statusString': 'OK', 
  'spotifyError': 0
}

Zeroconf API Service: addUser Action

The addUser action should cause the device to issue a call to SpConnectionLoginBlob. If successful, the associated device id is added to the Spotify Connect active device list for the specified user account.

The login (on the device) is performed asynchronously, so the return result only indicates whether the library is able to perform the login attempt. You should issue a call to the Spotify Web API Get Available Devices endpoint to check the current device list to ensure that the device id was successfully added or not.

Note that if you don't have a password setup for your Spotify account (e.g. you utilize the "Continue with Google" or other non-password methods for login), then you will need to define a "device password" in order to use the ZeroConf Connect service; use the Spotify Set Device Password page to define a device password. You will then use your Spotify username and the device password to Connect to the device.

Some Spotify Connect device types will be "woken up" with the initial addUser request; when this happens, the initial request will return a 203 status (ERROR-INVALID-PUBLICKEY), and return a valid public key in the response. This public key is then used to submit another addUser request to connect to the device with the newly returned public key. When this happens, a ZeroconfResponse object is returned with the result of the final addUser request. If only one addUser request is processed, then a ZeroconfGetInfo object is returned with the result of the addUser request. Note that ZeroconfGetInfo inherits from ZeroconfResponse, so you can always treat the result of this method as a ZeroconfResponse object.

Refer to the Endpoint URL section above for how to formulate the service endpoint request url for this action, as well as how to interpret its output.

You must also pass other parameters to this endpoint which contain the login details: username, blob, clientKey, loginId, and tokenType. The Spotify Zeroconf API guide does not disclose how to formulate these parameters, but some careful searching on the web reveals how it can be done.

Issue the following request (from your desktop browser of choice) to execute this action for instance name Bose-ST10-1:

http://Bose-SM2-341513fbeeae.local.:8200/zc?action=addUser&version=1.0
you could also specify the direct IP address of the device, if it's a static (or DHCP reserved) address:
http://192.168.1.81:8200/zc?action=resetUsers&version=1.0

Endpoint Results: addUsers Action

{
  'status': 101, 
  'statusString': 'OK', 
  'spotifyError': 0
}

# if an invalid publicKey was detected:
{
  'status': 203, 
  'statusString': 'ERROR-INVALID-PUBLICKEY', 
  'spotifyError': 0,
  'deviceID': '30fbc80e35598f3c242f2120413c943dfd9715fe',
  'publicKey': 'zd0izOw8jx ...'
}

Spotify Connect Device Tracing

The following walks you through how to trace Spotify Connect activity that takes place between the Spotify player (e.g. Spotify desktop app) and the Spotify Connect device (e.g. Bose Soundtouch, Sonos, Yamaha, etc).

Requirements

The following are required in order to capture Spotify Connect device activity:

  • Spotify desktop application installed, and logged on to your Spotify Premium account.
  • Spotify Connect enabled device, that shows up in the Spotify desktop device list.
  • Spotify Connect device endpoint URI - see the Spotify Connect Zeroconf Troubleshooting guide for more information on how to obtain the endpoint URI for a Spotify Connect device.
  • Network tracing tool (Wireshark, etc).

Capture Login Flow

Use the following steps to capture the Spotify Connect logon flow.

  1. Ensure that the Spotify desktop application is shut down; once we start it back up, it should re-discover any Spotify Connect devices on the network as well as log them in.

  2. Start the network trace, using your tool of choice (e.g. WireShark, etc). You can limit the trace to the IP addresses of the Spotify Connect device and the Spotify Desktop application, or capture everything and filter the results later.

  3. Issue a disconnect request to the device.
    This will cause the device to logout from Spotify, and remove the device from the Spotify player's active device list. You can use the curl command-line tool to do this, using the Spotify Connect device endpoint URI and action=resetUsers parameter as a POST request.

    Example, with response:

    C:\Users\thluc>curl -X POST http://192.168.1.82:8200/zc -d "action=resetUsers"
    {"status":101,"statusString":"OK","spotifyError":0}
    
  4. Start the Spotify desktop application.
    This should re-discover any Spotify Connect devices on the network, as well as log them in.

  5. Stop the network trace, and save the results.

Diagnose Trace Results

The trace file should contain requests made to the Spotify Zeroconf API endpoints. These requests are sent from the Spotify desktop player to the device.

Action addUser Requests

The addUser request and response will look something like this.

Note that the Spotify player does not perform the actual login for the device; it's the device itself that will issue the login request to Spotify directly via its embedded SDK software.

Some devices require multiple addUser requests and responses in order to login to Spotify.

Request #1 (POST)

POST /spotifyzc HTTP/1.1
Content-Type: application/x-www-form-urlencoded
x-www-form-urlencoded:

action=addUser
&userName=XXXX
&blob=
&clientKey=
&tokenType=default
&loginId=XXXX
&deviceName=mypc
&deviceId=eff383adad456422d43a77801a05ae587abf4095
&version=2.7.1

Response #1

HTTP/1.1 200 OK
Content-Type: application/json

{
  "status":203,
  "statusString":"ERROR-INVALID-PUBLICKEY",
  "spotifyError":0,
  "version":"2.9.0",
  "deviceID":"5d4931f9d0684b625d702eaa24137b2c1d99539c",
  "publicKey":"XXXX"
}

Request #2 (POST)

POST /spotifyzc HTTP/1.1
Content-Type: application/x-www-form-urlencoded

action=addUser
&userName=XXXX
&blob=XXXX
&clientKey=XXXX
&tokenType=default
&loginId=XXXX
&deviceName=mypc
&deviceId=eff383adad456422d43a77801a05ae587abf4095
&version=2.7.1

Response #2

HTTP/1.1 200 OK
Content-Type: application/json

{
  "status":101, 
  "statusString":"OK", 
  "spotifyError":0
}

Action resetUsers Requests

The resetUsers request and response will look something like this.

Note that the Spotify player does not perform the actual logout for the device; it's the device itself that will issue the logout request to Spotify directly via its embedded SDK software.

Request (POST)

POST /spotifyzc HTTP/1.1
Content-Type: application/x-www-form-urlencoded

action=resetUsers
&version=2.7.1

Response

HTTP/1.1 200 OK
Content-Type: application/json

{
  "status":101,
  "statusString":"OK",
  "spotifyError":0
}

Action getInfo Requests

The addUser request and response will look something like this.

Request (GET)

GET /spotifyzc?action=getInfo&version=2.7.1 HTTP/1.1\r\n
Content-Type: application/x-www-form-urlencoded

Response

HTTP/1.1 200 OK
Content-Type: application/json

{
  'status': 101,
  'statusString': 'OK',
  'spotifyError': 0,
  'version': '2.7.1',
  'deviceID': '5d4931f9d0684b625d702eaa24137b2c1d99539c',
  'remoteName': 'Bose-ST10-2',
  'activeUser': '',
  'publicKey': 'XXXX',
  'deviceType': 'SPEAKER',
  'libraryVersion': '3.88.29-gc4d4bb01',
  'accountReq': 'DONTCARE',
  'brandDisplayName': 'Bose',
  'modelDisplayName': 'Soundtouch',
  'resolverVersion': '0',
  'groupStatus': 'NONE',
  'tokenType': 'accesstoken',
  'clientID': 'XXXX',
  'productID': 70001,
  'scope': 'streaming',
  'availability': '',
  'voiceSupport': 'YES'
}

Spotify Connect Test Script

The following script can be used to test various Spotify Connect related services.

The following settings will need to be adjusted for your environment:

  • YOUR_SPOTIFYPLUS_ENTITY_ID - e.g. "john_smith_premium"
  • YOUR_SPOTIFY_USERNAME
  • YOUR_SPOTIFY_PASSWORD
  • YOUR_DEVICE_IP_ADDRESS - e.g. "192.168.1.82" EndPoint
  • YOUR_DEVICE_IP_PORT - e.g. 8200
  • YOUR_DEVICE_CPATH - e.g. "/zc"
  • YOUR_DEVICE_NAME - e.g. "LivingRoom"
alias: SpotifyPlus Connection Tests
sequence:
  - alias: Test Disconnect - remove device from player active device list
    service: spotifyplus.zeroconf_device_disconnect
    data:
      entity_id: media_player.YOUR_SPOTIFYPLUS_ENTITY_ID
      host_ipv4_address: YOUR_DEVICE_IP_ADDRESS
      host_ip_port: YOUR_DEVICE_IP_PORT
      cpath: YOUR_DEVICE_CPATH
    response_variable: response_Disconnect
  - alias: Test Connect - add device to player active device list
    service: spotifyplus.zeroconf_device_connect
    data:
      entity_id: media_player.YOUR_SPOTIFYPLUS_ENTITY_ID
      host_ipv4_address: YOUR_DEVICE_IP_ADDRESS
      host_ip_port: YOUR_DEVICE_IP_PORT
      cpath: YOUR_DEVICE_CPATH
      username: YOUR_SPOTIFY_USERNAME
      password: YOUR_SPOTIFY_PASSWORD
      pre_disconnect: true
    response_variable: response_Connect
  - alias: Test PlayerResolveDeviceId - resolve spotify connect deviceId from device name
    service: spotifyplus.player_resolve_device_id
    data:
      entity_id: media_player.YOUR_SPOTIFYPLUS_ENTITY_ID
      device_value: YOUR_DEVICE_NAME
      verify_timeout: 4
    response_variable: response_PlayerResolveDeviceId
  - alias: Test PlayerTransferPlayback - transfer playback to specified device name
    service: spotifyplus.player_transfer_playback
    data:
      entity_id: media_player.YOUR_SPOTIFYPLUS_ENTITY_ID
      device_id: YOUR_DEVICE_NAME
      play: true
description: >-
  Test Spotify Connect device control with various SpotifyPlus integration
  services.

How To Test

I would suggest running individual steps in the script, versus running all steps at once.

For example ...

  • Test Disconnect - Prior to running this test step, ensure that the device exists in the Spotify player's active device list. Run the test step, and then verify that the device was removed from the Spotify player's active device list. Also check the response data to ensure that the returned response contains the following: status=101, statusString=OK, spotifyError=0.

  • Test Connect - Prior to running this test step, ensure that the device does not exist in the Spotify player's active device list. Run the test step, and then verify that the device was added to the Spotify player's active device list.

  • Test PlayerTransferPlayback - Prior to running this test, start playing a track on a Spotify Connect device via the Spotify web / desktop / mobile player. Run the test step and verify that play was transferred to the specified device id / name.

Manufacturer Device Zeroconf Reference

The following documents the various manufacturer devices that support Spotify Connect, and that can be controlled via the Home Assistant SpotifyPlus integration.

This list is by no means complete, and is a work in progress. Please let me know if you have a device that can be controlled by the integration, but is not listed below, and I will get it added.

Manufacturer Device List

Sorted in alphabetical order by manufacturer.

Manufacturer Model CPath Port Notes
Blusound Powernode 330 /spotifyconnect 11000
Bose SoundTouch: ST-10, ST-300 /zc 8200
Home Assistant Addon SpotifyConnect / [*1]
Onkyo TX-NR727 /SpotifyConnect 8080 Ensure "Network Standby" setting is enabled.
Sonos Symfonisk /spotifyzc 1400 uses tokenType=authorization_code
TCL Roku TV 7128X, H130X /zc [*1]
Yamaha R-N402D, RX-V481BL /goform/spotifyConfig 80 with MusicCast support
``

[*1] port number is dynamic - use dns-sd -L to list details to find port number.