Uptime Monitor API (1.0.0)

Download OpenAPI specification:

REST API for the self-hosted Uptime Monitor application.

Authentication

Most admin endpoints require a Bearer token in the Authorization header. Two token types are accepted:

  • Session tokens — obtained via POST /api/admin/login, valid for 7 days. Can access all endpoints including token management and 2FA.
  • API tokens — created in the admin UI with read (GET only) or write (all methods) scope. Cannot access /api/admin/api-tokens, /api/admin/2fa, or PUT /api/admin/config.

Timestamps

All timestamps in API responses are Unix milliseconds unless otherwise noted. The raw DB stores Unix seconds; the API layer multiplies by 1000. Exceptions (raw DB seconds) are noted per-field.

Rate Limiting

Public API endpoints are rate-limited per source IP. All limits are in-process and not distributed across instances.

Endpoint Limit
GET /api/pages 100 req / minute
GET /api/status 100 req / minute
GET /api/status/{id} 100 req / minute
GET /api/heartbeat/{id} 300 req / minute
POST /api/heartbeat/{id} 300 req / minute

Every response from these endpoints includes RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset headers. Requests that exceed the limit receive 429 with a Retry-After header (seconds until reset).

POST /api/admin/login uses a separate failure-based limit: 5 failures per IP per 15-minute window locks the IP out for 15 minutes.

public

Publicly accessible endpoints — no authentication required

List status pages

Returns all public status pages. Authenticated admins also see private pages and an additional isPublic field on each page.

Responses

Response samples

Content type
application/json
{
  • "pages": [
    ]
}

Get status page data

Returns the full status page payload including all services, their history, active incidents, and active announcements.

Requires bearer auth to view private pages. Public pages are accessible without auth.

query Parameters
page
string

Status page slug. Omit to use the default page.

Responses

Response samples

Content type
application/json
{
  • "page": {
    },
  • "title": "string",
  • "description": "string",
  • "logoUrl": "string",
  • "refreshInterval": 0,
  • "services": [
    ],
  • "activeIncidents": [
    ],
  • "announcements": [
    ]
}

Get single service status

Returns status and 90-day history for one service. Requires bearer auth to view services on private pages or unlisted (pageId null) services. Returns 404 (not 401) when the service is inaccessible to avoid leaking existence.

path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "name": "string",
  • "type": "http",
  • "status": "up",
  • "latencyMs": 0,
  • "message": "string",
  • "lastCheckedAt": 0,
  • "history90d": [
    ]
}

Record a heartbeat (POST)

Records a heartbeat for a heartbeat-type service. Use when your process can send POST requests (recommended).

The secret token must be provided via either the X-Heartbeat-Token header or the token query parameter.

Returns 404 for both "service not found" and "invalid token" to avoid leaking whether a service ID exists.

path Parameters
id
required
string
query Parameters
token
string

Heartbeat secret token (alternative to X-Heartbeat-Token header)

header Parameters
X-Heartbeat-Token
string

Heartbeat secret token (alternative to token query param)

Responses

Response samples

Content type
application/json
{
  • "error": "string",
  • "issues": [
    ],
  • "reason": "string"
}

Record a heartbeat (GET)

GET alias for POST /api/heartbeat/{id}. Intended for cron-like tools that issue a plain curl <url> without specifying a method.

Same token and response behavior as the POST variant.

path Parameters
id
required
string
query Parameters
token
string

Heartbeat secret token (alternative to X-Heartbeat-Token header)

header Parameters
X-Heartbeat-Token
string

Heartbeat secret token (alternative to token query param)

Responses

Response samples

Content type
application/json
{
  • "error": "string",
  • "issues": [
    ],
  • "reason": "string"
}

auth

Login and logout

Log in and obtain a session token

Verifies the admin password and, if 2FA is enabled, a TOTP code or recovery code. Returns a bearer token valid for 7 days.

Rate-limited to 5 failures per IP per 15-minute window. After 5 failures the IP is locked out for 15 minutes and all requests return 429 with a Retry-After header.

