Monitors API
List and retrieve uptime monitors via the StatusOwl REST API.
The Monitors API exposes the monitor configurations in your organization. The current v1 surface is read-only — list and retrieve. Create / update / delete endpoints are on the roadmap; until they ship, manage monitors from the dashboard.
All Monitors endpoints require the monitors:read
scope on the API key. See API authentication
for how to present a key, and Managing API keys
for creation and rotation.
Base URL
https://api.statusowl.net/v1
List monitors
GET /v1/monitors
Returns the monitors in the calling key's organization, newest first.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer ≥ 1 | 1 | Page number |
per_page | integer 1–100 | 25 | Results per page (capped at 100) |
type | string | — | Filter by monitor type: http, https, tcp, ping |
is_active | true / false | — | Filter by active state |
Example
curl https://api.statusowl.net/v1/monitors?type=http&per_page=10 \
-H "Authorization: Bearer sowl_live_xxxxxxxxxxxxxxxxxxxx"
Response
{
"data": [
{
"monitor_uuid": "9b6f6c8e-1f70-4b9b-87a0-9f3a8a8a4a01",
"name": "Marketing site",
"type": "https",
"target": "https://statusowl.net",
"port": null,
"interval": 60,
"regions": ["nyj", "fra"],
"maintenance_mode": false,
"is_active": true,
"last_check_at": "2026-04-26T19:14:02.118Z",
"last_status": "up",
"last_response_time_ms": 142,
"created_at": "2026-04-01T15:21:08.422Z",
"updated_at": "2026-04-12T11:03:55.901Z"
}
],
"pagination": {
"page": 1,
"per_page": 10,
"total": 1,
"total_pages": 1
}
}
Retrieve a monitor
GET /v1/monitors/{monitor_uuid}
Returns full configuration for one monitor, including HTTP-specific fields when applicable.
Path parameters
| Parameter | Type | Description |
|---|---|---|
monitor_uuid | UUID | The monitor's UUID. Must belong to the calling key's organization. |
Example
curl https://api.statusowl.net/v1/monitors/9b6f6c8e-1f70-4b9b-87a0-9f3a8a8a4a01 \
-H "Authorization: Bearer sowl_live_xxxxxxxxxxxxxxxxxxxx"
Response
{
"data": {
"monitor_uuid": "9b6f6c8e-1f70-4b9b-87a0-9f3a8a8a4a01",
"name": "Marketing site",
"type": "https",
"target": "https://statusowl.net",
"port": null,
"interval": 60,
"regions": ["nyj", "fra"],
"maintenance_mode": false,
"description": "Public marketing site, multi-region",
"is_active": true,
"last_check_at": "2026-04-26T19:14:02.118Z",
"last_status": "up",
"last_response_time_ms": 142,
"http_method": "GET",
"expected_status_codes": [200, 301],
"follow_redirects": true,
"timeout_ms": 10000,
"created_at": "2026-04-01T15:21:08.422Z",
"updated_at": "2026-04-12T11:03:55.901Z"
}
}
A monitor that doesn't exist or belongs to another organization returns 404 — the API does not distinguish between the two cases to avoid leaking the existence of foreign UUIDs.
Field reference
| Field | Type | Notes |
|---|---|---|
monitor_uuid | UUID | Stable identifier; safe to use in URLs and reports |
name | string | Human-readable label |
type | enum | http, https, tcp, or ping |
target | string | URL for http/https; hostname or IP for tcp/ping |
port | integer / null | TCP port (null for non-TCP monitors) |
interval | integer | Check interval in seconds |
regions | string[] | Region codes the monitor runs from. See Multi-region checks |
maintenance_mode | boolean | When true, results are recorded but no incidents or alerts fire |
description | string / null | Detail-only |
is_active | boolean | Inactive monitors are not scheduled |
last_check_at | timestamptz / null | Most recent check timestamp |
last_status | string / null | up, down, or null before the first check |
last_response_time_ms | integer / null | Most recent latency in ms |
http_method | enum / null | Detail-only. GET, POST, PUT, PATCH, DELETE, HEAD, or OPTIONS |
expected_status_codes | integer[] / null | Detail-only. Acceptable status codes |
follow_redirects | boolean / null | Detail-only. Whether 3xx responses are followed |
timeout_ms | integer / null | Detail-only. Request timeout |
created_at | timestamptz | When the monitor was created |
updated_at | timestamptz | When the monitor was last modified |
The list endpoint omits description, http_method, expected_status_codes,
follow_redirects, and timeout_ms — fetch a single monitor to get them.
Errors
| Status | Cause |
|---|---|
| 400 | Invalid query parameter (e.g. type=foo, per_page=500) |
| 401 | Missing, malformed, revoked, or expired API key |
| 403 | Key is valid but missing the monitors:read scope, or the calling IP is not on the key's allowlist |
| 404 | monitor_uuid doesn't exist in the calling organization |
| 429 | Rate limit or quota exceeded — see response headers and retry after the indicated interval |
All error responses follow the envelope:
{ "error": "Descriptive error message" }
Rate limit and quota headers
Every successful response includes the current per-key and per-org headroom:
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 599
X-RateLimit-Reset: 60
X-Quota-Daily-Limit: 100000
X-Quota-Daily-Remaining: 99873
X-Quota-Monthly-Limit: 3000000
X-Quota-Monthly-Remaining: 2987112
A 429 means you've crossed either the per-minute rate limit or one of the daily
/ monthly quotas. Back off based on X-RateLimit-Reset (seconds) for rate-limit
hits, or wait until the next daily / monthly window for quota hits.
What's not yet available
- Write endpoints (
POST,PATCH,DELETE) — themonitors:writescope exists in the catalog but no endpoint consumes it yet. Manage monitors in the dashboard for now. - Time-series check results — uptime % over a window, response-time
histograms, per-region timelines. The
metrics:readscope is reserved for this surface; endpoints are not yet shipped. - Bulk operations — no endpoint accepts a list of UUIDs in a single
request. List with
per_page=100and iterate.