Skip to main content

2026-09-05

Uptime Kuma API: what exists, and what to use instead

  • uptime kuma
  • api
  • monitoring as code
  • open-source

TL;DR

Uptime Kuma will not let you create a monitor over HTTP. Its entire HTTP surface is status badges, public status page data, one push endpoint and a Prometheus scrape. The dashboard drives everything else over Socket.IO, a private interface the project never promised to keep stable. Every library billed as an Uptime Kuma API is a client for that interface.

You want fifty monitors created from a CSV. Or a check added in the same pull request that adds the service. Or a deploy script that pauses one monitor while it runs, then puts it back. So you go looking for the API docs and you cannot find them.

They do not exist. So this is the surface as it stands in version 2.5.3, read out of the source on 5 September 2026.

Every HTTP route Uptime Kuma serves

Two Express routers carry almost all of it, plus a few routes registered straight on the app. Everything not in this table serves the single-page app itself, including the status page HTML at /status/:slug, or else it is uploaded images, robots.txt, a change-password well-known link, and the first-run database setup page.

RouteWhat it doesAuth
/api/push/:pushTokenRecords a heartbeat for a push monitorThe token in the URL
/metricsPrometheus metrics for all monitorsHTTP Basic
/api/badge/:id/statusSVG status badgeNone
/api/badge/:id/uptime/:duration?SVG uptime badgeNone
/api/badge/:id/ping/:duration?SVG response time badgeNone
/api/badge/:id/avg-response/:duration?SVG average response badgeNone
/api/badge/:id/cert-expSVG certificate expiry badgeNone
/api/badge/:id/responseSVG last response badgeNone
/api/status-page/:slugPublic status page as JSONNone
/api/status-page/heartbeat/:slugHeartbeat history for that pageNone
/api/status-page/:slug/incident-historyPast incidents on that pageNone
/api/status-page/:slug/badgeSVG badge for a whole status pageNone
/api/status-page/:slug/manifest.jsonWeb app manifest for that pageNone
/status/:slug/rssRSS feed for that status pageNone
/api/entry-pageWhich page to show at the rootNone

Read the auth column again. One route writes anything, and what it writes is a single heartbeat. Nothing here creates a monitor, and nothing here will even list your monitors unless you already published them on a public status page.

The API key does less than the name suggests

Uptime Kuma has an API key feature, in Settings, with expiry dates and an enable toggle. It is easy to assume that is the missing REST credential.

The key works on exactly one route, the Prometheus scrape at /metrics. In the source, apiAuth is attached there and nowhere else, so the key cannot touch a monitor at all.

Two things to know before you build on it. If API keys are switched off, that same endpoint falls back to HTTP Basic with your admin username and password, so a scrape config carries either a key or the login to the whole instance. And the key path is rate limited to 60 requests a minute across the instance, with the login path at 20.

The real interface is Socket.IO

Everything the web UI does, it does by emitting Socket.IO events at the server. The monitor events are what you would want from a REST API, in the wrong shape:

add             editMonitor      deleteMonitor
pauseMonitor    resumeMonitor    getMonitorList
getMonitor      getMonitorBeats  getTags

Creating a monitor is an event literally named add.

To reach any of them you log in first, as the admin, over that same socket. The login event hands back a JWT you can reuse, and if the account has two-factor auth switched on, your script also has to produce a TOTP code from the shared secret. Then you emit add with a monitor object whose shape is written down nowhere, so you either copy what the browser sends or lean on somebody's wrapper that already did.

That matters for three reasons. The credential is the whole instance: there is no read-only token and no per-monitor scope, so a deploy script that pauses one monitor is holding the login that could delete all of them and change the admin password. The payload shape is not a contract, it is whatever the current UI happens to send, so a field can be renamed in a minor release and the project has broken nothing, because nothing outside the UI was meant to depend on it. And none of it is documented, so you learn it by reading server/server.js or by reading someone else's wrapper.

This is on purpose, and the project says so

It is worth being fair to Uptime Kuma here. This is not neglect. The README lists the project's motivations, and one of them is:

Try to use WebSocket with SPA instead of a REST API.

Uptime Kuma set out to be a single-page app with a live socket behind it, which is a good fit for a dashboard you keep open all day. A REST API was never the goal, so asking for one is asking for a different product.

The request is not being ignored either. Issue 118, "API functionality", has been open since July 2021 with 776 reactions and 77 comments, which makes it the most-reacted open issue in the repository. The maintainer went further than acknowledging it. In October 2023 he opened a pull request against that issue, number 3854, called "Document the Socket.io API and try to convert it to a HTTP request". It is still a draft, and both it and the issue were open when this was written.

