# How the Uptime Kuma API Router Handles WebSocket Real-Time Updates

> Discover how the Uptime Kuma API router leverages Socket.IO for real-time WebSocket updates, efficiently synchronizing live UI with state persistence.

- Repository: [Louis Lam/uptime-kuma](https://github.com/louislam/uptime-kuma)
- Tags: internals
- Published: 2026-02-28

---

**The Uptime Kuma API router pushes real-time updates to connected browsers by emitting Socket.IO events to user-specific rooms after processing HTTP requests, decoupling state persistence from live UI synchronization.**

Uptime Kuma leverages **Socket.IO** to bridge its HTTP API and live dashboard updates. The **Uptime Kuma API router WebSocket real-time updates** mechanism allows the [`server/routers/api-router.js`](https://github.com/louislam/uptime-kuma/blob/main/server/routers/api-router.js) file to notify frontend clients immediately when monitor states change, creating a seamless monitoring experience where the Vue dashboard refreshes instantly without page reloads.

## Socket.IO Architecture and User Isolation

### Server Initialization

In [`server/uptime-kuma-server.js`](https://github.com/louislam/uptime-kuma/blob/main/server/uptime-kuma-server.js), the Socket.IO server initializes by attaching to the HTTP server instance. Lines 42-56 create the `Server` instance and configure the connection manager that handles all real-time communications. This centralizes WebSocket management within the `UptimeKumaServer` class, making the `io` object available throughout the application for emitting events.

### User-Scoped Rooms

The system implements strict user isolation through Socket.IO rooms. When a client authenticates, the server assigns `socket.userID` to the connection. This enables targeted emissions using `io.to(userID)`, ensuring that monitor updates reach only the browser sessions belonging to the specific user who owns those monitors. This room-based architecture prevents cross-contamination of data between different user accounts.

## End-to-End Update Flow

### HTTP Endpoint Processing

When a monitoring service calls the push API, the request enters through `POST /api/push/:pushToken` defined in [`server/routers/api-router.js`](https://github.com/louislam/uptime-kuma/blob/main/server/routers/api-router.js) (lines 27-34). The router validates the push token, identifies the associated monitor, and creates a heartbeat bean containing the status, message, and ping time. This HTTP endpoint acts as the entry point for external state changes.

### Real-Time Emission

After persisting the heartbeat data, lines 127-128 of [`server/routers/api-router.js`](https://github.com/louislam/uptime-kuma/blob/main/server/routers/api-router.js) trigger the WebSocket broadcast:

```javascript
io.to(monitor.user_id).emit("heartbeat", bean.toJSON());

```

This single line bridges the HTTP request/response cycle with the persistent Socket.IO connection, pushing the new state to all connected browsers for that user instantly.

### Frontend Subscription

The Vue mixin located in [`src/mixins/socket.js`](https://github.com/louislam/uptime-kuma/blob/main/src/mixins/socket.js) (lines 120-130) establishes the client-side Socket.IO connection and registers event listeners. When the server emits a `heartbeat` event, the frontend handler updates the dashboard table row immediately. The same pattern applies to `monitorList`, `updateMonitorIntoList`, and `maintenanceList` events, keeping all UI components synchronized with the server state.

## Implementation Across the Stack

### API Router Emissions

The [`server/routers/api-router.js`](https://github.com/louislam/uptime-kuma/blob/main/server/routers/api-router.js) file serves dual purposes: handling REST endpoints and triggering real-time notifications. After processing any state-modifying request—whether from the push API or internal status changes—it emits the appropriate Socket.IO events to refresh connected clients.

### Monitor Model Integration

Scheduled health checks in [`server/model/monitor.js`](https://github.com/louislam/uptime-kuma/blob/main/server/model/monitor.js) (lines 92-95) use identical emission logic:

```javascript
io.to(this.user_id).emit("heartbeat", bean.toJSON());

```

This ensures consistency between updates triggered by external push APIs and those generated by the internal monitoring scheduler, providing a unified real-time experience regardless of the update source.

## Practical Integration Examples

### Pushing Heartbeats via HTTP

Simulate a monitored service calling the push API to trigger a real-time update:

```bash

# Replace <TOKEN> with your monitor's push token

curl -X POST "http://localhost:3001/api/push/<TOKEN>?msg=OK&status=up&ping=42"

```

After execution, the server validates the token, stores the heartbeat, and emits the update to your browser instantly.

### Browser Client Implementation

Listen for real-time updates from a custom web application:

```html
<script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
<script>
  const socket = io();
  
  // Receive heartbeat updates instantly
  socket.on('heartbeat', (hb) => {
    console.log('New heartbeat received:', hb);
    // Update DOM elements with hb.status, hb.ping, hb.time
  });
  
  // Receive full monitor list on connection
  socket.on('monitorList', (list) => {
    console.log('Current monitors:', list);
  });
</script>

```

### Programmatic Server-Side Triggering

Trigger updates from a Node.js script:

```javascript
await fetch('http://localhost:3001/api/push/abcd1234?msg=Manual&status=up&ping=10')
  .then(r => r.json())
  .then(console.log);

```

Any connected Uptime Kuma dashboard will immediately reflect the new status through the WebSocket connection.

## Summary

- **Socket.IO Integration**: The [`server/uptime-kuma-server.js`](https://github.com/louislam/uptime-kuma/blob/main/server/uptime-kuma-server.js) file creates the Socket.IO server and manages user-specific room assignments via `socket.userID`.
- **Dual-Path Updates**: Both the API router ([`server/routers/api-router.js`](https://github.com/louislam/uptime-kuma/blob/main/server/routers/api-router.js)) and the monitor model ([`server/model/monitor.js`](https://github.com/louislam/uptime-kuma/blob/main/server/model/monitor.js)) emit `heartbeat` events using `io.to(user_id)` to ensure real-time synchronization.
- **User Isolation**: Room-based emissions guarantee that monitor data reaches only authenticated sessions belonging to the correct user.
- **Frontend Reactivity**: The [`src/mixins/socket.js`](https://github.com/louislam/uptime-kuma/blob/main/src/mixins/socket.js) Vue mixin handles connection management and event routing, enabling instantaneous UI updates without polling.

## Frequently Asked Questions

### How does Uptime Kuma ensure WebSocket updates reach only the correct user?

Uptime Kuma implements user-scoped rooms in Socket.IO. When a client authenticates, the server assigns `socket.userID` to the connection. Both the API router and monitor model emit events using `io.to(monitor.user_id)`, which restricts delivery to sockets belonging to that specific user only, preventing data leakage between accounts.

### What event names does the Uptime Kuma API router emit?

The primary events include `heartbeat` (for status changes), `monitorList` (full monitor synchronization), `updateMonitorIntoList` (partial updates), and `maintenanceList` (maintenance window changes). These stable event names allow the frontend mixin in [`src/mixins/socket.js`](https://github.com/louislam/uptime-kuma/blob/main/src/mixins/socket.js) to register predictable listeners that handle specific data types.

### Can external scripts trigger real-time updates in Uptime Kuma?

Yes. Any HTTP request to `POST /api/push/:pushToken` processed by [`server/routers/api-router.js`](https://github.com/louislam/uptime-kuma/blob/main/server/routers/api-router.js) will trigger the same Socket.IO emission chain as internal monitors. After the router validates the token and stores the heartbeat, it immediately emits to the user's room, causing instant dashboard updates for connected browsers.

### How does the frontend handle reconnection and missed events?

The Vue mixin in [`src/mixins/socket.js`](https://github.com/louislam/uptime-kuma/blob/main/src/mixins/socket.js) manages connection state and automatically re-registers event listeners upon reconnection. When the socket reconnects, the server typically emits a full `monitorList` event to resynchronize the client state, ensuring the dashboard remains consistent even after temporary disconnections.