This document describes the architecture, protocol specification, Granular Security protections, subscription model, command correlation, and event broadcasting for the Solaris Real-Time WebSocket API (ws://localhost:45321/api/v1/ws).
The WebSocket Streaming API provides a full-duplex, low-latency communication channel for real-time applications, dashboard widgets, and background daemons.
type: "update").subscribe and unsubscribe message types.snapshot frame (_buildSnapshotMap) and real-time broadcasts (broadcastModule, broadcastEvent) are filtered dynamically according to per-key ApiPermissionsConfig.subscription_revoked frames without severing TCP/WS connections.maxClients = 20). Upgrade attempts exceeding this limit are rejected with HTTP 503 Service Unavailable./api/v1/ws requires the Solaris Control API to be active (isApiServerEnabled = true). If Solaris Control API is disabled in settings, incoming upgrade attempts are rejected with HTTP 503 Service Unavailable (RFC 7807 problem details: Solaris Control API Disabled).4001 when an API key is deleted, token is regenerated, or requireLocalToken is enabled.cmd_id) subject to category permissions (allowedCategories).1008).ws://localhost:45321/api/v1/ws
or over LAN (if LAN mode enabled):
ws://<SOLARIS_HOST_IP>:45321/api/v1/ws
Tokens can be passed using any of the following 3 formats:
GET /api/v1/ws?token=sol_sec_ae1302d9e99a8b6aad30264417a64cec8ac1b17c20f5abc5cea38b5dea368eae01234567 HTTP/1.1
Host: localhost:45321
Upgrade: websocket
Connection: Upgrade
const token = 'sol_sec_ae1302d9e99a8b6aad30264417a64cec8ac1b17c20f5abc5cea38b5dea368eae01234567';
const socket = new WebSocket('ws://localhost:45321/api/v1/ws', [`bearer.${token}`]);
X-API-Key: sol_sec_ae1302d9e99a8b6aad30264417a64cec8ac1b17c20f5abc5cea38b5dea368eae01234567
or standard Authorization header:
Authorization: Bearer sol_sec_ae1302d9e99a8b6aad30264417a64cec8ac1b17c20f5abc5cea38b5dea368eae01234567
When a WebSocket connection closes, Solaris transmits precise status codes and reason strings:
| Close Code | Reason String | Trigger Condition |
|---|---|---|
1000 |
Normal Closure | Client gracefully disconnected. |
1001 |
Solaris API Server Stopping / PC Entering Sleep Mode |
Host user or OS turned off Control API server or PC entered sleep state. |
1001 |
Heartbeat failed |
Socket heartbeat timeout (ping/pong failure). |
1008 |
Slow Consumer: Pending buffer limit exceeded 512 KB |
Pending frame queue exceeded 512 KB memory limit. |
4001 |
Key Revoked |
Host user deleted the API key associated with this connection. |
4001 |
Token Regenerated |
Host user regenerated the secret token for this key. |
4001 |
Local Auth Required |
Host user enabled requireLocalToken = true while an anonymous socket was open. |
Upon connection, Solaris sends an initial snapshot frame containing current subsystem states.
{
"type": "snapshot",
"data": {
"version": "1.5.2+1",
"timestamp": "2026-07-25T14:30:00.000Z",
"monitors": [
{
"id": "\\\\.\\DISPLAY1",
"name": "LG UltraGear 27GP850",
"friendly_name": "LG UltraGear A1F9",
"slug": "display-1",
"device_id_hash": "a1f9",
"is_primary": true,
"brightness": { "current": 80, "target": 80.0, "offset": 0.0, "mode": "auto" },
"temperature": { "enabled": true, "current": 5500, "target": 5500, "mode": "auto" },
"game_mode": { "enabled": true, "active": false }
}
],
"solar": {
"elevation": 42.5,
"azimuth": 185.3,
"zenith": 47.5,
"progress": 0.65,
"current_phase": "day",
"uv_index": 4.2,
"spectral_intensity": 0.88
},
"weather": {
"available": true,
"temperature_celsius": 24.5,
"weather_code": 0
},
"sleep": {
"is_sleeping": false,
"sessions_count": 12,
"last_session_end": "2026-07-25T07:00:00.000Z"
},
"automation": {
"auto_brightness": true,
"auto_temperature": true,
"color_temperature_hardware_enabled": true,
"weather_brightness_adjustment": true,
"weather_temperature_adjustment": true,
"weather_adjustment_intensity": 0.45,
"smart_circadian": true,
"game_mode": {
"enabled": true,
"active": false,
"brightness_override": 80.0,
"temperature_enabled": true,
"temperature_override": 6500.0
}
}
}
}
type: "subscribe")Subscribing adds modules to the client’s active subscription set.
{
"type": "subscribe",
"modules": ["solar", "monitors"]
}
Response (type: "subscribed"):
{
"type": "subscribed",
"active_modules": ["solar", "monitors"]
}
type: "subscription_denied"):Emitted if a client attempts to subscribe to a module disabled in its API key permissions:
{
"type": "subscription_denied",
"module": "solar",
"reason": "Read access disabled in API permissions"
}
type: "subscription_revoked"):Emitted asynchronously when a host user disables read access for a module while a socket is active:
{
"type": "subscription_revoked",
"module": "solar"
}
type: "unsubscribe"){
"type": "unsubscribe",
"modules": ["automation"]
}
Response (type: "unsubscribed"):
{
"type": "unsubscribed",
"active_modules": ["solar", "monitors"]
}
type: "update"){
"type": "update",
"module": "solar",
"timestamp": "2026-07-25T14:30:00.000Z",
"data": {
"elevation": 42.5,
"azimuth": 185.3,
"zenith": 47.5,
"progress": 0.65,
"current_phase": "day",
"next_event": {
"type": "sunset",
"in_seconds": 18400
},
"uv_index": 4.2,
"spectral_intensity": 0.88
}
}
Every 30 seconds, the Solaris API server broadcasts a heartbeat ping to active WebSocket clients:
{
"type": "ping",
"timestamp": "2026-07-25T14:30:00.000Z"
}
Clients may also send a ping to verify connection liveness:
{
"type": "ping"
}
Server Response:
{
"type": "pong",
"timestamp": "2026-07-25T14:30:00.000Z"
}
type: "event"){
"type": "event",
"event": "on_system_resume",
"timestamp": "2026-07-25T14:30:00.000Z",
"data": {
"timestamp": "2026-07-25T14:30:00.000Z"
}
}
type: "event")Broadcasted when per-application profile rules or exit delay settings are updated:
{
"type": "event",
"event": "app_override_changed",
"timestamp": "2026-07-25T14:30:00.000Z",
"data": {
"app_overrides": [ ... ],
"exit_delay_seconds": 5
}
}
type: "event")Broadcasted when the foreground process changes or a per-app override rule applies:
{
"type": "event",
"event": "active_process_changed",
"timestamp": "2026-07-25T14:30:00.000Z",
"data": {
"active_process": "photoshop.exe",
"window_title": "Adobe Photoshop 2026",
"is_gaming": false,
"applied_override": {
"exeName": "photoshop.exe",
"appDisplayName": "Adobe Photoshop",
"isEnabled": true,
"isBuiltIn": true,
"brightnessMode": "global",
"temperatureMode": "fixed",
"fixedTemperature": 6500.0
},
"evaluated_brightness": 80.0,
"evaluated_temperature": 6500.0
}
}
type: "event")Broadcasted when a DDC/CI read/write error or I2C bus collision is detected:
{
"type": "event",
"event": "on_hardware_error",
"timestamp": "2026-07-25T14:30:00.000Z",
"data": {
"detail": "DDC/CI I2C Bus NAK on display \\\\.\\DISPLAY1",
"timestamp": "2026-07-25T14:30:00.000Z"
}
}
cmd_id Correlation)type: "command"):{
"type": "command",
"cmd_id": "ws-cmd-001",
"action": "set_brightness",
"value": 90.0,
"monitor_id": "display-1"
}
[!NOTE] When Extra Dark Dimming is enabled in application settings, the
valueparameter forset_brightnessaccepts floating-point values from-100.0to100.0. In the negative range (< 0.0), physical monitor backlights are kept at 0% DDC/CI while a click-through Win32 DWM overlay smoothly darkens the screen down to an 85% opacity safety floor.
{
"type": "command",
"cmd_id": "ws-cmd-002",
"action": "set_temperature",
"value": 1900.0,
"monitor_id": "dell-u2720q"
}
[!NOTE] The
set_temperaturecommand accepts color temperatures from1000.0to6500.0Kelvin. Values in the 1000K–3300K range utilize the 111-point Planckian Blackbody spectrum LUT via Win32 GDI & WCS APIs. Specifyingmonitor_id(or friendly slug such asdisplay-1or model base slugdell-u2720q) targets an individual display with independent manual temperature control. If omitted, the temperature is applied globally across all connected monitors.
type: "response"):{
"type": "response",
"cmd_id": "ws-cmd-001",
"status": "ok",
"action": "set_brightness",
"applied": {
"value": 90.0,
"monitor_id": "display-1"
},
"error": null,
"message": null
}