Skip to content

Instantly share code, notes, and snippets.

@rody64
Last active March 9, 2026 08:29
Show Gist options
  • Select an option

  • Save rody64/98a59990ff60ea962cac72cbe93edf56 to your computer and use it in GitHub Desktop.

Select an option

Save rody64/98a59990ff60ea962cac72cbe93edf56 to your computer and use it in GitHub Desktop.
A comprehensive guide to a possible solution for streaming internet radio to Bose SoundTouch speakers via local UPnP (Gerbera) and configure presets using Home Assistant, Python API, or WebServices after Bose's cloud service EOL in Feb 2026.

🎵 Play Internet Radio on Bose SoundTouch After Cloud Shutdown (Feb 2026)

This setup should allow your Bose SoundTouch speakers to continue playing Internet radio locally after Bose discontinues its cloud services (February 2026).
This method is experimental until confirmed after the official EOL.

It replaces the soon-to-be-retired TuneIn integration while keeping local playback working.

Note: Based on recent community testing, SoundTouch presets will likely stop working after the Bose cloud shutdown in February–March 2026 unless a workaround is found.

08-12-2025 — Removed most of this Gist because there’s a much simpler solution than using the Gerbera media server: hosting a JSON description of the radio station on an HTTP server (thanks to user gmuth).
19-11-2025 — Added testing notes:
thlucas1/homeassistantcomponent_soundtouchplus#37 (comment)


🧪 Preliminary Conclusion

Testing strongly indicates that even for “local” services like UPnP (STORED_MUSIC), Bose SoundTouch devices still rely heavily on the Bose cloud for initial setup and for enabling/persisting certain features.

This means that once the Bose cloud services are truly shut down, it is highly likely that:

  • Factory-reset devices will not be able to register new UPnP or other music services via the API or the app.
  • Existing configurations may disappear, especially presets, if the device attempts to “re-authenticate” or periodically sync with the now-absent cloud.

This reinforces the need to have SoundTouch devices fully configured and cloud-registered before the EOL date, hoping that existing configurations will continue to work for local playback afterward.

Possible directions for long-term solutions

  • Reverse-engineering the cloud interaction and simulating the required responses locally
  • Using an external device on AUX IN (e.g., a streamer or Raspberry Pi) to provide radio and other sources independent of the SoundTouch cloud

📡 Using JSON to Store a Radio Station

You can host a JSON description of the radio station on any HTTP server, e.g. bbc1.json.

Create a file such as bbc1.json containing:

{
  "audio": {
    "hasPlaylist": false,
    "isRealtime": true,
    "streamUrl": "http://bbc.com/stream/..."
  },
  "imageUrl": "",
  "name": "BBC 1",
  "streamType": "liveRadio"
}

Place this file on your HTTP server.

Now store the station to preset 1 using:

curl -d @- http://soundtouch:8090/storePreset << XML
<preset id="1">
  <ContentItem source="LOCAL_INTERNET_RADIO" type="stationurl" location="http://yourserver/bbc1.json">
    <itemName>BBC 1</itemName>
  </ContentItem>
</preset>
XML

📝 Notes

  • Stream URLs must use HTTP, not HTTPS.
  • Sometimes the SoundTouch does not start the preset immediately — a reboot usually fixes it.
  • This method remains experimental until confirmed after the SoundTouch cloud EOL in February 2026.
  • Also check out soundcork, which aims to intercept SoundTouch API calls and may offer a long-term solution:
    https://github.com/deborahgu/soundcork
@vigeland
Copy link

vigeland commented Nov 14, 2025

curl -X POST \
  -H "Content-Type: application/xml" \
  -d '<credentials source="STORED_MUSIC" displayName="gerbera">
        <user>345be6-2870-44cd-8ca4-85439f9ae0e0b/0</user>
        <pass/>
      </credentials>' \
  http://192.168.107.95:8090/setMusicServiceAccount
  
  I think <pass/> is wrong
  If I change I got
  <?xml version="1.0" encoding="UTF-8" ?><errors deviceID="XXXXXX"><error value="1019" name="CLIENT_XML_ERROR" severity="Unknown">Error parsing request</error></errors>
  
 Thanks for supporting
  

@rody64
Copy link
Author

rody64 commented Nov 17, 2025

I got the <pass/> from:
https://github.com/thlucas1/homeassistantcomponent_soundtouchplus/wiki/SoundTouch-WebServices-API#music-service---set-account
See "Figure 2b - Service Request, POST Body, NAS Library".

<credentials source="PANDORA" displayName="Pandora Music Service">
<user>YourPandoraUserId</user>
<pass>YourPandoraPassword$1pd</pass>
</credentials>

The <pass/> looks strange but it seems to work.

@vigeland
Copy link

vigeland commented Nov 17, 2025

<pass/> is ok, ist XML classic empty value. Today most of code is json.

@gmuth
Copy link

gmuth commented Dec 5, 2025

You can put a json description of the radio station to a http server e.g. as bbc1.json. Than you can store the radio station to preset 1.

