Self-hosted REST API wrapper for Uptime Kuma

Uptime Kuma couldn't be managed with a REST API call.
Now it can.

Kuma RestAPI Wrapper is a wrapper for Uptime Kuma's Socket.IO API. It allows you to control Uptime Kuma via authenticated REST API calls.

Uptime Kuma's REST API endpoints are limited and do not include monitor/tag/notifications/maintenance management. Those functions only exists over the Socket.IO API which doesn't accept API keys. This wrapper provides REST access to Socket.IO endpoints with API key authentication.

The problem

Uptime Kuma has two APIs, and only one of them can manage monitors.

The REST API in Uptime Kuma only can manage badge images, /metrics, and status page data. The Socket.IO API is the only interface that can add, edit, delete, pause, or resume a monitor, and it doesn't accept REST API calls or use API Keys.

That's the gap this wrapper fills.

01

One login

At startup, the wrapper opens a single persistent Socket.IO connection to your Uptime Kuma instance, signed in with the real username and password. It reconnects and re-authenticates automatically if the connection drops.

02

REST on top

That session backs a conventional REST API. The real admin username and password is never exposed, all REST API calls use Uptime Kuma API keys.

03

Every request re-checked

Each call to the wrapper must present a valid Uptime Kuma API key as the password in a HTTP Basic Auth header. It's validated against Uptime Kuma and cached. If you revoke a key in Uptime Kuma it stops working in the wrapper as soon as the cache expires.

What it does

Everything the Socket.IO API can do, as plain REST calls.

Full monitor lifecycle

Create, read, update, pause, resume, and delete monitors. Doesn’t matter if it’s a HTTP, TCP/port, or any of the other types Uptime Kuma supports.

API-key authentication

Every request is authenticated with a real Uptime Kuma API key over HTTP Basic Auth. Revoke it in Kuma and access is gone here too.

Partial edits, not full overwrites

You can /PUT a monitor with only the fields you're changing and it merges your patch over the monitor's existing configuration.

Beats and history

Read a monitor's recent heartbeats without having to open a Socket.IO connection.

Tags, notifications, proxies & more

Manage tag definitions, notification providers, outbound proxies, Docker hosts, maintenance windows, and status pages as well as monitors.

Interactive API docs

Swagger UI included at /api-docs, backed by a real OpenAPI 3.0 spec at /openapi.json, so you can authorize and try requests from the browser.

2FA-aware startup

If the wrapper's own account has 2FA enabled, hand it a TOTP secret and it computes codes itself for unattended startup.

Container-ready

A non-root, multi-stage Alpine image with a built-in HEALTHCHECK, plus a docker-compose file.

Reference

API endpoints

Every route below needs HTTP Basic Auth. The password is your Uptime Kuma API key.

curl -u api:your_api_key http://uptime-kuma:3100/monitors

Monitors

GET/monitorsList all monitors.
GET/monitors/:idGet one monitor by ID.
POST/monitorsCreate a monitor. Type-specific defaults are filled in.
PUT/monitors/:idPartially update a monitor by sending only the fields to change.
DELETE/monitors/:idDelete a monitor.
POST/monitors/:id/pausePause a monitor.
POST/monitors/:id/resumeResume a monitor.
GET/monitors/:id/beatsRead a monitor's recent heartbeat history.

Also managed as full REST resources

/tagsDefine tags and assign them to monitors.
/notificationsManage notification providers.
/proxiesManage outbound proxies used by monitors.
/docker-hostsManage hosts used by Docker-container monitors.
/maintenanceManage maintenance windows.
/status-pagesManage public status pages.

Full parameters and request/response shapes for these are documented in the Swagger UI.

System

GET/healthzA public unauthenticated health check which is also used by Docker’s HEALTHCHECK.
GET/api-docsInteractive Swagger UI.
GET/openapi.jsonThe raw OpenAPI 3.0 specification.
Under the hood

Technical info

Stack

  • Node.js≥ 18 (image uses 20-alpine)
  • Express 4REST server and routing
  • socket.io-clientPersistent connection to Uptime Kuma
  • express-basic-authHTTP Basic Auth on every route
  • swagger-ui-expressServes the interactive /api-docs UI
  • dotenvLoads configuration from .env

Container image

  • Runs as a non-root user on node:20-alpine.
  • Built-in HEALTHCHECK polling /healthz every 30s.
  • A docker-compose.yml example is included.

Configuration

KUMA_URLBase URL of your running Uptime Kuma instance.
KUMA_USERNAME / KUMA_PASSWORDA real Uptime Kuma account the wrapper logs in as internally.
KUMA_TOTP_SECRETOptional — base32 2FA secret, if that account has 2FA enabled.
PORTThe wrapper's own REST server port. Defaults to 3100.
APIKEY_CACHE_TTLSeconds a validated API key is cached before re-checking. Validates every request.
Get running

Installation

  1. Create a .env file with your Uptime Kuma connection details:

    KUMA_URL=http://uptime-kuma:3001
     KUMA_USERNAME=admin
     KUMA_PASSWORD=change_me
  2. Build and start the stack:

    docker compose up -d --build
  3. Or run the image directly, without compose:

    docker build -t kuma-rest-wrapper .
    
    docker run -d --name kuma-rest-wrapper -p 3100:3100 \
      -e KUMA_URL=http://host.docker.internal:3001 \
      -e KUMA_USERNAME=admin \
      -e KUMA_PASSWORD=change_me \
      kuma-rest-wrapper

KUMA_URL needs to resolve from inside the container — use host.docker.internal if Uptime Kuma runs on the host, or its service name if it runs in the same Docker network.

Transparency

About the AI use here

I understand the reservations surrounding AI-generated software. Relying on a tool to write code without fully understanding either the tool or the output is risky and many wish to avoid it. However, developer assistance tools like autocomplete or online reference platforms have been standard practice for years before AI came on the scene.

Both the wrapper and this website were developed with the help of AI coding assistants. Depending on the task, this assistance ranged from simple word completion to refactoring functions for modern best practices. Crucially, every line of code was individually reviewed, vetted, and thoroughly tested by me.

Finally, AI involvement is strictly confined to the build process: the wrapper itself contains no embedded AI features or runtime models.