diff --git a/README.md b/README.md
index 34e34020f..5c4521906 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
Uptime Kuma is an easy-to-use self-hosted monitoring tool.
-
+
[](https://github.com/sponsors/louislam)
@@ -23,17 +23,17 @@ It is a temporary live demo, all data will be deleted after 10 minutes. Sponsore
## ⭐ Features
-- Monitoring uptime for HTTP(s) / TCP / HTTP(s) Keyword / HTTP(s) Json Query / Ping / DNS Record / Push / Steam Game Server / Docker Containers
-- Fancy, Reactive, Fast UI/UX
-- Notifications via Telegram, Discord, Gotify, Slack, Pushover, Email (SMTP), and [90+ notification services, click here for the full list](https://github.com/louislam/uptime-kuma/tree/master/src/components/notifications)
-- 20-second intervals
-- [Multi Languages](https://github.com/louislam/uptime-kuma/tree/master/src/lang)
-- Multiple status pages
-- Map status pages to specific domains
-- Ping chart
-- Certificate info
-- Proxy support
-- 2FA support
+- Monitoring uptime for HTTP(s) / TCP / HTTP(s) Keyword / HTTP(s) Json Query / Ping / DNS Record / Push / Steam Game Server / Docker Containers
+- Fancy, Reactive, Fast UI/UX
+- Notifications via Telegram, Discord, Gotify, Slack, Pushover, Email (SMTP), and [90+ notification services, click here for the full list](https://github.com/louislam/uptime-kuma/tree/master/src/components/notifications)
+- 20-second intervals
+- [Multi Languages](https://github.com/louislam/uptime-kuma/tree/master/src/lang)
+- Multiple status pages
+- Map status pages to specific domains
+- Ping chart
+- Certificate info
+- Proxy support
+- 2FA support
## 🔧 How to Install
@@ -50,7 +50,7 @@ Uptime Kuma is now running on .
> [!NOTE]
> If you want to limit exposure to localhost (without exposing port for other users or to use a [reverse proxy](https://github.com/louislam/uptime-kuma/wiki/Reverse-Proxy)), you can expose the port like this:
->
+>
> ```bash
> docker run -d --restart=always -p 127.0.0.1:3001:3001 -v uptime-kuma:/app/data --name uptime-kuma louislam/uptime-kuma:1
> ```
@@ -59,15 +59,15 @@ Uptime Kuma is now running on .
Requirements:
-- Platform
- - ✅ Major Linux distros such as Debian, Ubuntu, CentOS, Fedora and ArchLinux etc.
- - ✅ Windows 10 (x64), Windows Server 2012 R2 (x64) or higher
- - ❌ FreeBSD / OpenBSD / NetBSD
- - ❌ Replit / Heroku
-- [Node.js](https://nodejs.org/en/download/) 18 / 20.4
-- [npm](https://docs.npmjs.com/cli/) 9
-- [Git](https://git-scm.com/downloads)
-- [pm2](https://pm2.keymetrics.io/) - For running Uptime Kuma in the background
+- Platform
+ - ✅ Major Linux distros such as Debian, Ubuntu, CentOS, Fedora and ArchLinux etc.
+ - ✅ Windows 10 (x64), Windows Server 2012 R2 (x64) or higher
+ - ❌ FreeBSD / OpenBSD / NetBSD
+ - ❌ Replit / Heroku
+- [Node.js](https://nodejs.org/en/download/) 18 / 20.4
+- [npm](https://docs.npmjs.com/cli/) 9
+- [Git](https://git-scm.com/downloads)
+- [pm2](https://pm2.keymetrics.io/) - For running Uptime Kuma in the background
```bash
git clone https://github.com/louislam/uptime-kuma.git
@@ -141,12 +141,12 @@ Telegram Notification Sample:
## Motivation
-- I was looking for a self-hosted monitoring tool like "Uptime Robot", but it is hard to find a suitable one. One of the closest ones is statping. Unfortunately, it is not stable and no longer maintained.
-- Wanted to build a fancy UI.
-- Learn Vue 3 and vite.js.
-- Show the power of Bootstrap 5.
-- Try to use WebSocket with SPA instead of a REST API.
-- Deploy my first Docker image to Docker Hub.
+- I was looking for a self-hosted monitoring tool like "Uptime Robot", but it is hard to find a suitable one. One of the closest ones is statping. Unfortunately, it is not stable and no longer maintained.
+- Wanted to build a fancy UI.
+- Learn Vue 3 and vite.js.
+- Show the power of Bootstrap 5.
+- Try to use WebSocket with SPA instead of a REST API.
+- Deploy my first Docker image to Docker Hub.
If you love this project, please consider giving it a ⭐.
@@ -156,8 +156,8 @@ If you love this project, please consider giving it a ⭐.
I recommend using Google, GitHub Issues, or Uptime Kuma's subreddit for finding answers to your question. If you cannot find the information you need, feel free to ask:
-- [GitHub Issues](https://github.com/louislam/uptime-kuma/issues)
-- [Subreddit (r/UptimeKuma)](https://www.reddit.com/r/UptimeKuma/)
+- [GitHub Issues](https://github.com/louislam/uptime-kuma/issues)
+- [Subreddit (r/UptimeKuma)](https://www.reddit.com/r/UptimeKuma/)
My Reddit account: [u/louislamlam](https://reddit.com/u/louislamlam)
You can mention me if you ask a question on the subreddit.
@@ -193,4 +193,6 @@ If you want to translate Uptime Kuma into your language, please visit [Weblate R
Feel free to correct the grammar in the documentation or code.
My mother language is not English and my grammar is not that great.
+### API Documentation
+For developers integrating with Uptime Kuma, detailed API documentation is available in [docs/API_Detailed.md](docs/API_Detailed.md).
diff --git a/docs/API_Detailed.md b/docs/API_Detailed.md
new file mode 100644
index 000000000..dd96b6dbd
--- /dev/null
+++ b/docs/API_Detailed.md
@@ -0,0 +1,448 @@
+# Uptime Kuma API Documentation (Detailed)
+
+Uptime Kuma primarily uses **WebSockets** for real-time communication after authentication. It also provides **RESTful API endpoints** for push monitors, status badges, Prometheus metrics, and public status page data.
+
+## Authentication
+
+### REST API
+
+- **Push Monitors (`/api/push/:pushToken`)**: Authenticated via the unique `:pushToken` in the URL path. No other authentication needed for this endpoint.
+- **Metrics (`/metrics`)**: Authentication depends on server settings (`Settings` -> `Security` -> `API Keys`):
+ - **API Key Authentication (If Enabled):**
+ - Method: HTTP Basic Auth.
+ - Username: (empty string or any value, it's ignored).
+ - Password: Your generated API Key (e.g., `uk2_somereallylongkey`).
+ - **Basic User Authentication (If API Keys Disabled or Not Provided):**
+ - Method: HTTP Basic Auth.
+ - Username: Your Uptime Kuma username.
+ - Password: Your Uptime Kuma password.
+ - **No Authentication (If Auth Disabled in Settings):**
+ - No credentials required. Access is open.
+- **Badges & Public Status Pages**: These endpoints are generally public. Access to monitor-specific badges depends on the monitor being included in a _public_ group on any status page. Status page data endpoints (`/api/status-page/...`) require the status page itself to be _published_.
+
+### WebSocket API
+
+1. Establish a WebSocket connection.
+2. **Authentication:** The client must authenticate _after_ connection using one of these events:
+ - `login` Event: Provide username, password, and optionally a 2FA token.
+ - `loginByToken` Event: Provide a JWT token obtained from a previous successful login where "Remember Me" was selected.
+3. **Authorization:** Once authenticated via `login` or `loginByToken`, all subsequent events sent on that specific socket connection are authorized for the logged-in user.
+
+## Common Data Structures
+
+_(Used in WebSocket events and some API responses)_
+
+- **Monitor Object (Partial Example):**
+ ```json
+ {
+ "id": 1,
+ "name": "My Website",
+ "type": "http",
+ "url": "https://example.com",
+ "method": "GET",
+ "interval": 60,
+ "retryInterval": 60,
+ "resendInterval": 0,
+ "maxretries": 0,
+ "hostname": null,
+ "port": null,
+ "active": true,
+ "tags": [
+ {
+ "tag_id": 1,
+ "monitor_id": 1,
+ "value": null,
+ "name": "production",
+ "color": "#059669"
+ }
+ ],
+ "notificationIDList": { "1": true },
+ // ... other monitor-type specific fields
+ "accepted_statuscodes_json": "[\"200-299\"]",
+ "conditions": "[]" // JSON string of condition groups
+ }
+ ```
+- **Heartbeat Object:**
+ ```json
+ {
+ "monitorID": 1,
+ "status": 1, // 0=DOWN, 1=UP, 2=PENDING, 3=MAINTENANCE
+ "time": "2023-10-27T10:30:00.123Z", // ISO 8601 UTC Timestamp
+ "msg": "OK",
+ "ping": 123, // Response time in ms, null if not applicable
+ "important": true, // Was this heartbeat a status change?
+ "duration": 60, // Seconds since the last heartbeat for this monitor
+ "localDateTime": "2023-10-27 12:30:00", // Formatted time in server's timezone
+ "timezone": "Europe/Berlin", // Server's timezone name
+ "retries": 0, // Number of retries attempted for this state
+ "downCount": 0 // Consecutive down count for resend logic
+ }
+ ```
+- **Notification Object (Partial Example):**
+ ```json
+ {
+ "id": 1,
+ "name": "My Telegram Bot",
+ "active": true,
+ "isDefault": false,
+ "userID": 1,
+ "config": "{\"type\":\"telegram\",\"telegramBotToken\":\"...\",\"telegramChatID\":\"...\",\"name\":\"My Telegram Bot\",\"isDefault\":false,\"applyExisting\":false}" // JSON string
+ }
+ ```
+
+## REST API Endpoints
+
+---
+
+### Push Endpoint
+
+Receive updates for "Push" type monitors.
+
+- **Endpoint:** `/api/push/`
+- **Method:** `GET` | `POST` | `PUT` | `PATCH` (Method is generally ignored)
+- **Authentication:** Push Token (`` in the path)
+- **Path Parameters:**
+ - `pushToken` (string, required): The unique token associated with the push monitor.
+- **Query Parameters:**
+ - `status` (string, optional): Status of the service. `"up"` or `"down"`. Defaults to `"up"`.
+ - `msg` (string, optional): A message describing the status. Defaults to `"OK"`. Max length approx. 250 chars.
+ - `ping` (number, optional): Response time in milliseconds. Parsed as float. Defaults to `null`.
+- **Success Response (200 OK):**
+ ```json
+ {
+ "ok": true
+ }
+ ```
+- **Error Response (404 Not Found):**
+ ```json
+ {
+ "ok": false,
+ "msg": "Monitor not found or not active."
+ }
+ ```
+
+---
+
+### Badge Endpoints
+
+Provide status badges for monitors associated with a _public_ status page group.
+
+- **Status Badge:**
+
+ - **Endpoint:** `/api/badge//status`
+ - **Response:** SVG image.
+ - _(See previous documentation for query parameters)_
+
+- **Uptime Badge:**
+
+ - **Endpoint:** `/api/badge//uptime[/]` (e.g., `/uptime/24h`, `/uptime/7d`)
+ - **Response:** SVG image.
+ - _(See previous documentation for query parameters)_
+
+- **Ping/Response Time Badge:**
+
+ - **Endpoint:** `/api/badge//ping[/]` (e.g., `/ping/24h`, `/ping/7d`)
+ - **Response:** SVG image.
+ - _(See previous documentation for query parameters)_
+ - _Note: `/avg-response` and `/response` variants also exist._
+
+- **Certificate Expiry Badge:**
+ - **Endpoint:** `/api/badge//cert-exp`
+ - **Response:** SVG image.
+ - _(See previous documentation for query parameters)_
+
+---
+
+### Status Page Endpoints
+
+Provide data for _published_ public status pages.
+
+- **Get Status Page Data:**
+
+ - **Endpoint:** `/api/status-page/`
+ - **Method:** `GET`
+ - **Authentication:** None (Requires Status Page to be published)
+ - **Path Parameters:**
+ - `slug` (string, required): The unique slug of the status page.
+ - **Success Response (200 OK):**
+ ```json
+ {
+ "config": { // StatusPage config object
+ "slug": "my-status",
+ "title": "My Service Status",
+ "description": "Current status of our services.",
+ "icon": "/icon.svg",
+ "theme": "light",
+ "published": true,
+ "showTags": false,
+ // ... other config fields
+ },
+ "incident": null | { // Pinned incident object or null
+ "id": 1,
+ "title": "Investigating Network Issues",
+ "content": "We are currently investigating network latency.",
+ "style": "warning",
+ "createdDate": "2023-10-27T10:00:00.000Z",
+ "lastUpdatedDate": "2023-10-27T10:15:00.000Z",
+ "pin": true
+ },
+ "publicGroupList": [ // Array of public monitor groups
+ {
+ "id": 1,
+ "name": "Core Services",
+ "weight": 0,
+ "monitorList": [ // Array of Monitor objects within the group
+ {
+ "id": 1,
+ "name": "Website",
+ "type": "http",
+ // ... other *public* monitor fields
+ },
+ // ... more monitors
+ ]
+ },
+ // ... more groups
+ ],
+ "maintenanceList": [ // Array of active/scheduled Maintenance objects relevant to this page
+ {
+ "id": 1,
+ "title": "Scheduled Server Upgrade",
+ "description": "Upgrading server hardware.",
+ "strategy": "single", // or "recurring-...", "manual", "cron"
+ "active": true,
+ "status": "scheduled", // "scheduled", "under-maintenance", "ended", "inactive"
+ "timeslotList": [
+ {
+ "startDate": "2023-11-01T02:00:00.000Z",
+ "endDate": "2023-11-01T04:00:00.000Z"
+ }
+ // ... more timeslots possible for recurring
+ ],
+ // ... other fields like timezone, weekdays etc.
+ }
+ ]
+ }
+ ```
+ - **Error Response (404 Not Found):** If slug doesn't exist or status page is not published.
+
+- **Get Status Page Heartbeats & Uptime:**
+
+ - **Endpoint:** `/api/status-page/heartbeat/`
+ - **Method:** `GET`
+ - **Authentication:** None (Requires Status Page to be published)
+ - **Path Parameters:**
+ - `slug` (string, required): The status page slug.
+ - **Success Response (200 OK):**
+ ```json
+ {
+ "heartbeatList": {
+ "1": [
+ // Monitor ID 1
+ { "status": 1, "time": "...", "msg": "OK", "ping": 55 }
+ // ... more heartbeats (up to 100 recent)
+ ],
+ "2": [
+ // Monitor ID 2
+ {
+ "status": 0,
+ "time": "...",
+ "msg": "Timeout",
+ "ping": null
+ }
+ // ...
+ ]
+ },
+ "uptimeList": {
+ "1_24": 0.9998, // Monitor ID 1, 24h uptime percentage
+ "2_24": 0.95 // Monitor ID 2, 24h uptime percentage
+ // ... potentially other periods if requested differently in future
+ }
+ }
+ ```
+ - **Error Response (404 Not Found):** If slug doesn't exist or status page is not published.
+
+- **Get Status Page Manifest:**
+
+ - **Endpoint:** `/api/status-page//manifest.json`
+ - **Method:** `GET`
+ - **Response:** Standard Web App Manifest JSON.
+ - _(See previous documentation for structure)_
+
+- **Get Overall Status Page Badge:**
+ - **Endpoint:** `/api/status-page//badge`
+ - **Method:** `GET`
+ - **Response:** SVG image.
+ - _(See previous documentation for query parameters and logic)_
+
+---
+
+### Metrics Endpoint
+
+Exposes internal metrics for Prometheus scraping.
+
+- **Endpoint:** `/metrics`
+- **Method:** `GET`
+- **Authentication:** API Key or Basic Auth (See Authentication section)
+- **Response:** Plain text in Prometheus exposition format. Includes gauges like:
+ - `monitor_status{monitor_name="...", monitor_type="...", ...}` (Value: 0, 1, 2, 3)
+ - `monitor_response_time{...}` (Value: milliseconds)
+ - `monitor_cert_days_remaining{...}` (Value: days)
+ - `monitor_cert_is_valid{...}` (Value: 0 or 1)
+
+---
+
+### Entry Page Endpoint
+
+Used by the frontend to determine the initial landing page.
+
+- **Endpoint:** `/api/entry-page`
+- **Method:** `GET`
+- **Authentication:** None
+- **Success Response (200 OK):**
+ - If domain matches a status page:
+ ```json
+ { "type": "statusPageMatchedDomain", "statusPageSlug": "" }
+ ```
+ - If standard entry:
+ ```json
+ { "type": "entryPage", "entryPage": "dashboard" | "statusPage-" }
+ ```
+
+## WebSocket API
+
+Real-time interaction occurs over WebSockets after successful authentication.
+
+### General Flow
+
+1. Client connects.
+2. Server may send `loginRequired`.
+3. Client sends `login` or `loginByToken`.
+4. Server responds via callback.
+5. If login OK, server sends initial data (`monitorList`, `heartbeatList`, etc.).
+6. Client sends commands (e.g., `addMonitor`, `pauseMonitor`), server responds via callback.
+7. Server pushes real-time updates (`heartbeat`, `avgPing`, `uptime`, list updates).
+
+### Client-Sent Events (Selected Detail)
+
+_(Format: `eventName`(data, callback(res)) )_
+
+- **Authentication:**
+
+ - `login`
+ - **Data:** `{ username: "", password: "", token?: "" }` (2FA token if needed)
+ - **Callback:** `res: { ok: , msg?: "", msgi18n?: , token?: "", tokenRequired?: }`
+ - _Description:_ Attempts to log in. Returns `tokenRequired: true` if 2FA is enabled and token wasn't provided. Returns JWT `token` on success.
+ - `loginByToken`
+ - **Data:** `jwtToken: ""`
+ - **Callback:** `res: { ok: , msg?: "", msgi18n?: }`
+ - _Description:_ Logs in using a previously obtained JWT.
+ - `logout`
+ - **Callback:** (Optional) `res: {}`
+ - _Description:_ Logs the current user out.
+
+- **Monitor Management:**
+
+ - `add`
+ - **Data:** `monitor: ` (without `id`)
+ - **Callback:** `res: { ok: , msg?: "", msgi18n?: , monitorID?: }`
+ - _Description:_ Adds a new monitor configuration.
+ - `editMonitor`
+ - **Data:** `monitor: ` (with `id`)
+ - **Callback:** `res: { ok: , msg?: "", msgi18n?: , monitorID?: }`
+ - _Description:_ Updates an existing monitor configuration.
+ - `deleteMonitor`
+ - **Data:** `monitorID: `
+ - **Callback:** `res: { ok: , msg?: "", msgi18n?: }`
+ - `pauseMonitor` / `resumeMonitor`
+ - **Data:** `monitorID: `
+ - **Callback:** `res: { ok: , msg?: "", msgi18n?: }`
+ - `getMonitor`
+ - **Data:** `monitorID: `
+ - **Callback:** `res: { ok: , monitor?: , msg?: "" }`
+ - `getMonitorBeats`
+ - **Data:** `monitorID: `, `period: ` (in hours)
+ - **Callback:** `res: { ok: , data?: [], msg?: "" }`
+ - `getMonitorChartData`
+ - **Data:** `monitorID: `, `period: ` (in hours)
+ - **Callback:** `res: { ok: , data?: [], msg?: "" }`
+ - _Note:_ `` has fields like `timestamp`, `up`, `down`, `ping`, `pingMin`, `pingMax`.
+
+- **Notification Management:**
+
+ - `addNotification`
+ - **Data:** `notification: ` (Config is stringified JSON), `notificationID: | null` (null for add, ID for edit)
+ - **Callback:** `res: { ok: , msg?: "", msgi18n?: , id?: }`
+ - `deleteNotification`
+ - **Data:** `notificationID: `
+ - **Callback:** `res: { ok: , msg?: "", msgi18n?: }`
+ - `testNotification`
+ - **Data:** `notification: ` (Config is stringified JSON)
+ - **Callback:** `res: { ok: , msg?: "" }`
+
+- **Settings:**
+
+ - `getSettings`
+ - **Callback:** `res: { ok: , data?: