Uptime Monitor¶
HTTP and TCP uptime checks with alerting.
All endpoints below are mounted under /api. Authentication: Authorization: Bearer <token> unless noted as public.
Endpoint count: 8
Endpoints¶
| Method | Path | Handler | Guards |
|---|---|---|---|
GET |
/api/uptime/monitors |
listUptimeMonitors |
RequireSuperuser() |
POST |
/api/uptime/monitors |
createUptimeMonitor |
RequireSuperuser() |
DELETE |
/api/uptime/monitors/:id |
deleteUptimeMonitor |
RequireSuperuser() |
PUT |
/api/uptime/monitors/:id |
updateUptimeMonitor |
RequireSuperuser() |
POST |
/api/uptime/monitors/:id/check |
manualUptimeCheck |
RequireSuperuser() |
GET |
/api/uptime/monitors/:id/history |
getUptimeHistory |
RequireSuperuser() |
POST |
/api/uptime/monitors/:id/toggle |
toggleUptimeMonitor |
RequireSuperuser() |
GET |
/api/uptime/status |
getUptimeStatus |
RequireSuperuser() |
Source¶
Handlers for this section live in api/routes/handlers_*.go in the StarkOne source. Each handler binds its request body with gin.ShouldBindJSON(&req) and responds with the standard envelope:
On error:
Note: the uptime handlers emit error bodies as
{ "error": { "message": "..." } }without acodefield. Thecodekey shown above is the panel-wide convention; it is not populated by these specific handlers.
Reference¶
GET /api/uptime/monitors¶
Lists all configured uptime monitors with their full configuration and last-check state, ordered by creation time (newest first).
Guards: RequireSuperuser()
Response - 200 OK
{
"data": {
"monitors": [
{
"id": 1,
"name": "Main site",
"type": "http",
"target": "https://example.com",
"http_method": "GET",
"http_override_ip": "",
"http_keyword": "",
"http_skip_ssl": false,
"check_interval": 300,
"timeout": 5,
"alert_email": "[email protected]",
"alert_webhook": "",
"webhook_skip_ssl": false,
"alert_ai": false,
"is_enabled": true,
"is_down": false,
"last_check": "2026-06-17 12:00:00",
"last_status": 200,
"last_response_time": 142,
"last_error": "",
"fail_count": 0,
"total_checks": 288,
"created_at": "2026-06-01 09:00:00",
"dns_failover": false,
"dns_zone": "",
"dns_record_name": "",
"dns_record_type": "A",
"dns_up_ip": "",
"dns_down_ip": ""
}
]
}
}
If the Uptime Monitor plugin is not installed (the uptime_monitors table does not exist), the handler returns 200 OK with an empty list: { "data": { "monitors": [] } }.
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
- | Database query failed ({ "error": { "message": "..." } }). |
Side effects
- Calls
ensureUptimeMonitorSchema(db), which may run schema/migration DDL on theuptime_monitorstable to add missing columns.
Example
POST /api/uptime/monitors¶
Creates a new uptime monitor from the request body, applying defaults for method, interval, timeout, and DNS record type.
Guards: RequireSuperuser()
Request body
{
"name": "string (required)",
"type": "string (required)",
"target": "string (required)",
"http_method": "string (optional, default GET)",
"http_override_ip": "string (optional)",
"http_keyword": "string (optional)",
"http_skip_ssl": "bool (optional)",
"check_interval": "int (optional, default 300)",
"timeout": "int (optional, default 5)",
"alert_email": "string (optional)",
"alert_webhook": "string (optional)",
"webhook_skip_ssl": "bool (optional)",
"alert_ai": "bool (optional)",
"dns_failover": "bool (optional)",
"dns_zone": "string (optional)",
"dns_record_name": "string (optional)",
"dns_record_type": "string (optional, default A)",
"dns_up_ip": "string (optional)",
"dns_down_ip": "string (optional)"
}
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | yes | Display name of the monitor. |
type |
string | yes | Monitor type (e.g. http, tcp); not validated against an enum in the handler. |
target |
string | yes | URL or host:port to check. |
http_method |
string | no | HTTP method for HTTP checks. Defaults to GET when empty. |
http_override_ip |
string | no | IP to connect to instead of resolving the target host. |
http_keyword |
string | no | Keyword that must be present in the response body. |
http_skip_ssl |
bool | no | Skip TLS certificate verification. |
check_interval |
int | no | Seconds between checks. Defaults to 300 when 0. |
timeout |
int | no | Per-check timeout in seconds. Defaults to 5 when 0. |
alert_email |
string | no | Email address for down/up alerts. |
alert_webhook |
string | no | Webhook URL for alerts. |
webhook_skip_ssl |
bool | no | Skip TLS verification when posting to the webhook. |
alert_ai |
bool | no | Send alerts to the AI agent. |
dns_failover |
bool | no | Enable DNS failover behavior. |
dns_zone |
string | no | DNS zone for failover. |
dns_record_name |
string | no | DNS record name for failover. |
dns_record_type |
string | no | DNS record type. Defaults to A when empty. |
dns_up_ip |
string | no | IP to set when the target is up. |
dns_down_ip |
string | no | IP to set when the target is down. |
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
- | Uptime Monitor plugin not installed, or request body failed binding (e.g. missing required field). |
500 |
- | Database insert failed. |
Side effects
- Inserts a row into the
uptime_monitorstable.
Example
curl -X POST https://panel.example.com:2087/api/uptime/monitors \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Main site", "type": "http", "target": "https://example.com"}'
DELETE /api/uptime/monitors/:id¶
Deletes a monitor and all of its history records.
Guards: RequireSuperuser()
Path parameters
| Name | Type | Description |
|---|---|---|
id |
int | ID of the monitor to delete. |
Response - 200 OK
Side effects
- Deletes rows from
uptime_monitor_history(matchingmonitor_id) and fromuptime_monitors. Errors from these statements are not surfaced; the handler always returns success.
Example
curl -X DELETE https://panel.example.com:2087/api/uptime/monitors/2 \
-H "Authorization: Bearer $TOKEN"
PUT /api/uptime/monitors/:id¶
Updates all configuration fields of an existing monitor and bumps its updated_at timestamp.
Guards: RequireSuperuser()
Path parameters
| Name | Type | Description |
|---|---|---|
id |
int | ID of the monitor to update. |
Request body
{
"name": "string (optional)",
"type": "string (optional)",
"target": "string (optional)",
"http_method": "string (optional)",
"http_override_ip": "string (optional)",
"http_keyword": "string (optional)",
"http_skip_ssl": "bool (optional)",
"check_interval": "int (optional)",
"timeout": "int (optional)",
"alert_email": "string (optional)",
"alert_webhook": "string (optional)",
"webhook_skip_ssl": "bool (optional)",
"alert_ai": "bool (optional)",
"dns_failover": "bool (optional)",
"dns_zone": "string (optional)",
"dns_record_name": "string (optional)",
"dns_record_type": "string (optional)",
"dns_up_ip": "string (optional)",
"dns_down_ip": "string (optional)"
}
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | no | Display name. |
type |
string | no | Monitor type. |
target |
string | no | URL or host:port to check. |
http_method |
string | no | HTTP method. No default is applied on update. |
http_override_ip |
string | no | IP to connect to instead of resolving the host. |
http_keyword |
string | no | Required response-body keyword. |
http_skip_ssl |
bool | no | Skip TLS certificate verification. |
check_interval |
int | no | Seconds between checks. No default is applied on update. |
timeout |
int | no | Per-check timeout in seconds. No default is applied on update. |
alert_email |
string | no | Alert email address. |
alert_webhook |
string | no | Alert webhook URL. |
webhook_skip_ssl |
bool | no | Skip TLS verification for the webhook. |
alert_ai |
bool | no | Send alerts to the AI agent. |
dns_failover |
bool | no | Enable DNS failover. |
dns_zone |
string | no | DNS zone for failover. |
dns_record_name |
string | no | DNS record name. |
dns_record_type |
string | no | DNS record type. No default is applied on update. |
dns_up_ip |
string | no | IP when up. |
dns_down_ip |
string | no | IP when down. |
All fields are sent to the
UPDATEstatement regardless of whether they were present in the request. Omitted fields default to their Go zero value and overwrite the stored value, so callers should send the complete configuration.
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
- | Request body failed binding. |
500 |
- | Database update failed. |
Side effects
- Updates the matching row in
uptime_monitorsand setsupdated_at = CURRENT_TIMESTAMP. A non-existentidproduces no error (zero rows affected) and still returns success.
Example
curl -X PUT https://panel.example.com:2087/api/uptime/monitors/2 \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Main site", "type": "http", "target": "https://example.com", "check_interval": 60, "timeout": 10}'
POST /api/uptime/monitors/:id/check¶
Triggers an immediate, asynchronous health check for a single monitor.
Guards: RequireSuperuser()
Path parameters
| Name | Type | Description |
|---|---|---|
id |
int | ID of the monitor to check. |
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
404 |
- | Monitor not found ({ "error": { "message": "Monitor not found" } }). |
Side effects
- Loads the monitor config from
uptime_monitors, then runsperformUptimeCheck(...)in a background goroutine. That check performs the HTTP/TCP probe and may update the monitor's status columns, write a history row, and dispatch email/webhook/AI alerts and DNS failover updates. The HTTP response returns immediately and does not reflect the check result.
Example
curl -X POST https://panel.example.com:2087/api/uptime/monitors/2/check \
-H "Authorization: Bearer $TOKEN"
GET /api/uptime/monitors/:id/history¶
Returns recent check-history events for a monitor, newest first.
Guards: RequireSuperuser()
Path parameters
| Name | Type | Description |
|---|---|---|
id |
int | ID of the monitor whose history is returned. |
Query parameters
| Name | Type | Optional | Description |
|---|---|---|---|
limit |
int | yes | Maximum number of history rows to return. Defaults to 100. |
Response - 200 OK
{
"data": {
"history": [
{
"id": 10,
"event_type": "down",
"status": 503,
"response_time": 0,
"error": "connection refused",
"created_at": "2026-06-17 11:55:00"
}
]
}
}
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
- | Database query failed. |
Example
curl -X GET "https://panel.example.com:2087/api/uptime/monitors/2/history?limit=50" \
-H "Authorization: Bearer $TOKEN"
POST /api/uptime/monitors/:id/toggle¶
Flips a monitor's enabled state (enabled to disabled, or vice versa).
Guards: RequireSuperuser()
Path parameters
| Name | Type | Description |
|---|---|---|
id |
int | ID of the monitor to toggle. |
Response - 200 OK
Side effects
- Runs
UPDATE uptime_monitors SET is_enabled = 1 - is_enabled, updated_at = CURRENT_TIMESTAMP WHERE id = ?. The exec error is not checked; a non-existentidstill returns success.
Example
curl -X POST https://panel.example.com:2087/api/uptime/monitors/2/toggle \
-H "Authorization: Bearer $TOKEN"
GET /api/uptime/status¶
Returns aggregate counts of enabled monitors by state (up, down, warning) plus install/running status.
Guards: RequireSuperuser()
Response - 200 OK
When the plugin is not installed, the handler returns { "data": { "installed": false } } only. Counts are over enabled monitors only: up = not down and empty last_error, down = is_down = 1, warning = not down but non-empty last_error. running reflects the in-process uptimeMonitorRunning flag.
Example