REST API
A JSON API for building dashboards, integrations and apps: read status, uptime and incidents, and create or manage HTTP monitors. Owners create keys under Settings → API access; keys are shown once and stored hashed.
Authentication
curl -H "Authorization: Bearer vgl_api_…" \ https://vigil.xzz.dk/api/v1/monitors
Missing or invalid keys return 401 with {"error": "…"}. Keys created by team members (via app login below) are read-only — write endpoints return 403 for them.
POST /api/v1/auth/login
Exchange your account email and password for a fresh API key — this is how the iOS app signs in. The key is returned exactly once and inherits your role in the org. deviceName is optional and only labels the key in Settings → API access, where it can be revoked at any time. Limited to 10 attempts per 5 minutes per IP.
curl -X POST -H "Content-Type: application/json" \
-d '{"email": "[email protected]", "password": "…", "deviceName": "Casper's iPhone"}' \
https://vigil.xzz.dk/api/v1/auth/login
{
"apiKey": "vgl_api_…",
"role": "owner", // owner | admin | member (member = read-only)
"user": { "name": "Casper", "email": "[email protected]" },
"org": { "name": "HTML ApS", "plan": "pro" }
}POST /api/v1/auth/logout
Revokes the API key used to authenticate the request (the app calls this on sign-out).
GET /api/v1/monitors
All monitors with current status and uptime.
{
"monitors": [
{
"id": "5db41d29-…",
"name": "Shop",
"url": "https://shop.example.com",
"status": "up", // up | down | challenged | pending | paused | maintenance
"intervalSeconds": 60,
"lastStatusChangeAt": "2026-06-10T14:43:55.000Z",
"uptime24h": 99.93,
"uptime30d": 99.98,
"uptime90d": 99.99,
"certExpiresAt": "2026-08-29T23:41:26.000Z",
"createdAt": "2026-06-01T09:00:00.000Z"
}
]
}GET /api/v1/monitors/:id
One monitor in full: configuration, uptime, SSL details, per-location state (HTTP status, response time, last error, redirect destination) and the 20 most recent incidents.
GET /api/v1/monitors/:id/results?hours=24
Raw check results, newest first, up to 5000 rows. hours accepts 1–168.
{
"results": [
{
"checkedAt": "2026-06-10T14:32:00.000Z",
"location": "fra",
"ok": true,
"httpStatus": 200,
"responseMs": 182,
"challenge": false,
"error": null
}
]
}GET /api/v1/incidents
The 100 most recent incidents across all monitors, with cause, affected locations and timestamps.
POST /api/v1/monitors
Create an HTTP monitor. name and url are required; everything else falls back to the same defaults as the dashboard. Returns 201 with the new monitor, or 403 when the plan's monitor limit is reached.
curl -X POST -H "Authorization: Bearer vgl_api_…" \
-H "Content-Type: application/json" \
-d '{
"name": "Shop",
"url": "https://shop.example.com",
"method": "GET", // GET | HEAD | POST | PUT | PATCH | DELETE
"intervalSeconds": 60, // 30–3600
"timeoutMs": 10000, // 1000–60000
"expectedStatus": "2xx", // "2xx" … "5xx" or an exact code like "200"
"followRedirects": true,
"confirmations": 2, // 1–10 consecutive fails before a location is down
"quorum": 1 // 1–10 locations down before an incident opens
}' \
https://vigil.xzz.dk/api/v1/monitorsKeyword assertions, custom headers/bodies, basic auth and channel/location selection are configured in the dashboard for now. Heartbeat monitors can't be created over the API.
PATCH /api/v1/monitors/:id
Partial update — send any subset of the creation fields plus paused and maintenance. Setting {"paused": true} behaves like the dashboard toggle (status resets to pending so resuming starts clean). Heartbeat monitors accept only name, paused and maintenance.
curl -X PATCH -H "Authorization: Bearer vgl_api_…" \
-H "Content-Type: application/json" \
-d '{"paused": true}' \
https://vigil.xzz.dk/api/v1/monitors/5db41d29-…DELETE /api/v1/monitors/:id
Deletes the monitor and all of its history. Irreversible.
POST /api/v1/monitors/:id/check
Asks every probe location to re-check the monitor on its next config poll (≈30 seconds).
POST /api/v1/devices
Registers an APNs device token so the iOS app receives incident push notifications. Idempotent — re-registering refreshes the token. environment is "production" (default) or "sandbox" for debug builds; name is an optional device label.
curl -X POST -H "Authorization: Bearer vgl_api_…" \
-H "Content-Type: application/json" \
-d '{"token": "a1b2c3…", "environment": "production", "name": "Casper's iPhone"}' \
https://vigil.xzz.dk/api/v1/devicesDELETE /api/v1/devices/:token
Unregisters a device (the app calls this on sign-out). Dead tokens are also pruned automatically when Apple rejects them.
Notes
- All timestamps are ISO 8601 in UTC.
- Uptime percentages are calculated over daily buckets;
nullmeans no data yet. - For pushing data out in real time, use signed webhooks instead of polling — see Webhook payloads.