Request Body schema: application/json
required
password
required
string

Admin password (minimum 12 characters)

totp
string

6-digit TOTP code (required when 2FA is enabled)

recovery
string

Single-use recovery code (alternative to totp when 2FA is enabled)

Responses

Request samples

Content type
application/json
{
  • "password": "string",
  • "totp": "string",
  • "recovery": "string"
}

Response samples

Content type
application/json
{
  • "token": "string"
}

Revoke the current session token

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "error": "string",
  • "issues": [
    ],
  • "reason": "string"
}

services

Monitored service CRUD and actions (admin)

List all services

Returns all services with their latest check result and 30-day stats. apiKey and token fields are redacted.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create a service

Creates a new monitored service. For heartbeat services, token is auto-generated if omitted. Returns 409 if the id is already in use.

Authorizations:
bearerAuth
Request Body schema: application/json
required
id
required
string^[a-z0-9\-_]+$

Unique service identifier — lowercase alphanumeric, hyphens, underscores

name
required
string non-empty
type
required
string
intervalSeconds
required
integer >= 5

How often to run the check (seconds)

pageId
string or null
Default: null

Status page this service appears on. null = unlisted (admin-only)

paused
boolean
Default: false

Paused services are excluded from status pages and not actively checked

tags
Array of strings <= 16 items [ items [ 1 .. 40 ] characters ]
Default: []
slaTarget
number [ 50 .. 100 ]

Optional uptime SLA target percentage (50–100)

displayOrder
integer >= 0
Default: 1000

Sort order (lower = first). Multiples of 1000 when managed via the reorder endpoint

timeoutMs
integer >= 100
Default: 10000

Per-check request timeout in milliseconds

confirmationThreshold
integer [ 1 .. 10 ]
Default: 1

Consecutive failing checks required before an incident opens and an alert fires. 1 alerts on the first failure; higher values suppress short-lived blips (e.g. at a 30s interval, 3 means a failure must persist ~60s+ before paging).

retries
integer [ 0 .. 10 ]
Default: 0

Immediate re-probes after a failing check. If any re-probe comes back up the check is treated as up — neither recorded as down nor counted toward confirmationThreshold — so a one-off network hiccup is ignored.

retryDelayMs
integer [ 0 .. 60000 ]
Default: 1000

Delay between immediate re-probes (see retries), in milliseconds

object (AlertsConfig)

Per-service alert override configuration

url
required
string <uri>

URL to monitor. SSRF-protected — loopback, RFC1918, and cloud-metadata addresses are blocked.

method
string
Default: "GET"
Enum: "GET" "POST" "HEAD"
integer or string
Default: 200
body
string

Request body sent with POST requests

object

Additional request headers

followRedirects
boolean
Default: true
object or null

Assert the response body matches a pattern. At least one of contains, regex, or jsonPath must be set.

sslWarnDays
integer [ 1 .. 365 ]

Alert when the SSL certificate expires within this many days

Responses

Request samples

Content type
application/json
Example
{
  • "id": "string",
  • "name": "string",
  • "type": "http",
  • "intervalSeconds": 5,
  • "pageId": null,
  • "paused": false,
  • "tags": [ ],
  • "slaTarget": 50,
  • "displayOrder": 1000,
  • "timeoutMs": 10000,
  • "confirmationThreshold": 1,
  • "retries": 0,
  • "retryDelayMs": 1000,
  • "alerts": {
    },
  • "method": "GET",
  • "expectedStatus": 200,
  • "body": "string",
  • "headers": {
    },
  • "followRedirects": true,
  • "bodyMatch": {
    },
  • "sslWarnDays": 1
}

Response samples

