Skip to content

WebSocket API ​

Endpoint ​

  • URL: ws://127.0.0.1:8765
  • Loopback only - never exposed externally
  • Allowed origins: null (OBS Browser Source), file:// (Electron production), http://127.0.0.1:5173 (Vite dev)

To connect an OBS overlay, see the OBS Overlays reference.

Message Types ​

TypeDirectionDescription
commandclient → serverSend an action to a feature
responseserver → senderCommand result
updateserver → all clientsState broadcast
errorserver → all clientsRuntime error

Targeted Broadcasting ​

The WebSocket server implements efficient broadcasting. Clients are only sent update events for features they have explicitly "interacted" with (e.g., by sending a get_state command).

  • Auto-subscription: Sending a valid get_state command for a feature automatically subscribes the client to that feature's updates.
  • Broadcast Filtering: The server skips state transformation and transmission if no clients are subscribed to a specific feature.

Sending a Command ​

json
{
  "type": "command",
  "feature": "timer",
  "action": "start",
  "user": "OverlayTimer",
  "data": {
    "minutes": 5,
    "seconds": 0
  }
}
FieldRequiredDescription
typeYesAlways "command"
featureYesModule identifier
actionYesAction to execute
userNoTraces overlay origin in logs
dataNoAction parameters

All payloads are validated by Zod schemas (discriminated unions). An invalid payload immediately returns a VALIDATION_ERROR.

Success Response ​

json
{
  "type": "response",
  "feature": "timer",
  "action": "start",
  "ok": true,
  "source": "overlay",
  "origin": "OverlayTimer",
  "data": {
    "feature": "timer",
    "action": "start",
    "timestamp": "2026-03-10T21:00:00.000Z"
  },
  "timestamp": "2026-03-10T21:00:00.001Z"
}

Error Response ​

json
{
  "type": "response",
  "feature": "timer",
  "action": "start",
  "ok": false,
  "source": "overlay",
  "code": "VALIDATION_ERROR",
  "message": "Timer duration must be greater than zero",
  "timestamp": "2026-03-10T21:00:00.001Z"
}

Error codes:

CodeCause
VALIDATION_ERRORMalformed payload, unknown action, or invalid parameter
FEATURE_NOT_FOUNDModule not supported by the runtime
INTERNAL_ERRORHandler execution error (page not loaded, etc.)

Update Broadcast ​

Automatically sent to subscribed clients on state change:

json
{
  "type": "update",
  "feature": "timer",
  "data": {
    "running": true,
    "durationSeconds": 300,
    "remainingSeconds": 297,
    "endAtMs": 1760000000000
  },
  "timestamp": "2026-03-10T21:00:03.000Z"
}

Action Matrix ​

timer ​

ActionParameters
startdata.minutes (int), data.seconds (int)
stop-
reset-
get_state-
set_overlay_configdata.enabled (bool), data.position (OverlayPosition), data.theme (string)

khinsider_radio ​

ActionParameters
play / pause / next-
shuffledata.enabled (bool, optional)
volumedata.value (0–100)
get_state / activate / deactivate / diagnostic-

smtc ​

ActionParameters
start_monitoring / stop_monitoring / get_state-
play / pause / toggle_play / next / previous / prev-
set_overlay_configdata.enabled (bool), data.radioSource (auto | khinsider | smtc), data.position (OverlayPosition), data.showArtwork (bool), data.showProgress (bool), data.theme (RadioOverlayTheme)
select_sourcedata.radioSource (same values as above)

twitch ​

ActionParameters
connect / disconnect-
status / get_profile-
planning:sync- (synchronizes local schedule with Twitch)
planning:get_weeks- (returns 9-week calendar)
planning:createdata.startTime (RFC3339), data.durationMinutes (int), data.timezone (IANA), data.title (string), data.categoryId (string), data.categoryName (string), data.isRecurring (bool)
planning:updatedata.id (string), plus optional: data.twitchId, data.startTime, data.durationMinutes, data.title, data.categoryId, data.categoryName, data.isCancelled
planning:deletedata.id (string), data.twitchId (string, optional)
twitch:search_categoriesdata.query (string)
alerts:get_config-
alerts:update_configdata (Partial<TwitchAlertConfig>)
alerts:testdata.alertType (follow, subscribe, raid, cheer, gift_sub)
events:get_recent-
events:clear-

discord_rpc ​

ActionParameters
connect / disconnect / status-

system ​

ActionParameters
shutdown- (IPC only, not allowed via WS)

System actions are restricted to IPC for security reasons. WebSocket clients cannot trigger system-level operations.

OverlayPosition Values ​

The OverlayPosition type accepts one of 9 anchor points:

top-left       top-center       top-right
middle-left    center           middle-right
bottom-left    bottom-center    bottom-right

Overlay Configuration ​

The timer and smtc features support a set_overlay_config action (smtc drives the single music overlay, which covers KHInsider and the system player). This allows overlays and the dashboard to configure visibility, position, and theme without restarting the app. The configuration is persisted and broadcast to subscribed clients via the feature's update event.

State Contracts ​

SmtcState ​

typescript
{
  connected: boolean
  isPlaying: boolean
  title: string
  artist: string
  albumTitle?: string
  artworkUrl?: string
  progressMs: number
  durationMs: number
  radioSource: 'khinsider' | 'smtc'
  mediaApp: string          // app id detecte (AUMID Windows / bus MPRIS), '' si inconnu
  mediaAppLabel: string     // libelle humain, '' si inconnu
  lastUpdatedAt: number
  platform?: string  // 'win32' | 'linux' | 'darwin'
  overlayConfig: {
    enabled: boolean
    radioSource: 'auto' | 'khinsider' | 'smtc'
    position: OverlayPosition
    showArtwork: boolean
    showProgress: boolean
    theme: RadioOverlayTheme
  }
}

KhinsiderState ​

typescript
{
  active: boolean
  isPlaying: boolean
  isShuffleEnabled?: boolean
  volume: number
  title: string
  game: string
  coverUrl: string
  currentTimeSeconds?: number
  durationSeconds?: number
  history: { title: string, game: string, coverUrl: string }[]
}

TimerState ​

typescript
{
  running: boolean;
  durationSeconds: number;
  remainingSeconds: number;
  endAtMs: number | null;
  overlayConfig: {
    enabled: boolean;
    position: OverlayPosition;
    theme: "streamoos" | "minimal-dark";
  }
}

TwitchState ​

typescript
{
  active: boolean
  connected: boolean
  displayName: string
  avatarUrl: string
  broadcasterId?: string
  planningWeeks?: PlanningWeek[]  // 9-week schedule (see planning types)
  lastAlert?: TwitchAlertData
  alertConfig?: TwitchAlertConfig
  eventSubConnected?: boolean
  recentEvents?: RecentEventsMap
}

Released under the MIT License.