Skip to content

Network and Protocol

AstorisTheBrave edited this page Jul 4, 2026 · 1 revision

Network and Protocol

Uptime Kuma's real-time API is an internal Socket.IO interface; its public REST surface covers status pages. URSA treats the socket API as unstable and isolates all of its quirks in one adapter, so the rest of the app only ever sees clean domain models. Every shape URSA relies on was captured from a live Kuma 2.4.0 instance.

Two channels

  • Socket.IO (authenticated): live monitor list and updates, heartbeats, average ping, uptime, certificate info, and pause/resume. One connection per active server.
  • REST (unauthenticated): public status pages, fetched with Ktor.

Authentication

Login is over Socket.IO (login with username/password and, if enabled, a TOTP code). The server returns a token, which URSA reuses on later connections (loginByToken). Only the token is stored, encrypted; the password is never persisted. On reconnect, the client silently re-authenticates with the stored token, so a dropped socket heals itself.

Wire quirks the adapter handles

  • Positional events. Some events arrive as positional multi-argument emits rather than objects, for example average ping, uptime (a numeric period in hours and a 0..1 fraction), and certificate info. These are read from the argument array directly.
  • camelCase vs snake_case. The live heartbeat event is camelCase (monitorID), while getMonitorBeats rows are snake_case (monitor_id, down_count). Both are modeled.
  • Double-encoded JSON. Some fields (such as tags and notification config) arrive as JSON encoded inside JSON and must be parsed twice.
  • Status codes. Heartbeat status: 0 down, 1 up, 2 pending, 3 maintenance.

Design

The parser is a pure function over JSON that produces domain models, kept free of Android and Socket.IO types so it is unit-testable on the JVM. If you touch a new endpoint or event, capture it from a live instance first, then extend the adapter and its tests. Never scatter protocol assumptions across the app.

See also Push Internals for the webhook payload Kuma sends to push endpoints.

Clone this wiki locally