Incident API v1
Drive incidents and maintenance windows on your status pages from your own monitoring.
Overview
The Incident API lets your own monitoring (checkMK, Zabbix, Prometheus Alertmanager, a cron script) drive FoundersDeck incidents and scheduled maintenances. It does exactly what the dashboard does: the same validation, the same status page updates and the same subscriber emails.
What the API can do:
- Open, update and resolve manual incidents on your status pages.
- Schedule, change and cancel maintenance windows, optionally suppressing alerts for the affected monitors.
- List your monitors and status pages, so you can reference them by ID.
What the API cannot do (v1):
- Create, change or delete monitors, status pages, alert channels or subscribers.
- Read or change automatic incidents that FoundersDeck opens from its own checks.
- Delete incidents or maintenances (use the dashboard).
Requirements: the API is available on the Pro plan or higher. All requests and responses use JSON (Content-Type: application/json), field names are snake_case, timestamps are ISO 8601 in UTC.
Base URL:
https://foundersdeck.dev/api/v1
Authentication
Every request needs an API key in the Authorization header:
Authorization: Bearer fd_live_<40 characters>
- Create a key in the dashboard under Settings → API keys. Give it a name (1–60 characters, for example
checkMK production). - Key format:
fd_live_followed by 40 charactersA–Z,a–z,0–9. - Shown once: the full key is displayed only right after creation. FoundersDeck stores only a SHA-256 hash and the first 12 characters (for example
fd_live_AbCd) so you can recognise the key in the list. If you lose a key, create a new one. - Limit: at most 5 active keys per account.
- Revoke a key in the same list. Requests with a revoked key fail immediately with
401 key_revoked. Revoking cannot be undone. - A key acts on behalf of the account that created it and only sees that account's data. Every change made via the API is recorded in the audit log together with the key that made it.
- If your account drops below the Pro plan, existing keys stop working (
403 plan_required) but stay in the list, so you can still revoke them.
The scheme name Bearer is case-insensitive. Put exactly one space between the scheme and the key.
Rate limits
- 60 requests per minute per API key. The window starts with the first request and resets after 60 seconds.
- 30 notification-triggering requests per minute per account, on top of that. These are the calls that can email your status page subscribers: opening an incident (
POST /incidents), posting an update (POST /incidents/{ref}/updates), resolving (POST /incidents/{ref}/resolve), scheduling a maintenance (POST /maintenances) and cancelling one (POST /maintenances/{ref}/cancel). This limit counts per account, so several keys share it. Idempotent repeats that return an existing incident or maintenance with200(sameexternal_id) do not count. - Exceeding either limit returns
429 rate_limitedwith the headerRetry-After: 60. Wait that many seconds before retrying. - Only authenticated requests count: requests rejected with
401or403do not use up your quota.
Errors
Every error has the same body:
{
"error": {
"code": "validation_failed",
"message": "Request validation failed",
"details": [
{
"origin": "string",
"code": "too_small",
"minimum": 1,
"inclusive": true,
"path": ["title"],
"message": "Too small: expected string to have >=1 characters"
}
]
}
}
code is stable and meant for your code; message is a human-readable English sentence and may change. details is only present for schema validation errors and lists every failed field with its path.
| HTTP | code |
When | Example message |
|---|---|---|---|
| 401 | unauthorized |
Authorization header missing, not Bearer <key>, key not in fd_live_ format |
Missing or malformed API key |
| 401 | unauthorized |
Well-formed key that does not exist | Invalid API key |
| 401 | key_revoked |
The key was revoked in the dashboard | This API key has been revoked |
| 403 | plan_required |
The account is not on Pro or higher | This feature requires the Pro plan or higher |
| 404 | not_found |
The {ref} in the path does not exist, belongs to another account or is not a valid UUID / ext: reference |
Incident not found / Maintenance not found / Not found |
| 404 | not_found |
A monitor_ids / status_page_ids entry or related_incident_id does not belong to your account |
One or more monitors do not belong to this user |
| 409 | conflict |
A concurrent request created the same external_id first (see Idempotency), or the automatic incident in related_incident_id is already linked to another manual incident |
Resource already exists |
| 409 | conflict |
An update with a status other than resolved was posted to a resolved incident |
Incident is already resolved |
| 422 | validation_failed |
Body is not valid JSON | Body must be valid JSON |
| 422 | validation_failed |
A field is missing, has the wrong type or is out of range (details lists the fields) |
Request validation failed |
| 422 | validation_failed |
A change would leave an incident or maintenance without any monitor and status page, or a maintenance window would end before it starts | At least one monitor or status page assignment is required |
| 429 | rate_limited |
More than 60 requests per minute with this key | Too many requests |
| 429 | rate_limited |
More than 30 notification-triggering requests per minute for this account (see Rate limits) | Too many notification-triggering requests |
| 500 | internal |
Unexpected server error; safe to retry with the same external_id |
Internal error |
Checks run in this order: authentication (401), plan (403), request rate limit (429), path reference (404), body (422), notification limit (429, only on the endpoints listed under Rate limits), then the change itself (404, 409, 422). At the path-reference step, a malformed {ref} or an unknown ext: reference returns 404. A well-formed UUID is only looked up with the change itself, so for an unknown UUID an invalid body returns 422 before the 404.
Requests with an HTTP method an endpoint does not support get a plain 405 Method Not Allowed from the web server, not the JSON error body above.
Idempotency with external_id
Monitoring systems retry notifications and sometimes send the same alert twice. Give each problem a stable external_id from your system (1–255 characters, for example checkmk:web01:HTTP) and FoundersDeck will not open duplicates. A longer external_id in a request body is rejected with 422 validation_failed; the checkmk:<host>:<service> ids from the checkMK script normally stay well under that limit.
Incidents (POST /incidents):
- While an open (not yet resolved) incident with this
external_idexists, the request returns that incident unchanged with200 OK. Nothing is created, no email is sent, and the other fields of the (still validated) body are not applied. - If there is no open incident with this
external_id(none ever, or all resolved), a new incident is created:201 Created. A resolved incident therefore frees itsexternal_idfor the next outage. - Use
external_idon everyPOSTyour monitoring sends for the same problem, including repeats afterWARNING → CRITICALflaps.
Maintenances (POST /maintenances):
- While a maintenance with this
external_idis active (not cancelled and itsscheduled_endis not yet in the past), the request returns it unchanged with200 OK. - Once that window has ended or was cancelled, the same
external_idschedules a new maintenance:201 Created. If the previous window had ended without being cancelled, itsexternal_idis set tonullat that moment, soext:then addresses only the new maintenance; the old one stays reachable by UUID.
Addressing by external_id: every endpoint with {ref} in the path accepts either the FoundersDeck UUID or ext:<external_id>:
POST /api/v1/incidents/ext:checkmk:web01:HTTP/resolve
- For incidents,
ext:points at the open incident with thatexternal_id; if none is open, at the most recently started one. Resolving twice is therefore harmless: the second call returns the already-resolved incident. - For maintenances,
ext:points only at a maintenance that is not cancelled. A cancelled maintenance is reachable by UUID only. - Colons inside the
external_idare fine. Percent-encode characters that are not allowed in a URL path, such as spaces (%20) or slashes (%2F):ext:checkmk:db01:Filesystem%20%2Fvar. - Unknown
external_idin the path, or one longer than 255 characters:404 not_found.
Concurrent requests: if two POST requests with the same external_id arrive at the same moment, one creates the resource (201) and the other gets 409 conflict. Treat 409 as "already exists" and fetch the resource: for incidents with GET /incidents/ext:<external_id>, for maintenances with GET /maintenances/ext:<external_id>.
external_id is set on creation and cannot be changed afterwards.
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET |
/monitors |
List your monitors |
GET |
/status-pages |
List your status pages |
GET |
/incidents |
List manual incidents |
POST |
/incidents |
Open an incident (idempotent with external_id) |
GET |
/incidents/{ref} |
Get one incident with its timeline |
PATCH |
/incidents/{ref} |
Change title, severity or assignments |
POST |
/incidents/{ref}/updates |
Post a timeline update and change the status |
POST |
/incidents/{ref}/resolve |
Resolve an incident (idempotent) |
GET |
/maintenances |
List maintenances |
POST |
/maintenances |
Schedule a maintenance (idempotent with external_id) |
GET |
/maintenances/{ref} |
Get one maintenance with its assignments |
PATCH |
/maintenances/{ref} |
Change a maintenance |
POST |
/maintenances/{ref}/cancel |
Cancel a maintenance (idempotent by UUID; a retry via ext: returns 404) |
{ref} is a UUID or ext:<external_id>. Maintenance endpoints need the same plan as incidents (Pro or higher).
Unknown fields in a request body are ignored. Markdown fields (message, description) keep line breaks and are not trimmed. Duplicate entries in monitor_ids / status_page_ids are ignored.
GET /monitors
Lists the monitors of your account, newest first, with the fields you need to reference them.
curl -sS https://foundersdeck.dev/api/v1/monitors \
-H "Authorization: Bearer $FOUNDERSDECK_API_KEY"
Response 200 OK:
{
"monitors": [
{
"id": "3f6c1d2e-8a4b-4c7d-9e1f-2a3b4c5d6e7f",
"name": "Website",
"url": "https://example.org",
"type": "http"
}
]
}
type is one of http, ping, keyword, heartbeat, dns. url is null for monitor types without a URL (heartbeat).
GET /status-pages
Lists the status pages of your account, newest first.
curl -sS https://foundersdeck.dev/api/v1/status-pages \
-H "Authorization: Bearer $FOUNDERSDECK_API_KEY"
Response 200 OK:
{
"status_pages": [
{
"id": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"title": "Acme Status",
"slug": "acme"
}
]
}
The public page is at https://foundersdeck.dev/status/<slug> (or your custom domain).
GET /incidents
Lists your manual incidents, newest first. Optional query parameter status=open returns only incidents that are not resolved.
curl -sS "https://foundersdeck.dev/api/v1/incidents?status=open" \
-H "Authorization: Bearer $FOUNDERSDECK_API_KEY"
Response 200 OK:
{
"incidents": [
{
"id": "6f1c2a7e-3b9d-4c1e-9a2f-0d4b5e6f7a81",
"external_id": "checkmk:web01:HTTP",
"title": "HTTP on web01 unavailable",
"severity": "major",
"status": "investigating",
"started_at": "2026-10-26T09:14:03.512Z",
"resolved_at": null,
"url": "https://foundersdeck.dev/dashboard/incidents/manual/6f1c2a7e-3b9d-4c1e-9a2f-0d4b5e6f7a81"
}
]
}
List items do not include assignments or the timeline; fetch a single incident for those. Any other status value returns 422.
POST /incidents
Opens a manual incident, shows it on the assigned status pages and emails their subscribers.
Request body:
| Field | Type | Required | Rules |
|---|---|---|---|
title |
string | yes | 1–200 characters after trimming |
severity |
string | yes | minor, major or critical |
status |
string | no | investigating (default), identified or monitoring. resolved is not allowed here |
message |
string | no | Markdown, max. 5000 characters. Becomes the first timeline update |
monitor_ids |
string[] | no* | Monitor UUIDs of your account. Default [] |
status_page_ids |
string[] | no* | Status page UUIDs of your account. Default [] |
external_id |
string | no | 1–255 characters, see Idempotency |
related_incident_id |
string | null | no | UUID of one of your automatic incidents to link this one to. An automatic incident can be linked to only one manual incident |
* At least one entry in monitor_ids or status_page_ids is required.
curl -sS -X POST https://foundersdeck.dev/api/v1/incidents \
-H "Authorization: Bearer $FOUNDERSDECK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "HTTP on web01 unavailable",
"severity": "major",
"message": "We are investigating failed requests to the web frontend.",
"status_page_ids": ["9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d"],
"external_id": "checkmk:web01:HTTP"
}'
Response 201 Created (new incident) or 200 OK (an open incident with this external_id already existed and is returned unchanged):
{
"id": "6f1c2a7e-3b9d-4c1e-9a2f-0d4b5e6f7a81",
"external_id": "checkmk:web01:HTTP",
"title": "HTTP on web01 unavailable",
"severity": "major",
"status": "investigating",
"started_at": "2026-10-26T09:14:03.512Z",
"resolved_at": null,
"monitor_ids": [],
"status_page_ids": ["9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d"],
"updates": [
{
"id": "c2d3e4f5-a6b7-4c8d-9e0f-1a2b3c4d5e6f",
"status": "investigating",
"message": "We are investigating failed requests to the web frontend.",
"created_at": "2026-10-26T09:14:03.512Z"
}
],
"url": "https://foundersdeck.dev/dashboard/incidents/manual/6f1c2a7e-3b9d-4c1e-9a2f-0d4b5e6f7a81"
}
This is the full incident resource, returned by every single-incident endpoint. updates is the timeline in chronological order (oldest first); it is empty when the incident was opened without message. url links to the incident in the dashboard.
GET /incidents/{ref}
Returns one incident with its assignments and timeline.
curl -sS https://foundersdeck.dev/api/v1/incidents/ext:checkmk:web01:HTTP \
-H "Authorization: Bearer $FOUNDERSDECK_API_KEY"
Response 200 OK: the full incident resource (see POST /incidents).
PATCH /incidents/{ref}
Changes title, severity or assignments. Send only the fields you want to change; at least one is required. This does not post a timeline update and sends no emails. To change the status, use /updates or /resolve.
| Field | Type | Rules |
|---|---|---|
title |
string | 1–200 characters after trimming |
severity |
string | minor, major or critical |
monitor_ids |
string[] | Replaces all monitor assignments |
status_page_ids |
string[] | Replaces all status page assignments |
After the change, the incident must still have at least one monitor or status page.
curl -sS -X PATCH https://foundersdeck.dev/api/v1/incidents/ext:checkmk:web01:HTTP \
-H "Authorization: Bearer $FOUNDERSDECK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"severity": "critical"}'
Response 200 OK: the full incident resource.
POST /incidents/{ref}/updates
Adds an update to the timeline, sets the incident's status and emails the subscribers of the assigned status pages.
| Field | Type | Required | Rules |
|---|---|---|---|
status |
string | yes | investigating, identified, monitoring or resolved |
message |
string | yes | Markdown, 1–5000 characters, not only whitespace |
status: "resolved" resolves the incident (sets resolved_at). If the incident is already resolved, a resolved update is ignored: no new update, no email, the incident is returned unchanged. Any other status on a resolved incident returns 409 conflict: a resolved incident is not reopened. For a new outage after a resolve, open a new incident.
An update with the same status and message as the incident's latest update is a no-op: 200 OK with the incident unchanged, no new update and no email. Retrying a request is therefore safe.
curl -sS -X POST https://foundersdeck.dev/api/v1/incidents/ext:checkmk:web01:HTTP/updates \
-H "Authorization: Bearer $FOUNDERSDECK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "identified", "message": "A failed deployment caused the errors. Rolling back."}'
Response 200 OK: the full incident resource including the new update.
POST /incidents/{ref}/resolve
Resolves the incident. Shortcut for an update with status: "resolved".
| Field | Type | Required | Rules |
|---|---|---|---|
message |
string | no | Markdown, max. 5000 characters. Default Resolved. |
The body may be empty. Resolving an already-resolved incident changes nothing and returns 200 with the incident, so retries are safe.
curl -sS -X POST https://foundersdeck.dev/api/v1/incidents/ext:checkmk:web01:HTTP/resolve \
-H "Authorization: Bearer $FOUNDERSDECK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"message": "Service recovered."}'
Response 200 OK: the full incident resource with status: "resolved" and resolved_at set.
GET /maintenances
Lists your maintenances, latest scheduled_start first, including past and cancelled ones.
curl -sS https://foundersdeck.dev/api/v1/maintenances \
-H "Authorization: Bearer $FOUNDERSDECK_API_KEY"
Response 200 OK:
{
"maintenances": [
{
"id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"external_id": "change-4711",
"title": "Database upgrade",
"description": "PostgreSQL minor upgrade. Expect up to 5 minutes of downtime.",
"scheduled_start": "2026-11-02T21:00:00.000Z",
"scheduled_end": "2026-11-02T22:00:00.000Z",
"suppress_alerts": true,
"cancelled_at": null,
"cancellation_message": null,
"url": "https://foundersdeck.dev/dashboard/maintenance/1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
}
]
}
List items do not include assignments; GET /maintenances/{ref}, PATCH and cancel return the full resource with monitor_ids and status_page_ids.
POST /maintenances
Schedules a maintenance window, shows it on the assigned status pages and emails their subscribers.
| Field | Type | Required | Rules |
|---|---|---|---|
title |
string | yes | 1–200 characters after trimming |
description |
string | yes | Markdown, 1–5000 characters, not only whitespace |
scheduled_start |
string | yes | ISO 8601 date-time with seconds and a time zone, e.g. 2026-11-02T22:00:00+01:00 or 2026-11-02T21:00:00Z |
scheduled_end |
string | yes | Same format, must be after scheduled_start |
suppress_alerts |
boolean | no | Default true: no alerts for the assigned monitors during the window |
monitor_ids |
string[] | no* | Monitor UUIDs of your account. Default [] |
status_page_ids |
string[] | no* | Status page UUIDs of your account. Default [] |
external_id |
string | no | 1–255 characters, see Idempotency |
* At least one entry in monitor_ids or status_page_ids is required.
curl -sS -X POST https://foundersdeck.dev/api/v1/maintenances \
-H "Authorization: Bearer $FOUNDERSDECK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Database upgrade",
"description": "PostgreSQL minor upgrade. Expect up to 5 minutes of downtime.",
"scheduled_start": "2026-11-02T22:00:00+01:00",
"scheduled_end": "2026-11-02T23:00:00+01:00",
"monitor_ids": ["3f6c1d2e-8a4b-4c7d-9e1f-2a3b4c5d6e7f"],
"status_page_ids": ["9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d"],
"external_id": "change-4711"
}'
Response 201 Created (new maintenance) or 200 OK (an active maintenance with this external_id already existed and is returned unchanged):
{
"id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"external_id": "change-4711",
"title": "Database upgrade",
"description": "PostgreSQL minor upgrade. Expect up to 5 minutes of downtime.",
"scheduled_start": "2026-11-02T21:00:00.000Z",
"scheduled_end": "2026-11-02T22:00:00.000Z",
"suppress_alerts": true,
"cancelled_at": null,
"cancellation_message": null,
"monitor_ids": ["3f6c1d2e-8a4b-4c7d-9e1f-2a3b4c5d6e7f"],
"status_page_ids": ["9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d"],
"url": "https://foundersdeck.dev/dashboard/maintenance/1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
}
Times are always returned in UTC.
GET /maintenances/{ref}
Returns one maintenance with its assignments. As everywhere, ext: only finds a maintenance that is not cancelled.
curl -sS https://foundersdeck.dev/api/v1/maintenances/ext:change-4711 \
-H "Authorization: Bearer $FOUNDERSDECK_API_KEY"
Response 200 OK: the full maintenance resource (see POST /maintenances).
PATCH /maintenances/{ref}
Changes a maintenance. Send only the fields you want to change; at least one is required. Sends no emails.
| Field | Type | Rules |
|---|---|---|
title |
string | 1–200 characters after trimming |
description |
string | Markdown, 1–5000 characters, not only whitespace |
scheduled_start |
string | ISO 8601 date-time with seconds and a time zone |
scheduled_end |
string | ISO 8601 date-time with seconds and a time zone |
suppress_alerts |
boolean | |
monitor_ids |
string[] | Replaces all monitor assignments |
status_page_ids |
string[] | Replaces all status page assignments |
The resulting window must end after it starts (checked against the stored values if you send only one end), and the maintenance must keep at least one monitor or status page. external_id cannot be changed.
curl -sS -X PATCH https://foundersdeck.dev/api/v1/maintenances/ext:change-4711 \
-H "Authorization: Bearer $FOUNDERSDECK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"scheduled_end": "2026-11-02T23:30:00+01:00"}'
Response 200 OK: the full maintenance resource (see POST /maintenances).
POST /maintenances/{ref}/cancel
Cancels a maintenance and emails the subscribers of the assigned status pages.
| Field | Type | Required | Rules |
|---|---|---|---|
message |
string | no | Markdown, max. 5000 characters. Stored as cancellation_message |
The body may be empty. Cancelling an already-cancelled maintenance by UUID changes nothing and returns 200 with it. Retrying a cancel via ext:<external_id> returns 404 not_found, because a cancelled maintenance is only addressable by UUID. For safe retries, take the id from the first response and retry with that UUID.
curl -sS -X POST https://foundersdeck.dev/api/v1/maintenances/ext:change-4711/cancel \
-H "Authorization: Bearer $FOUNDERSDECK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"message": "Postponed to next week."}'
Response 200 OK: the full maintenance resource with cancelled_at set.
Example: checkMK notification script
This script turns checkMK notifications into FoundersDeck incidents: CRITICAL/DOWN opens an incident on your status page, OK/UP resolves it. The external_id checkmk:<host>:<service> makes repeated notifications for the same problem harmless. WARNING, UNKNOWN and other states are ignored.
Requirements on the checkMK server: bash, curl (7.76 or newer, for --fail-with-body) and jq. A failed API call exits non-zero and its error body shows up in checkMK's notification log. On OK/UP, a 404 counts as success: there is no incident to resolve, for example after a recovery from WARNING, which never opened one. Title and message are cut to the API limits (200 and 5000 characters) so a long plugin output cannot fail the call.
#!/usr/bin/env bash
# FoundersDeck notification script for checkMK (place in ~/local/share/check_mk/notifications/)
set -euo pipefail
API="https://foundersdeck.dev/api/v1"
KEY="${FOUNDERSDECK_API_KEY:?set FOUNDERSDECK_API_KEY}"
STATUS_PAGE_ID="${FOUNDERSDECK_STATUS_PAGE_ID:?set FOUNDERSDECK_STATUS_PAGE_ID}"
HOST="${NOTIFY_HOSTNAME}"
SERVICE="${NOTIFY_SERVICEDESC:-host}"
STATE="${NOTIFY_SERVICESTATE:-$NOTIFY_HOSTSTATE}"
EXT_ID="checkmk:${HOST}:${SERVICE}"
AUTH=(-H "Authorization: Bearer ${KEY}" -H "Content-Type: application/json")
case "$STATE" in
CRITICAL|DOWN)
curl -sS --fail-with-body -X POST "${API}/incidents" "${AUTH[@]}" -d "$(jq -n \
--arg t "${SERVICE} on ${HOST} unavailable" --arg e "$EXT_ID" --arg sp "$STATUS_PAGE_ID" \
--arg m "${NOTIFY_SERVICEOUTPUT:-$NOTIFY_HOSTOUTPUT}" \
'{title:($t|.[0:200]), severity:"major", message:($m|.[0:5000]), status_page_ids:[$sp], external_id:$e}')" ;;
OK|UP)
# Service names may contain spaces or slashes (e.g. "Filesystem /var"): percent-encode the id for the URL path.
EXT_ID_ENC=$(jq -rn --arg s "$EXT_ID" '$s|@uri')
RESP=$(curl -sS -w '\n%{http_code}' -X POST "${API}/incidents/ext:${EXT_ID_ENC}/resolve" "${AUTH[@]}" \
-d '{"message":"Service recovered."}')
CODE="${RESP##*$'\n'}"
# 404 = no incident with this id (e.g. recovery after a WARNING that never opened one): nothing to resolve.
case "$CODE" in
200|404) exit 0 ;;
*) printf '%s\n' "${RESP%$'\n'*}" >&2; exit 1 ;;
esac ;;
*) exit 0 ;;
esac
Setup:
- Create an API key under Settings → API keys and look up your status page ID with
GET /status-pages. - Save the script as
~/local/share/check_mk/notifications/foundersdeckin your checkMK site and make it executable (chmod +x). - Make
FOUNDERSDECK_API_KEYandFOUNDERSDECK_STATUS_PAGE_IDavailable to the site's notification process, for example in the site's~/etc/environment. - Create a notification rule in checkMK that uses the script for the hosts and services that should appear on your status page.
The resolve URL percent-encodes the external_id (jq ... '@uri') because it goes into the URL path; the POST /incidents body sends it as plain JSON.
Changelog
- v1 — 2026-10: initial release.