Content type
application/json
Example
{
  • "id": "string",
  • "name": "string",
  • "type": "http",
  • "intervalSeconds": 5,
  • "pageId": null,
  • "paused": false,
  • "tags": [ ],
  • "slaTarget": 50,
  • "displayOrder": 1000,
  • "timeoutMs": 10000,
  • "confirmationThreshold": 1,
  • "retries": 0,
  • "retryDelayMs": 1000,
  • "alerts": {
    },
  • "method": "GET",
  • "expectedStatus": 200,
  • "body": "string",
  • "headers": {
    },
  • "followRedirects": true,
  • "bodyMatch": {
    },
  • "sslWarnDays": 1
}

Reorder services

Reassigns displayOrder to multiples of 1000 in the given array order.

Authorizations:
bearerAuth
Request Body schema: application/json
required
ids
required
Array of strings

Service IDs in the desired display order

Responses

Request samples

Content type
application/json
{
  • "ids": [
    ]
}

Response samples

Content type
application/json
{
  • "ok": true
}

Export services and pages as YAML

Downloads a YAML file containing all services and pages. Compatible with the import endpoint. By default, secrets (apiKey, token) are omitted; pass includeSecrets=1 to include them.

Authorizations:
bearerAuth
query Parameters
includeSecrets
string
Value: "1"

Pass 1 to include apiKey/token fields in the export

Responses

Response samples

Content type
application/json
{
  • "error": "string",
  • "issues": [
    ],
  • "reason": "string"
}

Import services and pages from YAML

Parses and validates a YAML document (same format as export). Runs a dry-run by default; pass mode: "commit" to apply changes.

The YAML must have a top-level services: array. An optional pages: array may also be present. All services are upserted (create or overwrite).

Authorizations:
bearerAuth
Request Body schema: application/json
required
yaml
required
string

YAML string to import

mode
string
Default: "dry-run"
Enum: "dry-run" "commit"

dry-run validates and reports what would be imported; commit applies the changes

Responses

Request samples

Content type
application/json
{
  • "yaml": "string",
  • "mode": "dry-run"
}

Response samples

Content type
application/json
{
  • "imported": 0,
  • "importedPages": 0
}

Get a service

Authorizations:
bearerAuth
path Parameters
id
required
string

Service ID

Responses

Response samples

Content type
application/json
Example
{
  • "id": "string",
  • "name": "string",
  • "type": "http",
  • "intervalSeconds": 5,
  • "pageId": null,
  • "paused": false,
  • "tags": [ ],
  • "slaTarget": 50,
  • "displayOrder": 1000,
  • "timeoutMs": 10000,
  • "confirmationThreshold": 1,
  • "retries": 0,
  • "retryDelayMs": 1000,
  • "alerts": {
    },
  • "method": "GET",
  • "expectedStatus": 200,
  • "body": "string",
  • "headers": {
    },
  • "followRedirects": true,
  • "bodyMatch": {
    },
  • "sslWarnDays": 1
}

Update a service

Merges the provided fields into the existing service config. Fields sent as null are cleared (optional fields become absent). Empty strings for apiKey or token are ignored — omit them to preserve the stored value.

Authorizations:
bearerAuth
path Parameters
id
required
string

Service ID

Request Body schema: application/json
required
id
required
string^[a-z0-9\-_]+$

Unique service identifier — lowercase alphanumeric, hyphens, underscores

name
required
string non-empty
type
required
string
intervalSeconds
required
integer >= 5

How often to run the check (seconds)

pageId
string or null
Default: null

Status page this service appears on. null = unlisted (admin-only)

paused
boolean
Default: false

Paused services are excluded from status pages and not actively checked

tags
Array of strings <= 16 items [ items [ 1 .. 40 ] characters ]
Default: []
slaTarget
number [ 50 .. 100 ]

Optional uptime SLA target percentage (50–100)

displayOrder
integer >= 0
Default: 1000

Sort order (lower = first). Multiples of 1000 when managed via the reorder endpoint

timeoutMs
integer >= 100
Default: 10000

Per-check request timeout in milliseconds

confirmationThreshold
integer [ 1 .. 10 ]
Default: 1

Consecutive failing checks required before an incident opens and an alert fires. 1 alerts on the first failure; higher values suppress short-lived blips (e.g. at a 30s interval, 3 means a failure must persist ~60s+ before paging).

