Skip to content
SoundTouch Speaker Endpoint Documentation

SoundTouch Speaker Endpoint Documentation

This document describes the implementation of the /speaker endpoint for Bose SoundTouch devices, which enables Text-To-Speech (TTS) notifications and URL content playback.

Overview

The /speaker endpoint is used to play notification content on SoundTouch devices, including:

  • Text-To-Speech messages using Google TTS
  • Audio content from HTTP/HTTPS URLs
  • Notification beeps (via /playNotification endpoint)

Important: This functionality is primarily supported by ST-10 (Series III) speakers. ST-300 and other models may not support this endpoint despite it appearing in their supported URLs.

API Reference

POST /speaker

Plays notification content on the speaker.

Request Body:

<play_info>
  <url>URL_TO_AUDIO_CONTENT</url>
  <app_key>YOUR_APPLICATION_KEY</app_key>
  <service>SERVICE_NAME</service>
  <message>MESSAGE_DESCRIPTION</message>
  <reason>REASON_OR_FILENAME</reason>
  <volume>VOLUME_LEVEL</volume> <!-- Optional: 0-100, omit for current volume -->
</play_info>

Response:

<?xml version="1.0" encoding="UTF-8" ?>
<status>/speaker</status>

GET /playNotification

Plays a simple notification beep sound.

Important: This endpoint requires a GET request, not POST. Earlier versions of this client library incorrectly used POST and would fail with HTTP 400 status.

Response:

<?xml version="1.0" encoding="UTF-8" ?>
<status>/playNotification</status>

Go Client Library Usage

Text-To-Speech (TTS)

package main

import (
    "log"
    "github.com/gesellix/bose-soundtouch/pkg/client"
    "github.com/gesellix/bose-soundtouch/pkg/models"
)

func main() {
    config := &client.Config{
        Host: "192.0.2.100",
        Port: 8090,
    }

    client := client.NewClient(config)

    // Play TTS at current volume (language code "EN", "DE", etc.)
    err := client.PlayTTS("Hello, this is a test message", "YOUR_APP_KEY", "EN")
    if err != nil {
        log.Fatal(err)
    }

    // Play TTS at specific volume (70)
    err = client.PlayTTS("Volume test message", "YOUR_APP_KEY", "EN", 70)
    if err != nil {
        log.Fatal(err)
    }
}

URL Content Playback

func main() {
    config := &client.Config{
        Host: "192.0.2.100",
        Port: 8090,
    }

    client := client.NewClient(config)

    // Play audio from URL
    err := client.PlayURL(
        "https://example.com/audio.mp3",
        "YOUR_APP_KEY",
        "Music Service",
        "Song Title",
        "Artist Name",
        50, // volume level
    )
    if err != nil {
        log.Fatal(err)
    }
}

Custom PlayInfo

func main() {
    client := client.NewClient(config)

    // Create custom play info
    playInfo := models.NewPlayInfo(
        "https://example.com/audio.mp3",
        "YOUR_APP_KEY",
        "Custom Service",
        "Custom Message",
        "Custom Reason",
    ).SetVolume(60)

    err := client.PlayCustom(playInfo)
    if err != nil {
        log.Fatal(err)
    }
}

Notification Beep

func main() {
    client := client.NewClient(config)

    // Uses GET request (fixed in v2025.02+)
    err := client.PlayNotificationBeep()
    if err != nil {
        log.Fatal(err)
    }
}

CLI Usage

Text-To-Speech

# Basic TTS (English)
soundtouch-cli speaker tts --text "Hello World" --app-key YOUR_KEY --host 192.0.2.100

# TTS with volume and language
soundtouch-cli speaker tts \
  --text "Bonjour le monde" \
  --app-key YOUR_KEY \
  --volume 70 \
  --language FR \
  --host 192.0.2.100

URL Content Playback

# Basic URL playback
soundtouch-cli speaker url \
  --url "https://example.com/audio.mp3" \
  --app-key YOUR_KEY \
  --host 192.0.2.100

# URL playback with custom metadata
soundtouch-cli speaker url \
  --url "https://example.com/song.mp3" \
  --app-key YOUR_KEY \
  --service "My Music Service" \
  --message "Beautiful Song" \
  --reason "Artist Name" \
  --volume 60 \
  --host 192.0.2.100

Notification Beep

soundtouch-cli speaker beep --host 192.0.2.100

Help

# General speaker help
soundtouch-cli speaker --help

# Detailed functionality help
soundtouch-cli speaker help

# Command-specific help
soundtouch-cli speaker tts --help
soundtouch-cli speaker url --help

Supported Languages for TTS

The following language codes are supported for Google TTS:

CodeLanguage
ENEnglish
DEGerman
ESSpanish
FRFrench
ITItalian
NLDutch
PTPortuguese
RURussian
ZHChinese
JAJapanese
KOKorean
ARArabic
HIHindi
THThai

Behavior Notes

  1. Volume Control: If a volume is specified, the device will:

    • Switch to the specified volume for playback
    • Automatically restore the previous volume after playback completes
    • If volume is 0 or omitted, content plays at current volume
  2. Content Interruption:

    • Currently playing content is paused during notification playback
    • Original content resumes automatically after notification ends
    • If currently playing content is already a notification, you may get an error
  3. Multiroom Behavior:

    • If the device is a zone master, notifications play on all zone members
    • Volume changes affect all devices in the zone
  4. Now Playing Display:

    • Service name appears in the “artist” field
    • Message appears in the “album” field
    • Reason appears in the “track” field
    • Custom artwork can be included in URL-based content

Error Handling

Common errors and their meanings:

  • Device not found: Check host/port configuration
  • Endpoint not supported: Device doesn’t support /speaker endpoint (common with ST-300)
  • Invalid app key: App key is required for TTS and URL playback
  • Network timeout: Check device connectivity
  • Invalid URL: URL must be accessible and contain valid audio content

App Key Requirements

Both TTS and URL playback require an app_key parameter. This appears to be used for:

  • Request authentication/identification
  • Rate limiting
  • Service tracking

You’ll need to provide your own application key. The format and generation method for valid app keys is not documented in the official API.

Google Cloud Text-to-Speech (via the AfterTouch service)

The direct speaker tts path above hands the speaker an (undocumented) Google Translate URL to fetch. That endpoint is fine for short notifications but is low quality, length-limited, and can change without notice.

For higher-quality speech (real voices, SSML, many languages) the AfterTouch service can synthesize audio with Google Cloud Text-to-Speech and host it locally for the speaker to play. Because Cloud TTS returns audio bytes from an authenticated request (not a fetchable URL), the service caches the clip and serves it at GET /media/tts/{id}, then tells the speaker to play that local URL via /speaker. The same app_key constraint applies.

Provider selection

The service picks a TTS provider via --tts-provider (env TTS_PROVIDER):

  • translate (default): the Google Translate URL path. No credentials.
  • google-cloud: Google Cloud TTS via a REST API key. No OAuth, no SDK.

Configuration (soundtouch-service)

FlagEnvPurpose
--tts-providerTTS_PROVIDERtranslate or google-cloud
--tts-google-api-keyTTS_GOOGLE_API_KEYGoogle Cloud TTS API key (required for google-cloud)
--tts-languageTTS_LANGUAGEDefault language. EN/DE for translate, BCP-47 like en-US for google-cloud
--tts-voiceTTS_VOICEDefault Cloud TTS voice (e.g. en-US-Neural2-C); ignored by translate
--tts-app-keyTTS_APP_KEYBose /speaker app_key used to play the clip
--tts-volumeTTS_VOLUMEDefault playback volume (0-100, 0 = keep current)

Example:

TTS_PROVIDER=google-cloud \
TTS_GOOGLE_API_KEY=YOUR_GOOGLE_API_KEY \
TTS_LANGUAGE=en-US \
TTS_VOICE=en-US-Neural2-C \
TTS_APP_KEY=YOUR_APP_KEY \
soundtouch-service

Triggering speech

Service HTTP API (under /setup, LAN-trust like the rest of the setup surface, no auth):

curl -X POST http://soundtouch.local:8000/setup/tts/speak \
  -H 'Content-Type: application/json' \
  -d '{"host":"192.0.2.100","text":"Dinner is ready"}'

deviceId may be used instead of host (the service resolves it to an IP from its datastore). Optional fields: language, voice, volume, and method (speaker, the default /speaker notification path that ducks and resumes playback, or radio, the LOCAL_INTERNET_RADIO path that needs no app_key but replaces the current source).

CLI (speaker tts-cloud routes through the service for Cloud TTS, in contrast to speaker tts which sends a Google Translate URL straight to the speaker):

soundtouch-cli speaker tts-cloud \
  --service-url http://soundtouch.local:8000 \
  --host 192.0.2.100 \
  --text "Dinner is ready" \
  --method speaker

Web UI: the TTS source view has a “Say something…” box. soundtouch-player proxies it to the service, so it must be started with --service-url (the target is server-configured, not entered in the browser, to avoid an SSRF proxy).

Notes and limitations

  • app_key validation is handled automatically (speaker method). The speaker validates the key by calling GET /v1/auth on Bose’s audio notification host (audionotification.api.bosecm.com, and a …dev… variant), which AfterTouch intercepts (DNS substring match on bosecm.com, plus /etc/hosts seeding during migration) and answers 200. So any non-empty app_key works; you don’t need a real Bose-issued key. The radio method needs no app_key at all.
  • Model support for the speaker method is the same as the direct /speaker path (primarily ST-10 Series III). Use --method radio on models without it.
  • Reachability: the speaker must be able to reach the service’s /media/tts/{id} URL. The service builds it from its configured server-url.
  • Synthesized clips are cached in memory for a short time and identical requests reuse the same clip.

Limitations

  1. Device Support: Limited to specific SoundTouch models (primarily ST-10 Series III)
  2. Audio Formats: Supported audio formats depend on device capabilities
  3. URL Requirements: URLs must be publicly accessible (no authentication)
  4. TTS Length: Very long TTS messages may be truncated
  5. Concurrent Playback: Cannot play multiple notifications simultaneously

Integration Examples

Home Automation

// Doorbell notification
client.PlayTTS("Someone is at the front door", "home-automation-key", "EN", 80)

// Security alert
client.PlayURL(
    "https://myserver.com/alerts/security-breach.mp3",
    "security-system-key",
    "Security System",
    "Alert",
    "Motion detected in restricted area",
    100,
)

Development/Testing

# Test connectivity
soundtouch-cli speaker beep --host 192.0.2.100

# Test TTS functionality
soundtouch-cli speaker tts --text "Testing TTS functionality" --app-key test-key --host 192.0.2.100

# Test URL playback
soundtouch-cli speaker url --url "https://www.soundjay.com/misc/sounds/bell-ringing-05.wav" --app-key test-key --host 192.0.2.100

Troubleshooting

  1. Command not found: Ensure you’re using a supported SoundTouch model
  2. No audio output: Check volume levels and device status
  3. TTS not working: Verify internet connectivity for Google TTS service
  4. URL content fails: Ensure URL is accessible and contains valid audio
  5. Volume not restored: May occur if device is powered off during playback

For more information, see the SoundTouch WebServices API documentation.

Last updated on