1. Documentation
  2. HTTP API
  3. Admin endpoints
ReadmenpmGitHub
  • Introduction
  • Quickstart
  • Configuration file
  • Monitors
  • Checks and scheduling
  • Notifications
  • Incidents and maintenance
  • Subscribers
  • Metrics and badges
  • Identity and appearance
  • Telemetry
  • The check run
  • Uptime and history
  • Automatic incidents
  • Notification delivery
  • Public subscriptions
  • StatusPage component
  • Themes
  • UI primitives
  • Colour mode
  • React Router
  • Next.js
  • Astro
  • SQLite
  • Cloudflare D1
  • PostgreSQL
  • Schema and migrations
  • Cloudflare Workers
  • Vercel
  • Self-hosting
  • API overview
  • Status endpoints
  • Incident and maintenance endpoints
  • Subscriber endpoints
  • Badges, feeds and metrics
  • Admin endpoints
  • CLI commands
  • Package exports
  • Security
  • Troubleshooting

Admin endpoints

Authentication, running checks on demand and reading the notification log.

Every mutation lives behind one authenticated prefix, so a public status page can never be edited by its visitors.

Authentication

http
Authorization: Bearer <HEYO_STATUS_API_TOKEN>

The token is read from adminToken in the configuration, falling back to the HEYO_STATUS_API_TOKEN environment variable — Workers and Deno do not always expose process.env, so both paths exist.

SituationResponse
No token configured503 { "error": "The management API is disabled. Set adminToken or HEYO_STATUS_API_TOKEN." }
Missing or wrong header401 { "error": "Unauthorized." }

Comparison is constant time, and the header is matched case-insensitively against Bearer <token>.

Closed by default is the point

A freshly deployed status page is not writable by anyone. Setting the token is a deliberate act, not something you can forget into being insecure.

ts
heyoStatus({  // …  adminToken: process.env.HEYO_STATUS_API_TOKEN,});

Generate one with openssl rand -hex 32, store it as a platform secret, and rotate it by updating the secret — there is no token list to maintain.

POST /admin/checks/run

Runs every configured monitor once, stores the results, reconciles automatic incidents and dispatches notifications. It is the same code path as the scheduler.

bash
curl -X POST https://status.acme.com/api/heyo-status/admin/checks/run \  -H "authorization: Bearer $HEYO_STATUS_API_TOKEN"
json
[  {    "name": "Website",    "type": "http",    "status": true,    "message": "HTTP 200",    "latencyMs": 96,    "checkedAt": "2026-01-01T12:00:00.000Z"  }]
ResponseWhen
200Results array.
501{ "error": "Manual checks require the status-page runtime." } — the app was built with createStatusApp() without a runChecks option.

Useful as an external trigger for a platform without cron, as a deploy-time warm-up so the page is never empty, and when verifying a monitor change.

Only checks have an HTTP trigger

Summarize and cleanup have no route. Run them with heyo-status, with scheduleStatusPage(), or through your platform's cron integration.

GET /admin/notifications/log

Every delivery attempt, newest first.

bash
curl -H "authorization: Bearer $HEYO_STATUS_API_TOKEN" \  "https://status.acme.com/api/heyo-status/admin/notifications/log?status=failed&limit=20"
QueryTypeNotes
channelIdstringexact match
eventTypeany event namecomma-separated
statussent, failedcomma-separated
limitnon-negative integer
offsetnon-negative integer
json
[  {    "id": "ntf_6ac204",    "channelId": "slack",    "channelType": "slack",    "eventType": "monitor.down",    "status": "failed",    "attempts": 1,    "error": "Slack delivery failed with HTTP 404: no_service",    "monitorName": "API",    "incidentId": null,    "maintenanceId": null,    "createdAt": "2026-01-01T10:02:00.000Z"  }]

The log stores no payload, no webhook URL, no credentials and no recipient. It exists to debug delivery, not to replay it.

Incident and maintenance management

Documented in full on Incident and maintenance endpoints:

MethodPath
POST/admin/incidents
POST/admin/incidents/:id/updates
PATCH/admin/incidents/:id
DELETE/admin/incidents/:id
POST/admin/maintenance
PATCH/admin/maintenance/:id
DELETE/admin/maintenance/:id

Scripting it

scripts/open-incident.ts
const base = "https://status.acme.com/api/heyo-status";const headers = {  authorization: `Bearer ${process.env.HEYO_STATUS_API_TOKEN}`,  "content-type": "application/json",};const incident = await fetch(`${base}/admin/incidents`, {  method: "POST",  headers,  body: JSON.stringify({    title: "Deploy rollback in progress",    severity: "major",    affectedMonitors: ["API"],    message: "Rolling back the 14:02 deploy.",  }),}).then((response) => response.json());await fetch(`${base}/admin/incidents/${incident.id}/updates`, {  method: "POST",  headers,  body: JSON.stringify({ status: "resolved", message: "Rollback complete." }),});

For a local or CI context, the CLI does the same without a token or a network round trip — it talks to the database directly:

bash
heyo-status incident create --title "…" --severity major --monitors API --message "…"

Related

  • Incident and maintenance endpoints
  • Security checklist
  • CLI commands
Badges, feeds and metrics< PreviousCLI commandsNext >

Powered by heyo

On this page

AuthenticationPOST /admin/checks/runGET /admin/notifications/logIncident and maintenance managementScripting it