retries
integer [ 0 .. 10 ]
Default: 0

Immediate re-probes after a failing check. If any re-probe comes back up the check is treated as up — neither recorded as down nor counted toward confirmationThreshold — so a one-off network hiccup is ignored.

retryDelayMs
integer [ 0 .. 60000 ]
Default: 1000

Delay between immediate re-probes (see retries), in milliseconds

object (AlertsConfig)

Per-service alert override configuration

url
required
string <uri>

URL to monitor. SSRF-protected — loopback, RFC1918, and cloud-metadata addresses are blocked.

method
string
Default: "GET"
Enum: "GET" "POST" "HEAD"
integer or string
Default: 200
body
string

Request body sent with POST requests

object

Additional request headers

followRedirects
boolean
Default: true
object or null

Assert the response body matches a pattern. At least one of contains, regex, or jsonPath must be set.

sslWarnDays
integer [ 1 .. 365 ]

Alert when the SSL certificate expires within this many days

Responses

Request samples

Content type
application/json
Example
{
  • "id": "string",
  • "name": "string",
  • "type": "http",
  • "intervalSeconds": 5,
  • "pageId": null,
  • "paused": false,
  • "tags": [ ],
  • "slaTarget": 50,
  • "displayOrder": 1000,
  • "timeoutMs": 10000,
  • "confirmationThreshold": 1,
  • "retries": 0,
  • "retryDelayMs": 1000,
  • "alerts": {
    },
  • "method": "GET",
  • "expectedStatus": 200,
  • "body": "string",
  • "headers": {
    },
  • "followRedirects": true,
  • "bodyMatch": {
    },
  • "sslWarnDays": 1
}

Response samples

Content type
application/json
Example
{
  • "id": "string",
  • "name": "string",
  • "type": "http",
  • "intervalSeconds": 5,
  • "pageId": null,
  • "paused": false,
  • "tags": [ ],
  • "slaTarget": 50,
  • "displayOrder": 1000,
  • "timeoutMs": 10000,
  • "confirmationThreshold": 1,
  • "retries": 0,
  • "retryDelayMs": 1000,
  • "alerts": {
    },
  • "method": "GET",
  • "expectedStatus": 200,
  • "body": "string",
  • "headers": {
    },
  • "followRedirects": true,
  • "bodyMatch": {
    },
  • "sslWarnDays": 1
}

Delete a service

Permanently deletes the service and all associated check history.

Authorizations:
bearerAuth
path Parameters
id
required
string

Service ID

Responses

Response samples

Content type
application/json
{
  • "error": "string",
  • "issues": [
    ],
  • "reason": "string"
}

Send a test alert

Dispatches a test alert to all configured destinations for this service.

Authorizations:
bearerAuth
path Parameters
id
required
string

Service ID

Responses

Response samples

Content type
application/json
{
  • "destinationsTried": 0,
  • "delivered": true
}

Trigger an immediate check

Runs the service check immediately, outside of the normal schedule. The result is also persisted as a regular check record.

Authorizations:
bearerAuth
path Parameters
id
required
string

Service ID

Responses

Response samples

Content type
application/json
{
  • "status": "up",
  • "latency_ms": 0,
  • "message": "string",
  • "checked_at": 0
}

checks

Check history, uptime percentages, and latency data (admin)

Get check history

Returns raw check result records, newest first, with 30-day retention.

Authorizations:
bearerAuth
path Parameters
id
required
string

Service ID

query Parameters
limit
integer [ 1 .. 1000 ]
Default: 100

Maximum number of records to return (default 100, max 1000)

before
integer

Return only records with checked_at earlier than this Unix timestamp (seconds). Use for cursor-based pagination.

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Get uptime percentage

Authorizations:
bearerAuth
path Parameters
id
required
string

Service ID

query Parameters
days
integer [ 1 .. 365 ]
Default: 30

Number of days to calculate over (default 30, max 365)

Responses