The wrapper ecosystem, with dates

Every library called an Uptime Kuma API is a Socket.IO client wearing a nicer coat. Star counts and commit dates below come from the GitHub API on 5 September 2026, not from the project pages, because a repository can look alive off a dependabot branch while nobody has touched the code in two years.

ProjectStarsLast commitNotes
lucasheld/uptime-kuma-api (Python)3942023-09-26The canonical one. Compatibility table stops at Kuma 1.23.2
lucasheld/ansible-uptime-kuma1882023-09-26Ansible modules built on the above
MedAziz11/Uptime-Kuma-Web-API2792023-08-10A FastAPI bridge that gives you a REST facade over the socket
breml/go-uptime-kuma-client162026-08-30Go client
pablofmorales/kuma-cli142026-04-02Command line client
exaland/uptime-kuma-api-v2112026-08-23Fork of the Python wrapper for Kuma 2
pbarone/uptime-kuma-api2112026-08-15Another fork of the same wrapper for Kuma 2

So the client almost everyone links to predates Uptime Kuma 2 entirely, and the forks that do cover version 2 are tiny. Two of them are the same idea, started a year apart by different people, with eleven stars each. That is what happens when the protocol underneath is neither stable nor written down: people rebuild the same wrapper instead of maintaining one together.

What you can do today

If you are staying on Uptime Kuma, roughly in order of how much sleep it will cost you.

Push monitors are the one automation surface the project supports deliberately. Your job calls a token URL when it finishes, and the endpoint takes status=up or status=down plus optional msg and ping parameters. That covers cron and batch work without going near the socket. Same idea as heartbeat checks for cron jobs, and the reason behind why cron jobs fail silently.

To read state, scrape /metrics with an API key and query it there. That is the supported read path and it is stable. If the data is public anyway, /api/status-page/heartbeat/:slug returns real heartbeats with no credentials, limited to the monitors you chose to publish.

A socket wrapper is fine for work you are watching, like a one-off import of fifty monitors that you run once and check by hand. Pin the wrapper version, pin your Kuma version, and keep it out of any pipeline nobody is looking at.

Writing to the database directly is the one to avoid. People do it anyway. Kuma holds state in memory and writes heartbeats continuously, so a write behind its back is a corrupted instance waiting for the next restart.

If you need monitoring as code

This is the point where the tool and the job stop matching. If your monitors have to live in Git, get reviewed in a pull request, and be created by a service account that cannot also delete them, you are asking a dashboard-first tool to behave like an API-first one.

That gap is what we built Uptimepage around. Monitors are defined in a Terraform provider or created over a documented REST API with scoped tokens, so a CI job can add a check without holding the keys to the account. There is an MCP server too, if the thing creating monitors is an agent rather than a pipeline. The side by side comparison is the short version.

Kuma is still the right answer for plenty of homelabs and small teams, and our roundup of self-hosted uptime monitors says so. This is one specific edge, and it is the one most people hit second, right after the single shared login.

Common questions

Does Uptime Kuma have a REST API?

Uptime Kuma has no REST API for managing monitors. The HTTP routes it does expose are read-only badges, the public status page JSON, the push endpoint for heartbeat monitors, and a Prometheus metrics endpoint. Creating, editing, pausing and deleting monitors all happen over Socket.IO instead.

How do I create a monitor in Uptime Kuma from a script?

You open a Socket.IO connection, log in with the admin username and password, and emit the add event with a monitor object. There is no documented schema for that object, so in practice you copy what the web UI sends, or you use a community wrapper that already did.

What can an Uptime Kuma API key do?

An API key authenticates exactly one endpoint, the Prometheus metrics at /metrics. It cannot create, edit, pause or delete a monitor, and it is not a general access token for the rest of the app.

Is the Python uptime-kuma-api library still maintained?

The original Python wrapper has had no commit since September 2023, and its own compatibility table stops at Uptime Kuma 1.23.2. Version 2 is the current line, so the ecosystem has split into several small forks rather than one maintained package.

What is the safest way to automate Uptime Kuma today?

Push monitors are the one automation surface Uptime Kuma supports on purpose. Your job calls a token URL when it finishes, which covers cron and batch work without driving the private Socket.IO interface at all.

Manage monitors over a real API

Artem Senenko

Artem Senenko

Founder & Software Engineer, Uptimepage

Software engineer with 20+ years building and running production systems: microservice architecture on Kubernetes, cloud infrastructure on AWS and Terraform, and security-critical SaaS in the fintech domain.

← Back to all notes