PublicStatus API

Aktualisiere deine Status-Page von überall — lass Monitoring, CI oder Skripte Incidents öffnen und schließen, eine Komponente auf „degraded“ setzen oder Wartungen planen. Kein Browser, kein Login: ein langlebiger Personal Access Token trägt den Request.

Schnellstart

  1. Im Admin unter Einstellungen → API-Tokens einen Token erstellen (ab dem Team-Tarif). Der kpat_…-Wert wird nur einmal angezeigt — kopieren.
  2. Requests an deine Status-Domain: https://status.example.com/api/write für Änderungen, /api/query zum Lesen.
  3. Token als Bearer-Header senden. Der Tenant kommt aus dem Token — du übergibst nie eine 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" }
  }'

Authentifizierung

Jeder Request trägt einen Personal Access Token im Authorization-Header:

Authorization: Bearer kpat_your_token_here
Bearer-Requests sind von CSRF und Cookies ausgenommen — der Token allein authentifiziert. Behandle ihn wie ein Passwort.

Scopes

Jeden Scope gibt es als read und write. Ein Token bekommt nur die Scopes, die du beim Erstellen anhakst.

ScopeErlaubt
incidentsIncidents öffnen, Updates posten, auflösen
maintenanceWartungsfenster planen, starten, abschließen, abbrechen
componentsKomponenten (die Dienst-Liste) anlegen, ändern, löschen

Request-Format

Alle Calls sind POST mit JSON-Envelope. type ist die Aktion, payload ihre Parameter:

POST /api/write        { "type": "<action>", "payload": { … } }   // writes
POST /api/query        { "type": "<action>", "payload": { … } }   // reads

Ein erfolgreicher Write antwortet { "isSuccess": true, "data": { … } }. Bei Komponenten-Endpoints liegt die angelegte/geänderte Row (mit id + version) in data.data; Incident-/Wartungs-Endpoints antworten mit einer eigenen, kleineren data-Form (siehe die jeweilige Notiz unten). Reads antworten { "data": { "rows": [ … ] } }.

Incidents

Incident öffnen — publicstatus:write:incident:open

Felder: title, body (erstes Update), severity (minor · major · critical, Default minor), optional componentIds (betroffene Komponenten), 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"]
    }
  }'

Das data.id der Antwort ist die Incident-ID — für Updates und Resolve merken.

Update posten — publicstatus:write:incident:post-update

Felder: 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" }
  }'

Incident auflösen — publicstatus:write:incident:resolve

Felder: incidentId, body (Abschluss-Notiz).

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." }
  }'

Komponenten

Komponenten sind die Dienste auf deiner Seite. Status-Werte: operational · degraded-performance · partial-outage · major-outage · under-maintenance.

Anlegen — 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 }
  }'

Ändern (Status umschalten) — publicstatus:write:component:update

Sende die Komponenten-id, ihre aktuelle version (optimistische Sperre) und die changes. Genau das ruft eine Alert-Integration auf, um einen Dienst rot oder grün zu schalten.

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" } }
  }'

Löschen — 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 } }'

Wartung

Planen — publicstatus:write:maintenance:schedule

Felder: 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"]
    }
  }'

Starten / Abschließen / Abbrechen

Jeweils die Wartungs-id und ihre aktuelle 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 } }'

Daten lesen

Mit einem read-Scope kannst du Komponenten und Incidents auflisten — praktisch, um IDs vor einem Update nachzuschlagen.

# 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: die Seite aus Prometheus Alertmanager treiben

Der häufigste Fall: dein Monitoring weiß bereits, wann ein Dienst down ist — verdrahte es direkt mit der Status-Page. Alertmanager kann pro Alert einen Webhook POSTen; ein kleiner Adapter übersetzt das in API-Calls.

1. Webhook-Receiver hinzufügen

Neben deinen bestehenden Receivern (Slack, Telegram, …) einen ergänzen, der auf deinen Adapter zeigt:

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 ]

Markiere die Alerts, die auf die Seite sollen, mit einem Label, z. B. statuspage: "true" und einem component-Label mit dem betroffenen Dienst.

2. Webhook auf API-Calls mappen

Alertmanager schickt einen Batch mit status: "firing" | "resolved" und den Labels jedes Alerts. Die Adapter-Logik:

Ein firing-Webhook, übersetzt, ist genau der Call vom Anfang der Seite:

# 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" }
  }'
Gib dem Adapter-Token nur die nötigen Scopes — incidents:write und (falls er den Komponenten-Status setzt) components:write. Den kpat_… als Secret im Cluster ablegen, nie in der Alert-Config.

Fehler

Fehlschläge liefern einen Nicht-2xx-Status und { "isSuccess": false, "error": { … } }. Häufige Fälle:

StatusBedeutung
401Token fehlt, ist ungültig, widerrufen oder abgelaufen
403 feature_disabledDein Tarif enthält die API nicht — auf Team upgraden
403Der Token hat keinen Scope für diese Aktion
400 / 422Ungültiges Payload, oder ein Tarif-Limit erreicht (z. B. Komponenten-Cap)