PublicStatus API
Update your status page from anywhere — let your monitoring, CI or scripts open and resolve incidents, flip a component to degraded, or schedule maintenance. No browser, no login: a long-lived Personal Access Token carries the request.
On this page
Quickstart
- In the admin, open Settings → API Tokens and create a token (available from the Team plan). The
kpat_…value is shown once — copy it. - Point requests at your status domain:
https://status.example.com/api/writefor changes,/api/queryfor reads. - Send the token as a bearer header. The tenant is resolved from the token — you never pass a tenant id.
curl -X POST https://status.example.com/api/write \
-H "Authorization: Bearer kpat_your_token_here" \
-H "Content-Type: application/json" \
-d '{
"type": "publicstatus:write:incident:open",
"payload": { "title": "Elevated API latency", "body": "We are investigating.", "severity": "minor" }
}'
Authentication
Every request carries a Personal Access Token in the Authorization header:
Authorization: Bearer kpat_your_token_here
- Tokens are minted per user in Settings → API Tokens and are gated to the Team plan and up.
- A token inherits your account's live roles and is limited to the scopes you grant it.
- The plaintext token is shown once at creation. Store it securely (e.g. a CI secret) — you can revoke it anytime, effective immediately.
Scopes
Each scope comes in a read and a write variant. A token only receives the scopes you tick when creating it.
| Scope | Grants |
|---|---|
incidents | Open, post updates to, and resolve incidents |
maintenance | Schedule, start, complete and cancel maintenance windows |
components | Create, update and delete components (the service list) |
Request format
All calls are POST with a JSON envelope. type is the action, payload its parameters:
POST /api/write { "type": "<action>", "payload": { … } } // writes
POST /api/query { "type": "<action>", "payload": { … } } // reads
A successful write responds { "isSuccess": true, "data": { … } }. For component endpoints, the created/updated row (with its id and version) is in data.data; incident/maintenance endpoints respond with their own smaller data shape (see the note under each). Reads respond { "data": { "rows": [ … ] } }.
Incidents
Open an incident — publicstatus:write:incident:open
Fields: title, body (the first update), severity (minor · major · critical, default minor), optional componentIds (components to flag as affected), optional startedAt (ISO-8601).
curl -X POST https://status.example.com/api/write \
-H "Authorization: Bearer kpat_your_token_here" \
-H "Content-Type: application/json" \
-d '{
"type": "publicstatus:write:incident:open",
"payload": {
"title": "Elevated API latency",
"body": "We are investigating elevated response times.",
"severity": "major",
"componentIds": ["019f288c-2cf7-7631-b12b-0fca8db39544"]
}
}'
The response's data.id is the incident id — keep it to post updates and resolve.
Post an update — publicstatus:write:incident:post-update
Fields: incidentId, body, optional newStatus (investigating · identified · monitoring · resolved).
curl -X POST https://status.example.com/api/write \
-H "Authorization: Bearer kpat_your_token_here" \
-H "Content-Type: application/json" \
-d '{
"type": "publicstatus:write:incident:post-update",
"payload": { "incidentId": "019f28a1-....", "body": "Root cause identified, rolling out a fix.", "newStatus": "identified" }
}'
Resolve an incident — publicstatus:write:incident:resolve
Fields: incidentId, body (the closing note).
curl -X POST https://status.example.com/api/write \
-H "Authorization: Bearer kpat_your_token_here" \
-H "Content-Type: application/json" \
-d '{
"type": "publicstatus:write:incident:resolve",
"payload": { "incidentId": "019f28a1-....", "body": "Latency back to normal. Resolved." }
}'
Components
Components are the services shown on your page. Status values: operational · degraded-performance · partial-outage · major-outage · under-maintenance.
Create — publicstatus:write:component:create
curl -X POST https://status.example.com/api/write \
-H "Authorization: Bearer kpat_your_token_here" \
-H "Content-Type: application/json" \
-d '{
"type": "publicstatus:write:component:create",
"payload": { "name": "API", "description": "Public HTTP API", "status": "operational", "displayOrder": 0, "showOnPage": true }
}'
Update (flip the status) — publicstatus:write:component:update
Send the component id, its current version (optimistic concurrency) and the changes. This is what an alert integration calls to turn a service red or green.
curl -X POST https://status.example.com/api/write \
-H "Authorization: Bearer kpat_your_token_here" \
-H "Content-Type: application/json" \
-d '{
"type": "publicstatus:write:component:update",
"payload": { "id": "019f288c-2cf7-7631-b12b-0fca8db39544", "version": 1, "changes": { "status": "major-outage" } }
}'
Delete — publicstatus:write:component:delete
curl -X POST https://status.example.com/api/write \
-H "Authorization: Bearer kpat_your_token_here" \
-H "Content-Type: application/json" \
-d '{ "type": "publicstatus:write:component:delete", "payload": { "id": "019f288c-....", "version": 1 } }'
Maintenance
Schedule — publicstatus:write:maintenance:schedule
Fields: title, body, scheduledStart + scheduledEnd (ISO-8601), optional componentIds.
curl -X POST https://status.example.com/api/write \
-H "Authorization: Bearer kpat_your_token_here" \
-H "Content-Type: application/json" \
-d '{
"type": "publicstatus:write:maintenance:schedule",
"payload": {
"title": "Database upgrade",
"body": "Brief read-only window during the upgrade.",
"scheduledStart": "2026-07-10T02:00:00Z",
"scheduledEnd": "2026-07-10T03:00:00Z",
"componentIds": ["019f288c-2d6b-72aa-a5b0-feaf8a38ea37"]
}
}'
Start / Complete / Cancel
Each takes the maintenance id and its current version:
# start: "type": "publicstatus:write:maintenance:start"
# complete: "type": "publicstatus:write:maintenance:complete"
# cancel: "type": "publicstatus:write:maintenance:cancel"
curl -X POST https://status.example.com/api/write \
-H "Authorization: Bearer kpat_your_token_here" \
-H "Content-Type: application/json" \
-d '{ "type": "publicstatus:write:maintenance:start", "payload": { "id": "019f28b0-....", "version": 1 } }'
Reading data
With a read scope you can list your components and incidents — handy to look up ids before updating.
# list components (returns id, name, status, version, …)
curl -X POST https://status.example.com/api/query \
-H "Authorization: Bearer kpat_your_token_here" \
-H "Content-Type: application/json" \
-d '{ "type": "publicstatus:query:component:list", "payload": {} }'
# list incidents
curl -X POST https://status.example.com/api/query \
-H "Authorization: Bearer kpat_your_token_here" \
-H "Content-Type: application/json" \
-d '{ "type": "publicstatus:query:incident:list", "payload": {} }'
Guide: drive the page from Prometheus Alertmanager
The most common setup: your monitoring already knows when a service is down — wire it straight to the status page. Alertmanager can POST a webhook per alert; a tiny adapter translates that into API calls.
1. Add a webhook receiver
Alongside your existing receivers (Slack, Telegram, …), add one that points at your adapter:
receivers:
- name: statuspage
webhook_configs:
- url: http://statuspage-bridge/alert # your adapter
send_resolved: true # so 'resolved' closes the incident
route:
routes:
- matchers: [ 'statuspage="true"' ] # opt individual alerts in
receiver: statuspage
group_by: [ alertname, component ]
Tag the alerts you want on the page with a label, e.g. statuspage: "true" and a component label naming the affected service.
2. Map the webhook to API calls
Alertmanager sends a batch with status: "firing" | "resolved" and each alert's labels. The adapter's logic:
- firing →
incident:open(title fromalertname,severityfrom the severity label) and/or flip the mapped component tomajor-outageviacomponent:update. Remember the returned incident id (keyed by alert fingerprint). - resolved →
incident:resolvefor the remembered id, and flip the component back tooperational.
A firing webhook, translated, is exactly the call from the top of this page:
# adapter receives Alertmanager JSON, then:
curl -X POST https://status.example.com/api/write \
-H "Authorization: Bearer $STATUSPAGE_PAT" \
-H "Content-Type: application/json" \
-d '{
"type": "publicstatus:write:incident:open",
"payload": { "title": "HighLatency on studio", "body": "Alert firing since 15:04Z.", "severity": "major" }
}'
incidents:write and (if it flips component status) components:write. Store the kpat_… as a secret in your cluster, never in the alert config.Errors
Failures return a non-2xx status and { "isSuccess": false, "error": { … } }. Common cases:
| Status | Meaning |
|---|---|
401 | Missing, malformed, revoked or expired token |
403 feature_disabled | Your plan doesn't include the API — upgrade to Team |
403 | The token wasn't granted a scope covering this action |
400 / 422 | Invalid payload, or a plan limit reached (e.g. component cap) |