curl -d @- soundtouch:8090/storePreset << XML
<preset id="1">
  <ContentItem source="LOCAL_INTERNET_RADIO" type="stationurl" location="http://yourserver/bbc1.json">
    <itemName>BBC 1</itemName>
  </ContentItem>
</preset>
XML

@rody64
Copy link
Author

rody64 commented Dec 6, 2025

Great news that the JSON description is working!

@gmuth So, for Internet radio, this looks like Gerbera isn't needed, which should simplify the setup completly?

The key next step is definitely more testing on preset persistence once the Bose cloud is offline.

Also, highly relevant: check out the soundcork project. It aims to intercept the API, which could be the ultimate long-term solution:
https://github.com/deborahgu/soundcork

@phfuh
Copy link

phfuh commented Feb 7, 2026

I’ve started a small list of radio station JSON files, in case anyone’s interested:
https://codeberg.org/phfu/soundtouch-radio-json

@gmuth
Copy link

gmuth commented Feb 7, 2026

@phfuh, it's kind of brute force but you could convert the entire radio station database from radio-browser.info (available in one big json list) into single json files using the bose json format.

Source type LOCAL_INTERNET_RADIO will stop working in May. You can verify by denying the device access to bose cloud servers (e.g. by using a blacklist filter of your router).

@phfuh
Copy link

phfuh commented Feb 8, 2026

@gmuth thanks for the quick feedback. Blocking content.api.bose.io completely crashes the app, but using the presets on the device and the streams works fine. Also, blocking streaming.bose.com and events.api.bosecm.com doesn’t break presets or streams.

The idea of my list is to simplify the process for the end user. Making an API call is already complicated enough for a normal user.

For myself, I have an n8n workflow that generates a JSON file based on data from Radio Browser.

@phfuh
Copy link

phfuh commented Feb 8, 2026

Device reboot is working, but power disconnect is not. After a power disconnect, you need to unblock content.api.bose.io once.

After a power disconnect, the box checks content.api.bose.io every minute until unblocked. In the blocked state, the box is reachable over the API and the presets are still present. It seems to me that the call to content.api.bose.io is only a connectivity check.

@bilboo9696
Copy link

Hi there,

sorry for maybe asking a silly question but new to this all here.

Where exactly do you run the curl command with the xml instructions from to set the preset keys with the .json fiel on the http web server..... can you run it from a command prompt on windows?

tnx a mil

@phfuh
Copy link

phfuh commented Feb 20, 2026

The simplest way is to use Insomnia, Postman, or something similar to send your requests as i wrote in my repository mentioned above.

On Windows, you can also try using Invoke-WebRequest in PowerShell. It should look something like this:

$url = "https://example.com/api"

$xmlBody = @"
<?xml version="1.0" encoding="UTF-8"?>
<Request>
    <Name>John Doe</Name>
    <Email>john.doe@example.com</Email>
</Request>
"@

Invoke-WebRequest `
    -Uri $url `
    -Method Post `
    -Body $xmlBody `
    -ContentType "application/xml"

@sdenengelsman
Copy link

I still can't believe Bose is doing this...
I can't help coding (stopped with coding some time ago) but am happy to try things every now and then. I have several Soundtouch Wireless Link devices and a Soundtouch 20, which I hope will all keep working as I use them on a regular basis, especially the Spotify streaming feature.
I'll keep an eye on the messages here :-)

@timvahlbrock
Copy link

@phfuh, it's kind of brute force but you could convert the entire radio station database from radio-browser.info (available in one big json list) into single json files using the bose json format.

Wouldn't it be even nicer, to create a proxy application (or maybe even contribute it to radio-browser.info) that is able to just convert the information radio-browser.info already provides into the required format?

Source type LOCAL_INTERNET_RADIO will stop working in May. You can verify by denying the device access to bose cloud servers (e.g. by using a blacklist filter of your router).

Is there any source that this will definitely be the case? Did Bose want to provide one more update before may? Maybe this update will allow using LOCAL_INTERNET_RADIO without the Bose Soundtouch servers?

@timvahlbrock
Copy link

Is there any source that this will definitely be the case?

Seems like this is still unclear, at least Bose support gave me conflicting information/couldn't help me with that. If the update in may fixes that, switching existing presets to LOCAL_INTERNET_RADIO would be the best option in my point of view. Though some other thread indicate that without adjustments in the update presets will survive reboots without the Bose servers.

@gmuth
Copy link

gmuth commented Mar 9, 2026

I tried UPNP and QPLAY - so this might indeed provide a solution to play radio streams without requiring the user to gain root access.
SoundTouch provides multiple options: UPNP, QPLAY and STORED_MUSIC. We still need a Client App that can be used to start the stream (like mconnect). @rody64, could you document how to setup a UPNP stream - maybe with a simple docker setup? My router supports this feature so I can see:

<nowPlaying deviceID="..." source="UPNP" sourceAccount="UPnPUserName">
  <ContentItem source="UPNP" location="http://192.168.2.1:49200/ST/AUDIO/DLNA-1-0/dispatcher.rndfnk.com/br/br3/live/mp3/mid" 
sourceAccount="UPnPUserName" isPresetable="false">

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment