Technical docs

Developer Documentation

DJConnect is a Home Assistant-first platform for Spotify or Music Assistant playback, voice remote control, Ask DJ, OTA, pairing and client integrations.

Home Assistant is the orchestration point

The custom integration coordinates pairing, backend playback, Assist/STT/TTS, Ask DJ, Music DNA, diagnostics and firmware update flows. Clients render state and send intent; they do not own Spotify backend credentials.

Architecture overview

Clients
ESP32Device runtime, audio, local UI and OTA target. No Spotify credentials.
iOS, macOS, watchOSHome Assistant API clients with optional Apple push wake/sync hints.
Raspberry Pi, WindowsLocal or desktop clients using DJConnect API contracts.
Home Assistant DJConnect integrationPairing, bearer token validation, Spotify OAuth/backend playback, Assist/STT/TTS, Ask DJ, Music DNA, diagnostics, OTA coordination and status cache.
Backends and services
Spotify Web API / Music AssistantPlayback and library operations through backend adapters.
Home Assistant Assist/STT/TTSVoice pipeline, transcript and spoken responses.
Central API / APNs relayOptional Apple push wake/sync hints with per-install djci_ tokens.
djconnect-firmwarePublic firmware releases and firmware_manifest.json.

Repositories

RepositoryPurposeRuntime/languagePublic roleLink
pcvantol/djconnectHome Assistant custom integration and canonical contracts.Python / Home AssistantOrchestration, API and HACS install source.GitHub
pcvantol/djconnect-appApple clients.Swift / SwiftUIiOS, macOS and watchOS clients.GitHub
pcvantol/djconnect-esp32Embedded firmware source.ESP32 firmwareDevice runtime, UI, audio and local device API.GitHub
pcvantol/djconnect-windowsWindows client.Windows desktop appDesktop client integration.GitHub
pcvantol/djconnect-piRaspberry Pi client.Python / LinuxLocal controller and display client.GitHub
pcvantol/djconnect-websiteProduct website and public docs.Static HTML/CSS/JS, Cloudflare Pages FunctionsWebsite, docs, downloads and operator UI.GitHub
pcvantol/djconnect-apiCentral API and APNs relay.Cloudflare / API serviceOptional Apple push relay and operator contracts.GitHub
pcvantol/djconnect-firmwarePublic firmware release repository.Release assetsFirmware binaries and manifests.GitHub

Client identity and pairing

Canonical client_type values are esp32, ios, macos, watchos, raspberry_pi and windows. The type must match the stable ID prefix.

djconnect-ios-XXXXXXXXXXXX
djconnect-macos-XXXXXXXXXXXX
djconnect-watchos-XXXXXXXXXXXX
djconnect-raspberry-pi-XXXXXXXXXXXX
djconnect-windows-XXXXXXXXXXXX
djconnect-lilygo-t-embed-s3-XXXXXXXXXXXX

Pairing rules

  • ESP32 status and pairing JSON payloads must include client_type: "esp32".
  • Pairing and status use bearer tokens. Token values must never appear in docs, logs or diagnostics.
  • App clients use Home Assistant API endpoints and do not store playback-backend credentials.
  • ESP32 firmware owns device runtime/audio/UI and stores no Spotify credentials.

API documentation

Examples use placeholders only: <HA_TOKEN>, <DEVICE_TOKEN>, <CLIENT_ID>, <DEVICE_ID>, <PAIRING_CODE> and <IMAGE_TOKEN>.

POST /api/djconnect/v1/status

Used by ESP32/local clients to publish current device status to Home Assistant. Auth: bearer device token.

{"client_type":"esp32","device_id":"<DEVICE_ID>","firmware_version":"3.2.16","battery_percent":84}
{"success":true,"paired":true,"server_time":"2026-07-05T08:00:00Z"}

POST /api/djconnect/v1/command

Used by app/device clients for playback, backend-aware actions, Ask DJ Play Now and confirmation responses. Auth: bearer HA/client token.

{"client_type":"ios","client_id":"<CLIENT_ID>","command":"play_track","value":"spotify:track:example"}
{"success":true,"music_backend":"spotify_direct","music_backend_available":true,"music_target_player":"Living Room"}

POST /api/djconnect/v1/voice

Used for voice/PTT upload or text-only DJ response tests. WAV requests use Assist/STT before command or Ask DJ handling. Auth: bearer HA/client token.

{"client_type":"macos","client_id":"<CLIENT_ID>","text":"Play the latest album by Nova Lane"}
{"success":true,"recognized_text":"Play the latest album by Nova Lane","message":"I found a matching album."}

POST /api/djconnect/v1/ask_dj/message

Text chat for iOS, macOS, watchOS, Raspberry Pi and Windows. client_message_id deduplicates retries. Auth: bearer HA/client token.

{"client_type":"watchos","client_id":"<CLIENT_ID>","client_message_id":"msg-001","message":"Why does this track fit my mood?"}
{"success":true,"messages":[{"role":"user","text":"Why does this track fit my mood?"},{"role":"assistant","text":"Because it matches your recent late-night groove."}],"history_revision":42}

GET /api/djconnect/v1/ask_dj/history?since_revision=<number>

Synchronizes server-side HA-user-scoped Ask DJ history to clients. Auth: bearer HA/client token.

{"success":true,"history_revision":42,"messages":[{"role":"assistant","text":"Try a mellow synth mix."}]}

POST /api/djconnect/v1/ask_dj/history/clear

Clears Ask DJ history for the authenticated Home Assistant user scope. Auth: bearer HA/client token.

{"client_type":"macos","client_id":"<CLIENT_ID>"}
{"success":true,"clear_revision":43}

POST /api/djconnect/v1/ask_dj

Developer/service Ask DJ entrypoint for structured requests. Auth: Home Assistant authenticated request.

{"message":"Suggest three quiet tracks","client_type":"macos"}
{"success":true,"text":"Here are three quiet picks.","intent":"personal_music_recommendations"}

POST /api/djconnect/v1/ask_dj/idle_suggestion

Backend-generated Ask DJ suggestion for idle clients that support it. Auth: bearer HA/client token.

{"client_type":"ios","client_id":"<CLIENT_ID>","locale":"en"}
{"success":true,"message":"Want a short discovery mix?"}

POST /api/djconnect/v1/music_dna/profile

Returns structured Music DNA dashboard/profile data. Music DNA is explicit opt-in. Auth: bearer HA/client token.

{"client_type":"ios","client_id":"<CLIENT_ID>"}
{"success":true,"enabled":true,"profile":{"summary":"Warm electronic listening pattern."}}

POST /api/djconnect/v1/music_dna/settings

Enables or disables Music DNA for the HA user scope. Auth: bearer HA/client token.

{"client_type":"macos","enabled":true}
{"success":true,"enabled":true}

POST /api/djconnect/v1/music_dna/clear

Clears learned Music DNA while preserving the opt-in setting. Auth: bearer HA/client token.

{"client_type":"macos","confirm":true}
{"success":true,"enabled":true,"cleared":true}

GET /api/djconnect/v1/music_discovery

Returns backend-owned Music Discovery recommendations from Home Assistant Music DNA. Auth: bearer HA/client token.

{"client_type":"ios","client_id":"<CLIENT_ID>"}
{"success":true,"enabled":true,"sections":[{"id":"daily","items":[{"id":"rec-001","kind":"track","title":"Midnight Circuit","reason":"Fits your recent late-night groove."}]}]}

POST /api/djconnect/v1/music_discovery/refresh

Refreshes the Home Assistant-generated discovery feed; clients never render recommendations from push payloads. Auth: bearer HA/client token.

{"client_type":"macos","client_id":"<CLIENT_ID>"}
{"success":true,"refresh_target":"music_discovery"}

POST /api/djconnect/v1/music_discovery/play

Starts a backend-owned recommendation through its section and item id, instead of generic local playback. Auth: bearer HA/client token.

{"client_type":"ios","section_id":"daily","discovery_item_id":"rec-001"}
{"success":true,"command":"play_now"}

GET /api/djconnect/v1/image_proxy/{token}

Serves external Ask DJ images through a safe proxy token. Auth: endpoint token plus Home Assistant access context.

GET /api/djconnect/v1/image_proxy/<IMAGE_TOKEN>
HTTP 200 image/jpeg

Local device API

Home Assistant uses local-device endpoints for ESP32/Raspberry Pi pairing, commands, OTA and DJ responses. Auth varies by pairing state and device bearer token.

POST /api/device/pair
GET /api/device/info
POST /api/device/command
POST /api/device/ota
POST /api/device/dj_response
{"pairing_code":"<PAIRING_CODE>","device_token":"<DEVICE_TOKEN>"}

Ask DJ contract highlights

  • Ask DJ history is server-side, HA-user scoped and synchronized through history endpoints.
  • messages[] is canonical for render order; client_message_id prevents duplicate chat entries.
  • Responses may include success, text, dj_text, message, messages[], user_message, assistant_message, history_revision, clear_revision, images[], links[], sources[], playback_actions[], confirmation_actions[], intent and action.
  • recently_played_history, track_insight, personal_music_profile_analysis and personal_music_recommendations are informational unless an explicit playback action is executed through /command.
  • External images must go through the image proxy.

Music backend architecture

DJConnect routes playback through a use-case/backend layer. Spotify Direct is the default backend; Music Assistant can be used as a backend adapter when configured. New playback/control code should call the backend adapter, not Spotify helpers directly.

music_backend
music_backend_name
music_backend_available
music_backend_revision
music_backend_capabilities
music_target_player
music_backend_error

Firmware / OTA

ESP firmware and the Home Assistant integration must share the same major.minor protocol version. A mismatch returns HTTP 426 with error: "version_mismatch". Public releases expose firmware_manifest.json with firmwares[] entries containing device, asset, url, sha256 and size. The LilyGO device key is lilygo-t-embed-s3; stable uses the latest non-prerelease and beta uses the latest prerelease.

Security and privacy

  • No Spotify credentials on ESP/app clients; Spotify OAuth uses PKCE in Home Assistant.
  • BLE provisioning writes only WiFi SSID/password.
  • Diagnostics redact keys containing token, password, secret, proof, authorization, prompt, history, memory or raw_audio.
  • Push payloads contain no tokens, raw prompts, full history, Music DNA dumps or long assistant text.
  • Music DNA is opt-in. Raw audio is not stored by default.