Skip to content

WebSocket

The WebSocket hub at /ws streams real-time events to browsers and backend integrations. Browser clients authenticate with the om_session HttpOnly session cookie set by /api/auth/login, so the JWT is not placed in the WebSocket URL. The legacy /ws?token=<jwt> form remains available for non-browser or older clients that cannot send the session cookie.

Message envelope

Every message is a JSON object with a type discriminator. Additional fields are flat on the root — there is no payload wrapper:

{
  "type": "workload_update",
  "workload": { /* models.Workload */ },
  "connected_instance_count": 3,
  "drifted_instance_count": 0
}

Event types

Type When it fires Other fields
workload_update A workload is registered or its state changes (status, labels, version, active config, live instance count). workload — full models.Workload; connected_instance_count; drifted_instance_count.
workload_event A single append-only pod-lifecycle event is recorded (connect / disconnect / version change). event — full models.WorkloadEvent.
workload_config_status A workload reports a RemoteConfigStatus for a pushed config (aggregated across its instances). workload_id, status{ status, config_hash, error_message, updated_at }.
alert_update An alert transitions (fired, acknowledged, resolved). alert — full models.Alert.
auto_rollback_applied The server auto-pushed the last-known-good config after a failure. workload_id, from_hash, to_hash, reason.

For authoritative payload shapes, consult internal/api/wshub.go (or the matching file in the current revision).

Reconnect behavior

The browser client reconnects with exponential backoff capped at a few seconds. Integrations should do the same and treat any missed events as eventually reconciled by a fresh GET /api/workloads call.