WebSocket API
The live-update channel that tells the dashboard when to refetch, not a granular event feed.
The KubeWatch Live Data service exposes a WebSocket endpoint that tells the dashboard when to refetch data in real time. It's intentionally lightweight: it doesn't stream full metrics payloads, just a signal that something changed and which agent or alert it relates to. This is what the dashboard itself uses internally, not a general-purpose integration API. If you need programmatic access to metrics or alerts, use the REST endpoints instead.
Connecting
wss://YOUR_KUBEWATCH_URL/ws
This endpoint authenticates the same way every other tenant-scoped request does: a Bearer JWT in the Authorization header, the auth_token session cookie, or an X-API-Key header. From within the dashboard, the browser sends the auth_token cookie automatically during the WebSocket handshake, the same cookie used for regular dashboard requests. A script or server can connect too, as long as its WebSocket client lets it set an Authorization or X-API-Key header on the handshake request (not every browser WebSocket API does, which is why the dashboard itself relies on the cookie instead).
JavaScript example (from within the dashboard's own origin):
const ws = new WebSocket("wss://YOUR_KUBEWATCH_URL/ws");
ws.addEventListener("open", () => {
console.log("Connected to KubeWatch live stream");
});
ws.addEventListener("message", (event) => {
const message = JSON.parse(event.data);
console.log(message.type, message.payload);
});
ws.addEventListener("close", (event) => {
console.log("Disconnected:", event.code, event.reason);
});
Message format
Every message is a JSON object with exactly two fields:
{
"type": "agent.data",
"payload": {}
}
The payload shape depends on type. There are four event types today.
Event types
agent.push
Emitted synchronously, the moment an agent's push request is handled. The payload includes rough counts, but not the metrics themselves.
{
"type": "agent.push",
"payload": {
"agentId": "agent_abc123",
"orgId": "org_xyz789",
"containers": 8,
"pods": 12
}
}
agent.data
Emitted from a separate ingestion pipeline once a pushed snapshot has been processed. The payload only identifies which agent or org changed. It doesn't carry the metrics themselves. Clients are expected to refetch (for example, by re-calling the relevant REST endpoint) on receiving either this or agent.push.
{
"type": "agent.data",
"payload": {
"agentId": "agent_abc123",
"orgId": "org_xyz789"
}
}
alert.fired
Emitted when an alert rule transitions to the firing state. Note the field casing below is exactly what the server sends (it is not camelCased).
{
"type": "alert.fired",
"payload": {
"ID": "alert_abc123",
"RuleID": "rule_xyz789",
"OrgID": "org_xyz789",
"AgentID": "agent_abc123",
"ResourceID": "container_xyz",
"ResourceType": "container",
"State": "firing",
"Value": 94.2
}
}
integration.metrics
Emitted after each scheduled refresh of an external integration (a monitored Kafka cluster, Postgres instance, and similar) that isn't collected by a KubeWatch agent. Unlike agent.push/agent.data, this one does carry the metrics themselves, since integration polling already runs on a slow interval rather than the agent's push cadence.
{
"type": "integration.metrics",
"payload": {
"integrationId": 42,
"orgId": "org_xyz789",
"metrics": {}
}
}
Reconnection
The server pings every 30 seconds. If a client doesn't respond, the connection gets dropped, so reconnect with backoff on close:
function connectWithBackoff() {
let attempt = 0;
const maxBackoff = 30000; // 30 seconds
function connect() {
const ws = new WebSocket("wss://YOUR_KUBEWATCH_URL/ws");
ws.addEventListener("open", () => {
attempt = 0;
console.log("Connected");
});
ws.addEventListener("close", () => {
const backoff = Math.min(1000 * Math.pow(2, attempt++), maxBackoff);
console.log(`Reconnecting in ${backoff}ms (attempt ${attempt})`);
setTimeout(connect, backoff);
});
return ws;
}
return connect();
}