Response samples

Content type
application/json
{
  • "total": 0,
  • "uptimePct": 0
}

Get daily average latency

Returns daily average latency data. Today's row is refreshed on read.

Authorizations:
bearerAuth
path Parameters
id
required
string

Service ID

query Parameters
days
integer [ 1 .. 365 ]
Default: 30

Number of days to return (default 30, max 365)

Responses

Response samples

Content type
application/json
[
  • {
    }
]

pages

Status page management (admin)

List status pages

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create a status page

id, slug, and title are required. Slug must be lowercase alphanumeric, hyphens, or underscores, max 40 characters, and not a reserved word (admin, api, public, p, theme.css, favicon.svg).

Authorizations:
bearerAuth
Request Body schema: application/json
required
id
required
string^[a-z0-9\-_]+$
slug
required
string <= 40 characters ^[a-z0-9\-_]+$
title
required
string [ 1 .. 120 ] characters
description
string
Default: ""
logoUrl
string or null <uri>
isDefault
boolean
Default: false
isPublic
boolean
Default: true
displayOrder
integer >= 0
Default: 1000

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "slug": "string",
  • "title": "string",
  • "description": "",
  • "logoUrl": "http://example.com",
  • "isDefault": false,
  • "isPublic": true,
  • "displayOrder": 1000
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "slug": "string",
  • "title": "string",
  • "description": "string",
  • "logoUrl": "http://example.com",
  • "isDefault": true,
  • "isPublic": true,
  • "displayOrder": 0,
  • "createdAt": 0,
  • "updatedAt": 0
}

Get a status page

Authorizations:
bearerAuth
path Parameters
id
required
string

Status page ID

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "slug": "string",
  • "title": "string",
  • "description": "string",
  • "logoUrl": "http://example.com",
  • "isDefault": true,
  • "isPublic": true,
  • "displayOrder": 0,
  • "createdAt": 0,
  • "updatedAt": 0,
  • "serviceCount": 0
}

Update a status page

Partial update — only provided fields are changed. Setting isDefault: false on the current default page is rejected; set another page as default first. Setting logoUrl to an empty string clears it.

Authorizations:
bearerAuth
path Parameters
id
required
string

Status page ID

Request Body schema: application/json
required
slug
string <= 40 characters ^[a-z0-9\-_]+$
title
string [ 1 .. 120 ] characters
description
string
logoUrl
string or null <uri>
isDefault
boolean
isPublic
boolean
displayOrder
integer >= 0

Responses

Request samples

Content type
application/json
{
  • "slug": "string",
  • "title": "string",
  • "description": "string",
  • "logoUrl": "http://example.com",
  • "isDefault": true,
  • "isPublic": true,
  • "displayOrder": 0
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "slug": "string",
  • "title": "string",
  • "description": "string",
  • "logoUrl": "http://example.com",
  • "isDefault": true,
  • "isPublic": true,
  • "displayOrder": 0,
  • "createdAt": 0,
  • "updatedAt": 0
}

Delete a status page

Cannot delete the default page or a page that has services attached. Reassign or unlist services first, and set another page as default.

Authorizations:
bearerAuth
path Parameters
id
required
string

Status page ID

Responses

Response samples

Content type
application/json
{
  • "error": "string",
  • "issues": [
    ],
  • "reason": "string"
}

Set a page as the default

Makes this page the default status page. The previous default page is automatically demoted.

Authorizations:
bearerAuth
path Parameters
id
required
string

Status page ID

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

incidents

Incident tracking (admin)

List incidents

Returns all incidents, or filter by resolution state. Timestamps are raw Unix seconds.

Authorizations:
bearerAuth
query Parameters
resolved
string
Enum: "true" "false"

Filter by resolution state. Omit to return all.

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Resolve an incident

Marks an incident as resolved with resolved_by = "admin". Returns 409 if already resolved.

Authorizations:
bearerAuth
path Parameters
id
required
integer

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

maintenance

Maintenance window scheduling (admin)

List maintenance windows

Returns all maintenance windows grouped by group_id. Timestamps are raw Unix seconds.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create a maintenance window

Schedules a maintenance window for one or more services under a shared group ID.

Authorizations:
bearerAuth
Request Body schema: application/json
required
serviceIds
required
Array of strings non-empty

IDs of services to include in this maintenance window

label
required
string non-empty

Human-readable label for the maintenance window

startsAt
required
integer

Unix seconds when the maintenance window begins

endsAt
required
integer

Unix seconds when the maintenance window ends (must be after startsAt)

Responses

Request samples

Content type
application/json
{
  • "serviceIds": [
    ],
  • "label": "string",
  • "startsAt": 0,
  • "endsAt": 0
}

Response samples

Content type
application/json
{
  • "group_id": "string"
}

Update a maintenance window group

Updates all windows in the group. Omitted fields retain their current values.

Authorizations:
bearerAuth
path Parameters
id
required
string

Maintenance group ID

Request Body schema: application/json
required
serviceIds
Array of strings non-empty
label
string non-empty
startsAt
integer

Unix seconds

endsAt
integer

Unix seconds (must be after startsAt)

Responses

Request samples

Content type
application/json
{
  • "serviceIds": [
    ],
  • "label": "string",
  • "startsAt": 0,
  • "endsAt": 0
}

Response samples

Content type
application/json
{
  • "ok": true
}

Delete a maintenance window group

Authorizations:
bearerAuth
path Parameters
id
required
string

Maintenance group ID

Responses

Response samples

Content type
application/json
{
  • "error": "string",
  • "issues": [
    ],
  • "reason": "string"
}

announcements

Status announcements (admin)

List announcements

Returns all announcements (up to 200), newest first. Timestamps are raw Unix seconds.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create an announcement

Creates a new announcement and associates it with one or more status pages. At least one page ID is required.

Authorizations:
bearerAuth
Request Body schema: application/json
required
pageIds
required
Array of strings non-empty

IDs of pages this announcement should appear on

severity
required
string (AnnouncementSeverity)
Enum: "info" "incident" "maintenance"
title
required
string non-empty
bodyMarkdown
string or null

Optional body text in Markdown format

startsAt
required
integer

Unix seconds when the announcement becomes visible

endsAt
integer or null

Unix seconds when the announcement expires (null = no expiry)

Responses

Request samples

Content type
application/json
{
  • "pageIds": [
    ],
  • "severity": "info",
  • "title": "string",
  • "bodyMarkdown": "string",
  • "startsAt": 0,
  • "endsAt": 0
}

Response samples

Content type
application/json
{
  • "id": 0
}

Update an announcement

Partial update. Omitted fields retain their current values. Providing pageIds replaces the page list entirely.

Authorizations:
bearerAuth
path Parameters
id
required
integer

Announcement ID

Request Body schema: application/json
required
pageIds
Array of strings non-empty
severity
string (AnnouncementSeverity)
Enum: "info" "incident" "maintenance"
title
string non-empty
bodyMarkdown
string or null
startsAt
integer

Unix seconds

endsAt
integer or null

Unix seconds

Responses

Request samples

Content type
application/json
{
  • "pageIds": [
    ],
  • "severity": "info",
  • "title": "string",
  • "bodyMarkdown": "string",
  • "startsAt": 0,
  • "endsAt": 0
}

Response samples

Content type
application/json
{
  • "ok": true
}

Delete an announcement

Authorizations:
bearerAuth
path Parameters
id
required
integer

Announcement ID

Responses

Response samples

Content type
application/json
{
  • "error": "string",
  • "issues": [
    ],
  • "reason": "string"
}

Resolve an announcement

Sets resolved_at to now, hiding the announcement from status pages. Returns 409 if already resolved.

Authorizations:
bearerAuth
path Parameters
id
required
integer

Announcement ID

Responses

Response samples

Content type
application/json
{
  • "ok": true
}

audit

Audit log (admin)

List audit log entries

Returns audit log entries, newest first. Timestamps are raw Unix seconds.

Authorizations:
bearerAuth
query Parameters
limit
integer
Default: 100

Maximum number of entries to return (default 100)

offset
integer
Default: 0

Number of entries to skip (for pagination)

action
string

Filter by action name (exact match, e.g. service.create)

Responses

Response samples

Content type
application/json
[
  • {
    }
]

api-tokens

API token management — session auth only, not usable with API tokens

List API tokens

Returns all API tokens. Plaintext token values are never returned after creation. Requires session auth — API tokens cannot access this endpoint.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create an API token

Creates a new API token with read or write scope. The plaintext token is returned exactly once in the response — store it immediately. Requires session auth — API tokens cannot create other tokens.

Authorizations:
bearerAuth
Request Body schema: application/json
required
name
required
string non-empty

Human-readable label for this token

scope
required
string
Enum: "read" "write"

read — GET requests only. write — all HTTP methods. Neither scope allows access to /api/admin/api-tokens, /api/admin/2fa, or PUT /api/admin/config.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "scope": "read"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "name": "string",
  • "scope": "read",
  • "created_at": 0,
  • "token": "string"
}

Delete an API token

Permanently revokes the token. Requires session auth.

Authorizations:
bearerAuth
path Parameters
id
required
integer

Responses

Response samples

Content type
application/json
{
  • "error": "string",
  • "issues": [
    ],
  • "reason": "string"
}

2fa

Two-factor authentication management — session auth only

Get 2FA status

Returns whether 2FA is enabled and when it was enrolled. Requires session auth.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "enabled": true,
  • "enrolledAt": 0
}

Begin 2FA enrollment

Generates a new TOTP secret, stores it as pending (not yet enabled), and returns the secret with a QR code data URL for scanning in an authenticator app. Call POST /api/admin/2fa/verify-and-enable after scanning to complete enrollment. Requires session auth.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "secret": "string",
  • "otpUrl": "string",
  • "qrDataUrl": "string"
}

Verify TOTP and enable 2FA

Verifies a TOTP code against the pending secret and enables 2FA. Returns 8 single-use recovery codes — shown exactly once. Store them securely. Requires session auth. Call POST /api/admin/2fa/setup first.

Authorizations:
bearerAuth
Request Body schema: application/json
required
code
required
string

6-digit TOTP code from the authenticator app

Responses

Request samples

Content type
application/json
{
  • "code": "string"
}

Response samples

Content type
application/json
{
  • "recoveryCodes": [
    ]
}

Disable 2FA

Disables 2FA after verifying the admin password and a current TOTP code. Also invalidates all existing sessions, forcing a fresh login. Requires session auth.

Authorizations:
bearerAuth
Request Body schema: application/json
required
password
required
string

Current admin password

code
required
string

Current 6-digit TOTP code

Responses

Request samples

Content type
application/json
{
  • "password": "string",
  • "code": "string"
}

Response samples

Content type
application/json
{
  • "error": "string",
  • "issues": [
    ],
  • "reason": "string"
}

config

Application configuration (admin)

Get application configuration

Returns the current config. adminPassword and sessionSecret are always redacted from the response.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "server": {
    },
  • "database": {
    },
  • "alerts": {
    },
  • "statusPage": {
    }
}

Update application configuration

Replaces the configuration. Fields not provided are reset to defaults. Empty strings for adminPassword and sessionSecret preserve the existing values. Changing adminPassword invalidates all existing sessions.

Note: Only server.adminPassword, server.sessionSecret, and alerts.discord.webhookUrl support ${VAR} environment variable interpolation in the config file.

Authorizations:
bearerAuth
Request Body schema: application/json
required
property name*
additional property
any

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{
  • "ok": true
}

metrics

Prometheus metrics export

Prometheus metrics

Returns Prometheus-format metrics for all services including status, latency, and incident state. A read-scoped API token is sufficient.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "error": "string",
  • "issues": [
    ],
  • "reason": "string"
}