Introduction
REST API for status pages: incidents, maintenance, components, subscribers, metrics and more — for CI/CD pipelines, monitoring alerts and your own tools.
Everything you can do with your status page in the dashboard, a pipeline or a monitoring tool can do here: open an incident when a deployment fails, set a component's status from an alert, post an update, resolve it — subscribers are notified exactly as when you do it by hand.
## Conventions
- **Base URL** `https://statuswerk.eu/api/v1`, JSON in and out (`Accept: application/json`).
- **Which status page:** every endpoint below works on one status page. With several, send `X-Statuspage-Id: <id>`; without it the request goes to your workspace's oldest status page. `GET /statuspages` lists them.
- **Language:** the API always answers in English — error messages, labels and pagination, whatever `Accept-Language` you send. Texts you send are published as you write them; the frame around them on the page and in notifications (subjects, labels, dates) follows the page's `language`.
- **Lists** are paginated: `per_page` (default 20, at most 100) and `page`; the response carries `meta` and `links`.
## Errors
| Status | `error` | Meaning |
|---|---|---|
| 401 | | No or invalid token. |
| 403 | `Forbidden` | Your plan has no API access, or only read access (the Starter plan); the token is read-only; it is bound to another workspace; or the endpoint's feature is not in your plan. The `message` says which. |
| 404 | | The record does not exist on this status page. |
| 422 | | Validation failed; `errors` lists the fields. |
| 422 | `quota_exceeded` | A plan limit is reached (incidents per month, components, subscribers, …). |
| 429 | | Too many requests: 120 per minute per token; calls that test, verify or send a confirmation 10 per minute. |
Authenticating requests
To authenticate requests, include an Authorization header with the value "Bearer {YOUR_AUTH_KEY}".
All authenticated endpoints are marked with a requires authentication badge in the documentation below.
Create a token in the dashboard under Account → API Tokens and send it as Authorization: Bearer YOUR_TOKEN. A token belongs to one workspace — no workspace header needed — and is either read-only or read & write. Writing also needs a plan with API write access; on the Starter plan the API is read-only.
Audit log
Every change made in the workspace, by whom and from where — read-only, as in the dashboard. Subscribers are never named and secrets are redacted. Pro sees the last 30 days, Business the whole year kept (365 days); other plans get 403.
List audit entries
requires authentication
Newest first, for the whole workspace (each entry names its statuspage_id), within the plan's window — since does not reach past it. A change lists each field as {from, to} (entries before 12 November 2026 have to only); a secret or personal field is {redacted: true}, before and after.
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/audit-log?action=updated&actor_type=api_token&since=2026-10-01T00%3A00%3A00Z&until=2026-10-31T23%3A59%3A59Z&statuspage_id=01a1c639-3aa8-70ef-8655-b6f3d56e786b&subject_type=Incident&per_page=50" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/audit-log"
);
const params = {
"action": "updated",
"actor_type": "api_token",
"since": "2026-10-01T00:00:00Z",
"until": "2026-10-31T23:59:59Z",
"statuspage_id": "01a1c639-3aa8-70ef-8655-b6f3d56e786b",
"subject_type": "Incident",
"per_page": "50",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Component groups
Groups that bundle components on the page. Creating needs a plan with component groups (403 otherwise); existing groups can be read, changed, reordered and deleted on every plan.
Reorder component groups
requires authentication
Send groups as a list of {id, position}; lower positions come first. Ids of other pages are ignored.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/component-groups/reorder" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"groups\": [
{
\"id\": \"6ff8f7f6-1eb3-3525-be4a-3932c805afed\",
\"position\": 84
}
]
}"
const url = new URL(
"https://statuswerk.eu/api/v1/component-groups/reorder"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"groups": [
{
"id": "6ff8f7f6-1eb3-3525-be4a-3932c805afed",
"position": 84
}
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List component groups
requires authentication
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/component-groups" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/component-groups"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create a component group
requires authentication
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/component-groups" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"b\",
\"description\": \"Et animi quos velit et fugiat.\",
\"position\": 42,
\"collapsed_by_default\": false,
\"visible\": false
}"
const url = new URL(
"https://statuswerk.eu/api/v1/component-groups"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "b",
"description": "Et animi quos velit et fugiat.",
"position": 42,
"collapsed_by_default": false,
"visible": false
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"data": {
"id": "01a1544c-7c05-70fc-9b8d-e46b1a39c2a3",
"name": "Payments",
"description": null,
"position": 1,
"collapsed_by_default": null,
"visible": null,
"overall_status": "operational",
"components": [],
"created_at": "2026-10-19T08:30:00+00:00",
"updated_at": "2026-10-19T08:30:00+00:00"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get a component group
requires authentication
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/component-groups/01a1f3c2-6a01-7b10-9c20-3d4e5f6a7b80" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/component-groups/01a1f3c2-6a01-7b10-9c20-3d4e5f6a7b80"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update a component group
requires authentication
Example request:
curl --request PUT \
"https://statuswerk.eu/api/v1/component-groups/01a1f3c2-6a01-7b10-9c20-3d4e5f6a7b80" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"b\",
\"description\": \"Et animi quos velit et fugiat.\",
\"position\": 42,
\"collapsed_by_default\": false,
\"visible\": true
}"
const url = new URL(
"https://statuswerk.eu/api/v1/component-groups/01a1f3c2-6a01-7b10-9c20-3d4e5f6a7b80"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "b",
"description": "Et animi quos velit et fugiat.",
"position": 42,
"collapsed_by_default": false,
"visible": true
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete a component group
requires authentication
Its components stay, ungrouped.
Example request:
curl --request DELETE \
"https://statuswerk.eu/api/v1/component-groups/01a1f3c2-6a01-7b10-9c20-3d4e5f6a7b80" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/component-groups/01a1f3c2-6a01-7b10-9c20-3d4e5f6a7b80"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Components
The parts of your service a status page shows — API, website, payments — each with its current status.
List components
requires authentication
All components of the status page, in their display order.
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/components" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/components"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": "01a1bb24-fdc6-731a-9f22-b7e1198b2414",
"name": "Checkout API",
"description": "Payments and orders",
"status": "operational",
"status_label": "Operational",
"group_id": "01a1bb24-fdc3-7139-9cd9-6b02e7859302",
"group": {
"id": "01a1bb24-fdc3-7139-9cd9-6b02e7859302",
"name": "Payments"
},
"position": 1,
"show_uptime": true,
"uptime_start_date": null,
"uptime_90d": 100,
"visible": true,
"created_at": "2026-10-19T08:30:00+00:00",
"updated_at": "2026-10-19T08:30:00+00:00"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create a component
requires authentication
Over the plan's component limit: 422 with error: quota_exceeded.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/components" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"b\",
\"description\": \"Et animi quos velit et fugiat.\",
\"group_id\": \"5707ca55-f609-3528-be8b-1baeaee1567e\",
\"status\": \"degraded_performance\",
\"position\": 9,
\"show_uptime\": true,
\"uptime_start_date\": \"2022-12-07\",
\"visible\": true
}"
const url = new URL(
"https://statuswerk.eu/api/v1/components"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "b",
"description": "Et animi quos velit et fugiat.",
"group_id": "5707ca55-f609-3528-be8b-1baeaee1567e",
"status": "degraded_performance",
"position": 9,
"show_uptime": true,
"uptime_start_date": "2022-12-07",
"visible": true
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"data": {
"id": "01a1bb24-fdc6-731a-9f22-b7e1198b2414",
"name": "Checkout API",
"description": "Payments and orders",
"status": "operational",
"status_label": "Operational",
"group_id": "01a1bb24-fdc3-7139-9cd9-6b02e7859302",
"group": {
"id": "01a1bb24-fdc3-7139-9cd9-6b02e7859302",
"name": "Payments"
},
"position": 1,
"show_uptime": null,
"uptime_start_date": null,
"uptime_90d": null,
"visible": null,
"created_at": "2026-10-19T08:30:00+00:00",
"updated_at": "2026-10-19T08:30:00+00:00"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get a component
requires authentication
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/components/01a1f3c2-6b11-7c20-8d41-6a2e9f0c3d11" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/components/01a1f3c2-6b11-7c20-8d41-6a2e9f0c3d11"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": {
"id": "01a1bb24-fdc6-731a-9f22-b7e1198b2414",
"name": "Checkout API",
"description": "Payments and orders",
"status": "operational",
"status_label": "Operational",
"group_id": "01a1bb24-fdc3-7139-9cd9-6b02e7859302",
"group": {
"id": "01a1bb24-fdc3-7139-9cd9-6b02e7859302",
"name": "Payments"
},
"position": 1,
"show_uptime": true,
"uptime_start_date": null,
"uptime_90d": 100,
"visible": true,
"created_at": "2026-10-19T08:30:00+00:00",
"updated_at": "2026-10-19T08:30:00+00:00"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update a component
requires authentication
Example request:
curl --request PUT \
"https://statuswerk.eu/api/v1/components/01a1f3c2-6b11-7c20-8d41-6a2e9f0c3d11" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"b\",
\"description\": \"Et animi quos velit et fugiat.\",
\"group_id\": \"5707ca55-f609-3528-be8b-1baeaee1567e\",
\"status\": \"maintenance\",
\"position\": 9,
\"show_uptime\": false,
\"uptime_start_date\": \"2022-12-07\",
\"visible\": true
}"
const url = new URL(
"https://statuswerk.eu/api/v1/components/01a1f3c2-6b11-7c20-8d41-6a2e9f0c3d11"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "b",
"description": "Et animi quos velit et fugiat.",
"group_id": "5707ca55-f609-3528-be8b-1baeaee1567e",
"status": "maintenance",
"position": 9,
"show_uptime": false,
"uptime_start_date": "2022-12-07",
"visible": true
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete a component
requires authentication
Example request:
curl --request DELETE \
"https://statuswerk.eu/api/v1/components/01a1f3c2-6b11-7c20-8d41-6a2e9f0c3d11" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/components/01a1f3c2-6b11-7c20-8d41-6a2e9f0c3d11"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Set a component's status
requires authentication
For monitoring alerts and pipelines: sets the status directly, without an incident, and records it in the component's history. To tell subscribers, open an incident instead.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/components/01a1f3c2-6b11-7c20-8d41-6a2e9f0c3d11/status" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"status\": \"partial_outage\"
}"
const url = new URL(
"https://statuswerk.eu/api/v1/components/01a1f3c2-6b11-7c20-8d41-6a2e9f0c3d11/status"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"status": "partial_outage"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"data": {
"id": "01a1bb24-fdc6-731a-9f22-b7e1198b2414",
"name": "Checkout API",
"description": "Payments and orders",
"status": "degraded_performance",
"status_label": "Degraded Performance",
"group_id": "01a1bb24-fdc3-7139-9cd9-6b02e7859302",
"group": {
"id": "01a1bb24-fdc3-7139-9cd9-6b02e7859302",
"name": "Payments"
},
"position": 1,
"show_uptime": true,
"uptime_start_date": null,
"uptime_90d": 100,
"visible": true,
"created_at": "2026-10-19T08:30:00+00:00",
"updated_at": "2026-10-19T08:30:00+00:00"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Reorder components
requires authentication
Send components as a list of {id, position}; lower positions come first. Ids of other pages are ignored.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/components/reorder" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"components\": [
{
\"id\": \"6ff8f7f6-1eb3-3525-be4a-3932c805afed\",
\"position\": 84
}
]
}"
const url = new URL(
"https://statuswerk.eu/api/v1/components/reorder"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"components": [
{
"id": "6ff8f7f6-1eb3-3525-be4a-3932c805afed",
"position": 84
}
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Custom domain
Serve a status page on your own domain. Needs a plan with custom domains (403 otherwise).
Manage the (single) custom domain of a statuspage.
Custom domains are inherently asynchronous: after the domain is set, the
customer points a CNAME at cname_target and adds the TXT record from
verification_record (proof of ownership — without it the domain is not
verified), a scheduled job verifies DNS, and Caddy provisions the certificate on
demand. A domain still unverified 30 days after it was set is released again. This controller is a thin state
layer over that existing machinery (StatuspageDomainSyncObserver +
VerifyCustomDomain* jobs). Clients poll show until status is active.
Get the custom domain
requires authentication
status goes from pending_dns to dns_verified to active (or dns_error). verification_record is the TXT record that proves the domain is yours; it is required, alongside the CNAME to cname_target. Poll until active. 404 when none is set.
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/statuspages/01a1f3c2-5c00-7a10-8b20-1c2d3e4f5a6b/custom-domain" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/statuspages/01a1f3c2-5c00-7a10-8b20-1c2d3e4f5a6b/custom-domain"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Set the custom domain
requires authentication
Accepted with 202: create the CNAME and the TXT record from verification_record, then the domain is verified on its own (or call verify). A domain unverified for 30 days is released. 422 with error: domain_reserved for our own domains, domain_taken when another page uses it.
Example request:
curl --request PUT \
"https://statuswerk.eu/api/v1/statuspages/01a1f3c2-5c00-7a10-8b20-1c2d3e4f5a6b/custom-domain" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"domain\": \"b\"
}"
const url = new URL(
"https://statuswerk.eu/api/v1/statuspages/01a1f3c2-5c00-7a10-8b20-1c2d3e4f5a6b/custom-domain"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"domain": "b"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Check the DNS now
requires authentication
Queues the next check due instead of waiting for the scheduled one: DNS until it is verified, then the SSL certificate. Limited to 10 per minute.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/statuspages/01a1f3c2-5c00-7a10-8b20-1c2d3e4f5a6b/custom-domain/verify" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/statuspages/01a1f3c2-5c00-7a10-8b20-1c2d3e4f5a6b/custom-domain/verify"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Remove the custom domain
requires authentication
The page is served on its statuswerk.eu address again. Works on every plan, also after a downgrade.
Example request:
curl --request DELETE \
"https://statuswerk.eu/api/v1/statuspages/01a1f3c2-5c00-7a10-8b20-1c2d3e4f5a6b/custom-domain" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/statuspages/01a1f3c2-5c00-7a10-8b20-1c2d3e4f5a6b/custom-domain"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Incidents
Report disruptions. Creating, updating and resolving an incident has the same consequences as in the dashboard: its components show the outage, the timeline records each step, subscribers and chat channels are notified. On a page with four-eyes approval a new incident is held until a second person approves it in the dashboard.
List incidents
requires authentication
Newest first.
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/incidents?status=investigating&active=1&resolved=&per_page=20" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/incidents"
);
const params = {
"status": "investigating",
"active": "1",
"resolved": "0",
"per_page": "20",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": "01a1bb06-ac42-72a7-af4d-7bf1db7bb967",
"title": "Checkout API unavailable",
"slug": "checkout-api-unavailable",
"public_url": "https://acme.statuswerk.eu/incidents/checkout-api-unavailable",
"message": "We are investigating failed payments.",
"status": "identified",
"status_label": "Identified",
"severity": "major",
"severity_label": "Major",
"impact": null,
"visible": true,
"is_published": true,
"is_awaiting_approval": false,
"approval_state": null,
"approval_note": null,
"is_unlisted": false,
"excluded_from_uptime": false,
"stickied": false,
"notify_subscribers": true,
"occurred_at": "2026-10-19T08:30:00+00:00",
"resolved_at": null,
"duration_minutes": null,
"is_resolved": false,
"components": [
{
"id": "01a1bb06-ac3a-73d9-bdeb-b86ecd87c763",
"name": "Checkout API",
"status": null
}
],
"updates": [
{
"id": "01a1bb06-ac4b-714f-a2d1-f6630666fb42",
"incident_id": "01a1bb06-ac42-72a7-af4d-7bf1db7bb967",
"status": "identified",
"status_label": "Identified",
"message": "A certificate expired at our payment provider. We are rolling out a new one.",
"notify_subscribers": true,
"created_at": "2026-10-19T08:45:00+00:00",
"updated_at": "2026-10-19T08:45:00+00:00"
},
{
"id": "01a1bb06-ac46-7344-8e3c-1f5dabca8d6b",
"incident_id": "01a1bb06-ac42-72a7-af4d-7bf1db7bb967",
"status": "investigating",
"status_label": "Investigating",
"message": "We are investigating failed payments.",
"notify_subscribers": true,
"created_at": "2026-10-19T08:30:00+00:00",
"updated_at": "2026-10-19T08:30:00+00:00"
}
],
"created_at": "2026-10-19T08:30:00+00:00",
"updated_at": "2026-10-19T08:45:00+00:00"
}
],
"links": {
"first": "https://statuswerk.eu/api/v1/incidents?page=1",
"last": "https://statuswerk.eu/api/v1/incidents?page=1",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"links": [
{
"url": null,
"label": "« Previous",
"page": null,
"active": false
},
{
"url": "https://statuswerk.eu/api/v1/incidents?page=1",
"label": "1",
"page": 1,
"active": true
},
{
"url": null,
"label": "Next »",
"page": null,
"active": false
}
],
"path": "https://statuswerk.eu/api/v1/incidents",
"per_page": 20,
"to": 1,
"total": 1
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Open an incident
requires authentication
Without a status per component, each takes the status the severity implies (minor → partial outage, major and critical → major outage). Over the monthly incident limit: 422 with error: quota_exceeded. Held for four-eyes approval, the response says so in message and is_awaiting_approval; nothing is published or sent until it is approved.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/incidents" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"title\": \"Checkout API unavailable\",
\"message\": \"We are investigating failed payments.\",
\"status\": \"investigating\",
\"severity\": \"major\",
\"impact\": \"b\",
\"visible\": true,
\"is_unlisted\": false,
\"excluded_from_uptime\": false,
\"stickied\": false,
\"notify_subscribers\": true,
\"occurred_at\": \"2026-10-19T08:30:00+02:00\",
\"resolved_at\": \"2026-10-19T09:10:00+02:00\",
\"components\": [
{
\"id\": \"01a1f3c2-6b11-7c20-8d41-6a2e9f0c3d11\",
\"status\": \"major_outage\"
}
]
}"
const url = new URL(
"https://statuswerk.eu/api/v1/incidents"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"title": "Checkout API unavailable",
"message": "We are investigating failed payments.",
"status": "investigating",
"severity": "major",
"impact": "b",
"visible": true,
"is_unlisted": false,
"excluded_from_uptime": false,
"stickied": false,
"notify_subscribers": true,
"occurred_at": "2026-10-19T08:30:00+02:00",
"resolved_at": "2026-10-19T09:10:00+02:00",
"components": [
{
"id": "01a1f3c2-6b11-7c20-8d41-6a2e9f0c3d11",
"status": "major_outage"
}
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"data": {
"id": "01a1bb06-ac42-72a7-af4d-7bf1db7bb967",
"title": "Checkout API unavailable",
"slug": "checkout-api-unavailable",
"public_url": "https://acme.statuswerk.eu/incidents/checkout-api-unavailable",
"message": "We are investigating failed payments.",
"status": "investigating",
"status_label": "Investigating",
"severity": "major",
"severity_label": "Major",
"impact": null,
"visible": true,
"is_published": true,
"is_awaiting_approval": false,
"approval_state": null,
"approval_note": null,
"is_unlisted": false,
"excluded_from_uptime": false,
"stickied": false,
"notify_subscribers": true,
"occurred_at": "2026-10-19T08:30:00+00:00",
"resolved_at": null,
"duration_minutes": null,
"is_resolved": false,
"components": [
{
"id": "01a1bb06-ac3a-73d9-bdeb-b86ecd87c763",
"name": "Checkout API",
"status": null
}
],
"updates": [
{
"id": "01a1bb06-ac46-7344-8e3c-1f5dabca8d6b",
"incident_id": "01a1bb06-ac42-72a7-af4d-7bf1db7bb967",
"status": "investigating",
"status_label": "Investigating",
"message": "We are investigating failed payments.",
"notify_subscribers": true,
"created_at": "2026-10-19T08:30:00+00:00",
"updated_at": "2026-10-19T08:30:00+00:00"
}
],
"created_at": "2026-10-19T08:30:00+00:00",
"updated_at": "2026-10-19T08:30:00+00:00"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get an incident
requires authentication
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/incidents/01a1f3c2-7d0e-7a51-9c3b-2f6e8d4a1b90" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/incidents/01a1f3c2-7d0e-7a51-9c3b-2f6e8d4a1b90"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": {
"id": "01a1bb06-ac42-72a7-af4d-7bf1db7bb967",
"title": "Checkout API unavailable",
"slug": "checkout-api-unavailable",
"public_url": "https://acme.statuswerk.eu/incidents/checkout-api-unavailable",
"message": "We are investigating failed payments.",
"status": "identified",
"status_label": "Identified",
"severity": "major",
"severity_label": "Major",
"impact": null,
"visible": true,
"is_published": true,
"is_awaiting_approval": false,
"approval_state": null,
"approval_note": null,
"is_unlisted": false,
"excluded_from_uptime": false,
"stickied": false,
"notify_subscribers": true,
"occurred_at": "2026-10-19T08:30:00+00:00",
"resolved_at": null,
"duration_minutes": null,
"is_resolved": false,
"components": [
{
"id": "01a1bb06-ac3a-73d9-bdeb-b86ecd87c763",
"name": "Checkout API",
"status": null
}
],
"updates": [
{
"id": "01a1bb06-ac4b-714f-a2d1-f6630666fb42",
"incident_id": "01a1bb06-ac42-72a7-af4d-7bf1db7bb967",
"status": "identified",
"status_label": "Identified",
"message": "A certificate expired at our payment provider. We are rolling out a new one.",
"notify_subscribers": true,
"created_at": "2026-10-19T08:45:00+00:00",
"updated_at": "2026-10-19T08:45:00+00:00"
},
{
"id": "01a1bb06-ac46-7344-8e3c-1f5dabca8d6b",
"incident_id": "01a1bb06-ac42-72a7-af4d-7bf1db7bb967",
"status": "investigating",
"status_label": "Investigating",
"message": "We are investigating failed payments.",
"notify_subscribers": true,
"created_at": "2026-10-19T08:30:00+00:00",
"updated_at": "2026-10-19T08:30:00+00:00"
}
],
"created_at": "2026-10-19T08:30:00+00:00",
"updated_at": "2026-10-19T08:45:00+00:00"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update an incident
requires authentication
A changed status is recorded on the timeline, a changed severity moves the components, added and removed components follow. Setting status to resolved resolves it as resolve does.
Example request:
curl --request PUT \
"https://statuswerk.eu/api/v1/incidents/01a1f3c2-7d0e-7a51-9c3b-2f6e8d4a1b90" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"title\": \"b\",
\"message\": \"n\",
\"status\": \"monitoring\",
\"severity\": \"minor\",
\"impact\": \"g\",
\"visible\": true,
\"is_unlisted\": true,
\"excluded_from_uptime\": false,
\"stickied\": false,
\"notify_subscribers\": false,
\"occurred_at\": \"2026-11-12T21:59:18\",
\"resolved_at\": \"2026-11-12T21:59:18\",
\"components\": [
{
\"id\": \"c90237e9-ced5-3af6-88ea-84aeaa148878\",
\"status\": \"partial_outage\"
}
]
}"
const url = new URL(
"https://statuswerk.eu/api/v1/incidents/01a1f3c2-7d0e-7a51-9c3b-2f6e8d4a1b90"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"title": "b",
"message": "n",
"status": "monitoring",
"severity": "minor",
"impact": "g",
"visible": true,
"is_unlisted": true,
"excluded_from_uptime": false,
"stickied": false,
"notify_subscribers": false,
"occurred_at": "2026-11-12T21:59:18",
"resolved_at": "2026-11-12T21:59:18",
"components": [
{
"id": "c90237e9-ced5-3af6-88ea-84aeaa148878",
"status": "partial_outage"
}
]
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete an incident
requires authentication
Its components return to operational unless another open incident still affects them.
Example request:
curl --request DELETE \
"https://statuswerk.eu/api/v1/incidents/01a1f3c2-7d0e-7a51-9c3b-2f6e8d4a1b90" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/incidents/01a1f3c2-7d0e-7a51-9c3b-2f6e8d4a1b90"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List an incident's updates
requires authentication
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/incidents/01a1f3c2-7d0e-7a51-9c3b-2f6e8d4a1b90/updates" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/incidents/01a1f3c2-7d0e-7a51-9c3b-2f6e8d4a1b90/updates"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Post an incident update
requires authentication
Adds a step to the timeline and moves the incident to its status; subscribers are notified unless notify_subscribers is false. resolved resolves the incident and returns its components. On an incident still awaiting approval the update is kept but sent to nobody.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/incidents/01a1f3c2-7d0e-7a51-9c3b-2f6e8d4a1b90/updates" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"status\": \"identified\",
\"message\": \"A failing database migration; rolling back.\",
\"notify_subscribers\": true,
\"created_at\": \"2022-12-07\"
}"
const url = new URL(
"https://statuswerk.eu/api/v1/incidents/01a1f3c2-7d0e-7a51-9c3b-2f6e8d4a1b90/updates"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"status": "identified",
"message": "A failing database migration; rolling back.",
"notify_subscribers": true,
"created_at": "2022-12-07"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"data": {
"id": "01a1544c-7c1d-7350-9874-aba971bbbc78",
"incident_id": "01a1544c-7c0f-7068-b8a5-30af62ccecd5",
"status": "identified",
"status_label": "Identified",
"message": "A certificate expired at our payment provider. We are rolling out a new one.",
"notify_subscribers": true,
"created_at": "2026-10-19T08:45:00+00:00",
"updated_at": "2026-10-19T08:45:00+00:00"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Correct an incident update
requires authentication
Fixes the text or the time of an update already posted. Nobody is notified again — a correction is not news.
Example request:
curl --request PATCH \
"https://statuswerk.eu/api/v1/incidents/01a1f3c2-7d0e-7a51-9c3b-2f6e8d4a1b90/updates/01a1f3c2-7d10-7f02-a9b4-0c1d2e3f4a5b" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"message\": \"b\",
\"created_at\": \"2022-12-07\"
}"
const url = new URL(
"https://statuswerk.eu/api/v1/incidents/01a1f3c2-7d0e-7a51-9c3b-2f6e8d4a1b90/updates/01a1f3c2-7d10-7f02-a9b4-0c1d2e3f4a5b"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"message": "b",
"created_at": "2022-12-07"
};
fetch(url, {
method: "PATCH",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete an incident update
requires authentication
Removes the step from the timeline. The incident keeps its current status.
Example request:
curl --request DELETE \
"https://statuswerk.eu/api/v1/incidents/01a1f3c2-7d0e-7a51-9c3b-2f6e8d4a1b90/updates/01a1f3c2-7d10-7f02-a9b4-0c1d2e3f4a5b" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/incidents/01a1f3c2-7d0e-7a51-9c3b-2f6e8d4a1b90/updates/01a1f3c2-7d10-7f02-a9b4-0c1d2e3f4a5b"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Resolve an incident
requires authentication
Components return to operational unless another open incident still affects them; subscribers get the resolution, with message if you send one.
Example request:
curl --request PATCH \
"https://statuswerk.eu/api/v1/incidents/01a1f3c2-7d0e-7a51-9c3b-2f6e8d4a1b90/resolve" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"message\": \"b\",
\"notify_subscribers\": true
}"
const url = new URL(
"https://statuswerk.eu/api/v1/incidents/01a1f3c2-7d0e-7a51-9c3b-2f6e8d4a1b90/resolve"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"message": "b",
"notify_subscribers": true
};
fetch(url, {
method: "PATCH",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"data": {
"id": "01a1bb06-ac42-72a7-af4d-7bf1db7bb967",
"title": "Checkout API unavailable",
"slug": "checkout-api-unavailable",
"public_url": "https://acme.statuswerk.eu/incidents/checkout-api-unavailable",
"message": "We are investigating failed payments.",
"status": "resolved",
"status_label": "Resolved",
"severity": "major",
"severity_label": "Major",
"impact": null,
"visible": true,
"is_published": true,
"is_awaiting_approval": false,
"approval_state": null,
"approval_note": null,
"is_unlisted": false,
"excluded_from_uptime": false,
"stickied": false,
"notify_subscribers": true,
"occurred_at": "2026-10-19T08:30:00+00:00",
"resolved_at": "2026-10-19T09:10:00+00:00",
"duration_minutes": 40,
"is_resolved": true,
"components": [
{
"id": "01a1bb06-ac3a-73d9-bdeb-b86ecd87c763",
"name": "Checkout API",
"status": null
}
],
"updates": [
{
"id": "01a1bb06-ac51-71da-a566-49dd7cc5c4cf",
"incident_id": "01a1bb06-ac42-72a7-af4d-7bf1db7bb967",
"status": "resolved",
"status_label": "Resolved",
"message": "Payments work again.",
"notify_subscribers": true,
"created_at": "2026-10-19T09:10:00+00:00",
"updated_at": "2026-10-19T09:10:00+00:00"
},
{
"id": "01a1bb06-ac4b-714f-a2d1-f6630666fb42",
"incident_id": "01a1bb06-ac42-72a7-af4d-7bf1db7bb967",
"status": "identified",
"status_label": "Identified",
"message": "A certificate expired at our payment provider. We are rolling out a new one.",
"notify_subscribers": true,
"created_at": "2026-10-19T08:45:00+00:00",
"updated_at": "2026-10-19T08:45:00+00:00"
},
{
"id": "01a1bb06-ac46-7344-8e3c-1f5dabca8d6b",
"incident_id": "01a1bb06-ac42-72a7-af4d-7bf1db7bb967",
"status": "investigating",
"status_label": "Investigating",
"message": "We are investigating failed payments.",
"notify_subscribers": true,
"created_at": "2026-10-19T08:30:00+00:00",
"updated_at": "2026-10-19T08:30:00+00:00"
}
],
"created_at": "2026-10-19T08:30:00+00:00",
"updated_at": "2026-10-19T09:10:00+00:00"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Integrations
Post incidents and maintenance into Slack, Microsoft Teams, Discord, Google Chat or any webhook. Needs a plan with webhook notifications: without it nothing is sent, creating returns 422 (quota_exceeded), changing and testing return 403. Listing, switching off (is_enabled: false) and deleting always work.
List integrations
requires authentication
A read-only token sees only the host of each webhook URL — the full URL is a credential.
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/integrations" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/integrations"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": 1,
"type": "slack",
"name": "Ops channel",
"url": "https://hooks.slack.com/services/T000/B000/XXXXXXXX",
"is_enabled": true,
"events": [
"incident.created",
"incident.updated",
"incident.resolved",
"maintenance.scheduled",
"maintenance.started",
"maintenance.completed"
],
"last_triggered_at": null,
"last_status_code": null,
"created_at": "2026-10-19T09:10:00+00:00",
"updated_at": "2026-10-19T09:10:00+00:00"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create an integration
requires authentication
Over the plan's integration limit: 422 with error: quota_exceeded. The URL must be public HTTPS.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/integrations" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"type\": \"generic\",
\"name\": \"b\",
\"url\": \"http:\\/\\/bailey.com\\/\",
\"is_enabled\": false,
\"events\": [
\"incident.created\"
]
}"
const url = new URL(
"https://statuswerk.eu/api/v1/integrations"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"type": "generic",
"name": "b",
"url": "http:\/\/bailey.com\/",
"is_enabled": false,
"events": [
"incident.created"
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get an integration
requires authentication
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/integrations/12" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/integrations/12"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update an integration
requires authentication
Without a plan with webhook notifications only switching it off is allowed (403 otherwise).
Example request:
curl --request PUT \
"https://statuswerk.eu/api/v1/integrations/12" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"type\": \"generic\",
\"name\": \"b\",
\"url\": \"http:\\/\\/bailey.com\\/\",
\"is_enabled\": true,
\"events\": [
\"maintenance.scheduled\"
]
}"
const url = new URL(
"https://statuswerk.eu/api/v1/integrations/12"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"type": "generic",
"name": "b",
"url": "http:\/\/bailey.com\/",
"is_enabled": true,
"events": [
"maintenance.scheduled"
]
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete an integration
requires authentication
Example request:
curl --request DELETE \
"https://statuswerk.eu/api/v1/integrations/12" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/integrations/12"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Send a test message
requires authentication
Posts a test message to the integration. 422 when the URL could not be reached. Limited to 10 per minute.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/integrations/12/test" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/integrations/12/test"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Mail server
The workspace's own SMTP server, used for subscriber notifications instead of ours.
Business only. Credentials are held once per workspace; the sender address can be
overridden per status page through mail_from_address on the status page endpoint.
Workspace admins only: the token's owner needs the right to change workspace settings
and must not be restricted to some status pages (403 otherwise, also for reading).
Get the mail server settings
requires authentication
404 when none are set. The password is never returned, only has_password.
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/mail-settings" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/mail-settings"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Set the mail server
requires authentication
The host must be reachable from the public internet.
Omit password to keep the stored one — only while host, port, username and
encryption stay the same; changing any of them without sending the password again
answers 422. is_active false keeps the configuration but sends through our own
servers again.
Example request:
curl --request PATCH \
"https://statuswerk.eu/api/v1/mail-settings" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"host\": \"b\",
\"port\": 22,
\"encryption\": \"tls\",
\"username\": \"g\",
\"password\": \"{+-0pBNvYgx\",
\"from_address\": \"w\",
\"is_active\": true
}"
const url = new URL(
"https://statuswerk.eu/api/v1/mail-settings"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"host": "b",
"port": 22,
"encryption": "tls",
"username": "g",
"password": "{+-0pBNvYgx",
"from_address": "w",
"is_active": true
};
fetch(url, {
method: "PATCH",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Remove the mail server
requires authentication
Subscriber mail goes through our servers again.
Notifications go back through our own servers immediately.
Example request:
curl --request DELETE \
"https://statuswerk.eu/api/v1/mail-settings" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/mail-settings"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Test the mail server
requires authentication
Connects and signs in without sending mail; the result says whether the login was checked. With send_test_mail: true a real test message goes through the server to the token owner's address. Limited to 10 per minute.
Opens a connection, performs the handshake, signs in and hangs up. Nothing is sent.
Always answers 200 when the test could be carried out — the outcome is in ok,
because a server refusing the login is a result, not a failed request. The stored
configuration is the only thing it will test; it does not accept a host to connect
to, which would make this an authenticated port scanner.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/mail-settings/test" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/mail-settings/test"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Maintenance
Announce planned work. Creating needs a plan with scheduled maintenance (403 otherwise); existing windows can be read, changed, started, completed and deleted on every plan, so a downgrade leaves none stuck.
List maintenance windows
requires authentication
In order of their start.
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/maintenances?status=scheduled&upcoming=1&active=&per_page=20" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/maintenances"
);
const params = {
"status": "scheduled",
"upcoming": "1",
"active": "0",
"per_page": "20",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": "01a1bb06-ac56-730b-ba95-295abe87a0b3",
"title": "Database upgrade",
"public_url": "https://acme.statuswerk.eu/maintenance/01a1bb06-ac56-730b-ba95-295abe87a0b3",
"message": "The dashboard is read-only for up to 30 minutes.",
"status": "scheduled",
"status_label": "Scheduled",
"scheduled_start_at": "2026-10-24T22:00:00+00:00",
"scheduled_end_at": "2026-10-24T23:00:00+00:00",
"actual_start_at": null,
"actual_end_at": null,
"scheduled_duration_minutes": 60,
"actual_duration_minutes": null,
"auto_start": false,
"auto_complete": false,
"notify_subscribers": true,
"is_published": true,
"is_awaiting_approval": false,
"approval_state": null,
"approval_note": null,
"is_unlisted": false,
"notify_at_scheduled": true,
"send_reminder_1h": true,
"notify_at_start": true,
"notify_at_end": true,
"update_component_status": false,
"is_scheduled": true,
"is_in_progress": false,
"is_completed": false,
"components": [],
"created_at": "2026-10-19T09:10:00+00:00",
"updated_at": "2026-10-19T09:10:00+00:00"
}
],
"links": {
"first": "https://statuswerk.eu/api/v1/maintenances?page=1",
"last": "https://statuswerk.eu/api/v1/maintenances?page=1",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"links": [
{
"url": null,
"label": "« Previous",
"page": null,
"active": false
},
{
"url": "https://statuswerk.eu/api/v1/maintenances?page=1",
"label": "1",
"page": 1,
"active": true
},
{
"url": null,
"label": "Next »",
"page": null,
"active": false
}
],
"path": "https://statuswerk.eu/api/v1/maintenances",
"per_page": 20,
"to": 1,
"total": 1
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Schedule maintenance
requires authentication
Subscribers are told when it is scheduled, an hour before, when it starts and when it ends — each switchable with notify_at_scheduled, send_reminder_1h, notify_at_start, notify_at_end. Held for four-eyes approval, it is announced once approved.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/maintenances" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"title\": \"b\",
\"message\": \"n\",
\"scheduled_start_at\": \"2052-12-06\",
\"scheduled_end_at\": \"2052-12-05\",
\"auto_start\": false,
\"auto_complete\": false,
\"notify_subscribers\": true,
\"is_unlisted\": false,
\"notify_at_scheduled\": false,
\"send_reminder_1h\": false,
\"notify_at_start\": true,
\"notify_at_end\": true,
\"update_component_status\": true,
\"component_ids\": [
\"a4855dc5-0acb-33c3-b921-f4291f719ca0\"
]
}"
const url = new URL(
"https://statuswerk.eu/api/v1/maintenances"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"title": "b",
"message": "n",
"scheduled_start_at": "2052-12-06",
"scheduled_end_at": "2052-12-05",
"auto_start": false,
"auto_complete": false,
"notify_subscribers": true,
"is_unlisted": false,
"notify_at_scheduled": false,
"send_reminder_1h": false,
"notify_at_start": true,
"notify_at_end": true,
"update_component_status": true,
"component_ids": [
"a4855dc5-0acb-33c3-b921-f4291f719ca0"
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"data": {
"id": "01a1bb06-ac56-730b-ba95-295abe87a0b3",
"title": "Database upgrade",
"public_url": "https://acme.statuswerk.eu/maintenance/01a1bb06-ac56-730b-ba95-295abe87a0b3",
"message": "The dashboard is read-only for up to 30 minutes.",
"status": "scheduled",
"status_label": "Scheduled",
"scheduled_start_at": "2026-10-24T22:00:00+00:00",
"scheduled_end_at": "2026-10-24T23:00:00+00:00",
"actual_start_at": null,
"actual_end_at": null,
"scheduled_duration_minutes": 60,
"actual_duration_minutes": null,
"auto_start": false,
"auto_complete": false,
"notify_subscribers": true,
"is_published": true,
"is_awaiting_approval": false,
"approval_state": null,
"approval_note": null,
"is_unlisted": false,
"notify_at_scheduled": null,
"send_reminder_1h": null,
"notify_at_start": null,
"notify_at_end": null,
"update_component_status": null,
"is_scheduled": true,
"is_in_progress": false,
"is_completed": false,
"components": [],
"created_at": "2026-10-19T09:10:00+00:00",
"updated_at": "2026-10-19T09:10:00+00:00"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get a maintenance window
requires authentication
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/maintenances/01a1f3c2-8f40-7d51-a263-7d8e9f0a1b2c" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/maintenances/01a1f3c2-8f40-7d51-a263-7d8e9f0a1b2c"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update a maintenance window
requires authentication
Example request:
curl --request PUT \
"https://statuswerk.eu/api/v1/maintenances/01a1f3c2-8f40-7d51-a263-7d8e9f0a1b2c" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"title\": \"b\",
\"message\": \"n\",
\"scheduled_start_at\": \"2026-11-12T21:59:18\",
\"scheduled_end_at\": \"2052-12-05\",
\"auto_start\": true,
\"auto_complete\": false,
\"notify_subscribers\": true,
\"is_unlisted\": false,
\"notify_at_scheduled\": true,
\"send_reminder_1h\": true,
\"notify_at_start\": true,
\"notify_at_end\": true,
\"update_component_status\": true,
\"status\": \"scheduled\",
\"actual_start_at\": \"2026-11-12T21:59:18\",
\"actual_end_at\": \"2052-12-05\",
\"component_ids\": [
\"a4855dc5-0acb-33c3-b921-f4291f719ca0\"
]
}"
const url = new URL(
"https://statuswerk.eu/api/v1/maintenances/01a1f3c2-8f40-7d51-a263-7d8e9f0a1b2c"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"title": "b",
"message": "n",
"scheduled_start_at": "2026-11-12T21:59:18",
"scheduled_end_at": "2052-12-05",
"auto_start": true,
"auto_complete": false,
"notify_subscribers": true,
"is_unlisted": false,
"notify_at_scheduled": true,
"send_reminder_1h": true,
"notify_at_start": true,
"notify_at_end": true,
"update_component_status": true,
"status": "scheduled",
"actual_start_at": "2026-11-12T21:59:18",
"actual_end_at": "2052-12-05",
"component_ids": [
"a4855dc5-0acb-33c3-b921-f4291f719ca0"
]
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete a maintenance window
requires authentication
Example request:
curl --request DELETE \
"https://statuswerk.eu/api/v1/maintenances/01a1f3c2-8f40-7d51-a263-7d8e9f0a1b2c" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/maintenances/01a1f3c2-8f40-7d51-a263-7d8e9f0a1b2c"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Start maintenance now
requires authentication
422 unless it is scheduled.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/maintenances/01a1f3c2-8f40-7d51-a263-7d8e9f0a1b2c/start" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/maintenances/01a1f3c2-8f40-7d51-a263-7d8e9f0a1b2c/start"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Complete maintenance now
requires authentication
422 unless it is in progress.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/maintenances/01a1f3c2-8f40-7d51-a263-7d8e9f0a1b2c/complete" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/maintenances/01a1f3c2-8f40-7d51-a263-7d8e9f0a1b2c/complete"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Metrics
Numbers shown as charts on the page — response time, error rate, queue length — pushed by you.
Metric definitions and the points pushed into them.
Metrics are addressed by the key the customer chose, not by an opaque id — their
monitoring script can then be written once against a name they control rather than
having to look up an identifier first.
List metrics
requires authentication
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/metrics" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/metrics"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create a metric
requires authentication
403 when the plan's metric limit is reached or the plan has no metrics.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/metrics" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"key\": \"b\",
\"name\": \"n\",
\"suffix\": \"gzmiyvdljnikhway\",
\"decimals\": 1,
\"aggregation\": \"last\",
\"description\": \"Omnis nostrum aut adipisci quidem nostrum qui commodi.\",
\"visible\": false,
\"position\": 3,
\"y_axis_min\": 4326.41688,
\"y_axis_max\": 4326.41688
}"
const url = new URL(
"https://statuswerk.eu/api/v1/metrics"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"key": "b",
"name": "n",
"suffix": "gzmiyvdljnikhway",
"decimals": 1,
"aggregation": "last",
"description": "Omnis nostrum aut adipisci quidem nostrum qui commodi.",
"visible": false,
"position": 3,
"y_axis_min": 4326.41688,
"y_axis_max": 4326.41688
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"data": {
"id": "01a1544c-7cb2-72ab-8a4d-ad75c201d2c1",
"key": "api.response_time",
"name": "API response time",
"source": "push",
"accepts_points": true,
"suffix": "ms",
"decimals": 0,
"aggregation": "avg",
"description": null,
"visible": true,
"position": 0,
"y_axis_min": null,
"y_axis_max": null,
"last_point_at": null,
"is_stale": true,
"created_at": "2026-10-19T09:10:00+00:00",
"updated_at": "2026-10-19T09:10:00+00:00"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get a metric
requires authentication
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/metrics/api.response_time" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/metrics/api.response_time"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update a metric
requires authentication
Example request:
curl --request PUT \
"https://statuswerk.eu/api/v1/metrics/api.response_time" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"key\": \"b\",
\"name\": \"n\",
\"suffix\": \"gzmiyvdljnikhway\",
\"decimals\": 1,
\"aggregation\": \"max\",
\"description\": \"Omnis nostrum aut adipisci quidem nostrum qui commodi.\",
\"visible\": true,
\"position\": 3,
\"y_axis_min\": 4326.41688,
\"y_axis_max\": 4326.41688
}"
const url = new URL(
"https://statuswerk.eu/api/v1/metrics/api.response_time"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"key": "b",
"name": "n",
"suffix": "gzmiyvdljnikhway",
"decimals": 1,
"aggregation": "max",
"description": "Omnis nostrum aut adipisci quidem nostrum qui commodi.",
"visible": true,
"position": 3,
"y_axis_min": 4326.41688,
"y_axis_max": 4326.41688
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete a metric
requires authentication
Removes its points too.
Example request:
curl --request DELETE \
"https://statuswerk.eu/api/v1/metrics/api.response_time" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/metrics/api.response_time"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Push points
requires authentication
One point or a batch; accepted with 202. 409 for a metric fed by another source. 403 on a plan without metrics (after a downgrade the metrics stay, but take no new points — as the dashboard hides them).
Idempotent: points are bucketed on write, so a client retrying a failed request overwrites rather than duplicates.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/metrics/api.response_time/points" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"points\": [
{
\"value\": 4326.41688,
\"timestamp\": \"2026-11-12T21:59:18\"
}
]
}"
const url = new URL(
"https://statuswerk.eu/api/v1/metrics/api.response_time/points"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"points": [
{
"value": 4326.41688,
"timestamp": "2026-11-12T21:59:18"
}
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"accepted": 2,
"bucket_seconds": 60,
"metric": {
"id": "01a1544c-7cb2-72ab-8a4d-ad75c201d2c1",
"key": "api.response_time",
"name": "API response time",
"source": "push",
"accepts_points": true,
"suffix": "ms",
"decimals": 0,
"aggregation": "avg",
"description": null,
"visible": true,
"position": 0,
"y_axis_min": null,
"y_axis_max": null,
"last_point_at": "2026-10-19T09:05:00+00:00",
"is_stale": false,
"created_at": "2026-10-19T09:10:00+00:00",
"updated_at": "2026-10-19T09:10:00+00:00"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Read points
requires authentication
Without from and to, the last 24 hours.
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/metrics/api.response_time/points?from=2026-10-18T09%3A00%3A00Z&to=2026-10-19T09%3A00%3A00Z&resolution=60" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/metrics/api.response_time/points"
);
const params = {
"from": "2026-10-18T09:00:00Z",
"to": "2026-10-19T09:00:00Z",
"resolution": "60",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Monitors
HTTP checks we run from several regions in Europe (Hetzner and UpCloud). A failure is confirmed from a second region before the check counts as down; it is up again after two successes in a row. The number of checks and the shortest interval depend on the plan (403 / 422 otherwise).
List monitors
requires authentication
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/monitors" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/monitors"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": "01a1bb34-522b-7341-9533-fe0f0f1b9d46",
"name": "Checkout API",
"url": "https://api.example.com/health",
"method": "GET",
"interval_seconds": 300,
"timeout_seconds": 10,
"expected_status_from": 200,
"expected_status_to": 399,
"keyword": null,
"regions": [
"fsn",
"nbg",
"hel",
"es-mad1",
"pl-waw1",
"nl-ams1"
],
"all_regions": true,
"auth": {
"type": "basic",
"username": "monitor"
},
"component_id": "01a1bb34-5188-7276-954d-338721448041",
"on_down": "switch_component",
"down_component_status": "major_outage",
"is_public": true,
"is_paused": false,
"paused_by_plan": false,
"state": "up",
"in_maintenance": false,
"state_changed_at": "2026-10-19T08:20:00+00:00",
"last_checked_at": "2026-10-19T08:29:41+00:00",
"last_region": "nbg",
"last_status_code": 200,
"last_response_ms": 184,
"last_error": null,
"certificate_expires_at": "2027-01-12T23:59:59+00:00",
"metric_key": null,
"recipients": {
"members": [],
"emails": [
"oncall@example.com"
],
"phones": [],
"integrations": []
},
"created_at": "2026-10-19T09:10:00+00:00",
"updated_at": "2026-10-19T09:10:00+00:00"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create a monitor
requires authentication
Runs for the first time within seconds. 403 when the plan has no monitors left or
SMS recipients are given on a plan without SMS.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/monitors" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Website\",
\"url\": \"https:\\/\\/example.com\\/health\",
\"method\": \"GET\",
\"interval_seconds\": 60,
\"timeout_seconds\": 10,
\"expected_status_from\": 200,
\"expected_status_to\": 399,
\"regions\": [
\"architecto\"
],
\"auth_type\": \"basic\",
\"auth_username\": \"monitor\",
\"auth_password\": \"correct-horse-battery\",
\"on_down\": \"notify\",
\"down_component_status\": \"major_outage\",
\"is_public\": false,
\"is_paused\": false,
\"recipients\": {
\"members\": [
16
],
\"emails\": [
\"n\"
],
\"phones\": [
\"+3642559314\"
],
\"integrations\": [
16
]
}
}"
const url = new URL(
"https://statuswerk.eu/api/v1/monitors"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Website",
"url": "https:\/\/example.com\/health",
"method": "GET",
"interval_seconds": 60,
"timeout_seconds": 10,
"expected_status_from": 200,
"expected_status_to": 399,
"regions": [
"architecto"
],
"auth_type": "basic",
"auth_username": "monitor",
"auth_password": "correct-horse-battery",
"on_down": "notify",
"down_component_status": "major_outage",
"is_public": false,
"is_paused": false,
"recipients": {
"members": [
16
],
"emails": [
"n"
],
"phones": [
"+3642559314"
],
"integrations": [
16
]
}
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"data": {
"id": "01a1bb34-522b-7341-9533-fe0f0f1b9d46",
"name": "Checkout API",
"url": "https://api.example.com/health",
"method": "GET",
"interval_seconds": 300,
"timeout_seconds": 10,
"expected_status_from": 200,
"expected_status_to": 399,
"keyword": null,
"regions": [
"fsn",
"nbg",
"hel",
"es-mad1",
"pl-waw1",
"nl-ams1"
],
"all_regions": true,
"auth": {
"type": "basic",
"username": "monitor"
},
"component_id": "01a1bb34-5188-7276-954d-338721448041",
"on_down": "switch_component",
"down_component_status": "major_outage",
"is_public": true,
"is_paused": false,
"paused_by_plan": false,
"state": "pending",
"in_maintenance": false,
"state_changed_at": null,
"last_checked_at": null,
"last_region": null,
"last_status_code": null,
"last_response_ms": null,
"last_error": null,
"certificate_expires_at": null,
"metric_key": null,
"recipients": {
"members": [],
"emails": [
"oncall@example.com"
],
"phones": [],
"integrations": []
},
"created_at": "2026-10-19T09:10:00+00:00",
"updated_at": "2026-10-19T09:10:00+00:00"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get a monitor
requires authentication
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/monitors/architecto" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/monitors/architecto"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update a monitor
requires authentication
Changing the URL, method, expected status or keyword starts the check afresh: an
open outage is closed and a component the check switched goes back to operational.
Pausing does the same. If the check was down, its recipients are told the outage
ended (mail and integrations with the event monitor.closed, no SMS). Resuming
beyond the plan's limit: 403.
Example request:
curl --request PUT \
"https://statuswerk.eu/api/v1/monitors/architecto" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Website\",
\"url\": \"https:\\/\\/example.com\\/health\",
\"method\": \"GET\",
\"interval_seconds\": 60,
\"timeout_seconds\": 10,
\"expected_status_from\": 200,
\"expected_status_to\": 399,
\"regions\": [
\"architecto\"
],
\"auth_type\": \"basic\",
\"auth_username\": \"monitor\",
\"auth_password\": \"correct-horse-battery\",
\"on_down\": \"notify\",
\"down_component_status\": \"major_outage\",
\"is_public\": false,
\"is_paused\": false,
\"recipients\": {
\"members\": [
16
],
\"emails\": [
\"n\"
],
\"phones\": [
\"+3642559314\"
],
\"integrations\": [
16
]
}
}"
const url = new URL(
"https://statuswerk.eu/api/v1/monitors/architecto"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Website",
"url": "https:\/\/example.com\/health",
"method": "GET",
"interval_seconds": 60,
"timeout_seconds": 10,
"expected_status_from": 200,
"expected_status_to": 399,
"regions": [
"architecto"
],
"auth_type": "basic",
"auth_username": "monitor",
"auth_password": "correct-horse-battery",
"on_down": "notify",
"down_component_status": "major_outage",
"is_public": false,
"is_paused": false,
"recipients": {
"members": [
16
],
"emails": [
"n"
],
"phones": [
"+3642559314"
],
"integrations": [
16
]
}
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete a monitor
requires authentication
Removes its outages and response times. A component the check had switched to an
outage goes back to operational. If the check was down, its recipients are told the
outage ended (mail and integrations with the event monitor.closed, no SMS).
Example request:
curl --request DELETE \
"https://statuswerk.eu/api/v1/monitors/architecto" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/monitors/architecto"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List outages
requires authentication
Confirmed outages of one monitor, newest first. A single failed run that a second region did not confirm is not an outage and does not appear here.
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/monitors/BcECdBDA-CdED-bFEA-CbCE-BcCdeBfbbebc/outages?per_page=25" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/monitors/BcECdBDA-CdED-bFEA-CbCE-BcCdeBfbbebc/outages"
);
const params = {
"per_page": "25",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": 1,
"started_at": "2026-10-19T08:02:10+00:00",
"ended_at": "2026-10-19T08:20:00+00:00",
"duration_seconds": 1070,
"regions": [
"fsn",
"hel"
],
"status_code": 503,
"error": "HTTP 503"
}
],
"links": {
"first": "https://statuswerk.eu/api/v1/monitors/01a1a79f-8af8-70ee-9168-1ab293fc293d/outages?page=1",
"last": "https://statuswerk.eu/api/v1/monitors/01a1a79f-8af8-70ee-9168-1ab293fc293d/outages?page=1",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"links": [
{
"url": null,
"label": "« Previous",
"page": null,
"active": false
},
{
"url": "https://statuswerk.eu/api/v1/monitors/01a1a79f-8af8-70ee-9168-1ab293fc293d/outages?page=1",
"label": "1",
"page": 1,
"active": true
},
{
"url": null,
"label": "Next »",
"page": null,
"active": false
}
],
"path": "https://statuswerk.eu/api/v1/monitors/01a1a79f-8af8-70ee-9168-1ab293fc293d/outages",
"per_page": 25,
"to": 1,
"total": 1
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
SMS
The workspace's SMS this month: the plan's allowance, what is used, and what is left in bought packs. Subscriber SMS, confirmation codes and check alerts count, in SMS parts (160 characters, 70 with emoji or other characters outside the SMS character set). Read-only: packs are bought in the dashboard.
Get SMS usage
requires authentication
allowance is null on plans without a monthly number. paused is true while the allowance and every pack are used up: SMS are not sent until the next month or a new pack; email, webhooks and chat carry on.
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/sms-usage" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/sms-usage"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": {
"period": "2026-11",
"allowance": 250,
"used": 212,
"from_packs": 0,
"pack_remaining": 250,
"paused": false
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Status page
Settings and status of the status page the request works on.
Get the status page
requires authentication
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/statuspage" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/statuspage"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": {
"id": "01a1cca7-529c-73dc-99c0-06ad67b5f04c",
"name": "Acme",
"slug": "acme",
"subdomain": "acme",
"custom_domain": null,
"public_url": "https://acme.statuswerk.eu",
"timezone": "UTC",
"language": "en",
"is_public": true,
"is_password_protected": false,
"access_ip_allowlist": [],
"overall_status": "major_outage",
"settings": {
"allow_subscriptions": true,
"show_uptime": true,
"uptime_days_to_show": 90,
"allow_email_subscribers": true,
"allow_sms_subscribers": false,
"allow_webhook_subscribers": true,
"allow_rss_subscribers": true,
"allow_public_api": true,
"show_overall_uptime": true,
"uptime_threshold_degraded": 99.5,
"approval_required_for_incidents": false,
"approval_required_for_maintenances": false,
"reply_to_email": null,
"mail_from_address": null
},
"branding": {
"primary_color": "#3B82F6",
"operational_color": null,
"section_titles": [],
"theme": "light",
"logo_path": null,
"logo_dark_path": null,
"favicon_path": null,
"logo_url": null,
"logo_dark_url": null,
"favicon_url": null,
"header_html": null,
"footer_html": null,
"custom_css": null,
"analytics_provider": null,
"analytics_site": null,
"analytics_host": null
},
"seo": {
"meta_title": null,
"meta_description": null,
"is_noindex": false
},
"component_groups": [
{
"id": "01a1cca7-52be-71d3-90fc-fdaee25a62c1",
"name": "Payments",
"description": null,
"position": 1,
"collapsed_by_default": false,
"visible": true,
"overall_status": "major_outage",
"components": [
{
"id": "01a1cca7-52c1-7051-9d9d-9e3639607967",
"name": "Checkout API",
"description": "Payments and orders",
"status": "major_outage",
"status_label": "Major Outage",
"group_id": "01a1cca7-52be-71d3-90fc-fdaee25a62c1",
"position": 1,
"show_uptime": true,
"uptime_start_date": null,
"uptime_90d": 100,
"visible": true,
"created_at": "2026-10-19T08:30:00+00:00",
"updated_at": "2026-10-19T08:30:00+00:00"
}
],
"created_at": "2026-10-19T08:30:00+00:00",
"updated_at": "2026-10-19T08:30:00+00:00"
}
],
"components": [
{
"id": "01a1cca7-52c1-7051-9d9d-9e3639607967",
"name": "Checkout API",
"description": "Payments and orders",
"status": "major_outage",
"status_label": "Major Outage",
"group_id": "01a1cca7-52be-71d3-90fc-fdaee25a62c1",
"position": 1,
"show_uptime": true,
"uptime_start_date": null,
"uptime_90d": 100,
"visible": true,
"created_at": "2026-10-19T08:30:00+00:00",
"updated_at": "2026-10-19T08:30:00+00:00"
}
],
"active_incidents_count": 1,
"created_at": "2026-10-19T08:30:00+00:00",
"updated_at": "2026-10-19T08:30:00+00:00"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update the status page
requires authentication
language (de or en) switches the public page, its feeds and badge, and every notification its subscribers receive. Switching on SMS or webhook subscribers needs the plan (403), as do a password, an IP allowlist, hiding from search engines (is_noindex), and custom HTML/CSS (cleaned of scripts on save); switching any of them off works on every plan. The four-eyes switches are read-only here (403): a token bound by the rule must not be able to lift it. Logo and favicon have their own endpoints.
Every field is optional; only those you send change.
Example request:
curl --request PATCH \
"https://statuswerk.eu/api/v1/statuspage" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Acme\",
\"timezone\": \"Europe\\/Berlin\",
\"language\": \"de\",
\"is_public\": true,
\"access_password\": null,
\"access_ip_allowlist\": [
\"203.0.113.0\\/24\"
],
\"allow_subscriptions\": true,
\"show_uptime\": true,
\"uptime_days_to_show\": 90,
\"allow_email_subscribers\": true,
\"allow_sms_subscribers\": false,
\"allow_webhook_subscribers\": false,
\"allow_rss_subscribers\": true,
\"allow_public_api\": true,
\"reply_to_email\": \"support@acme.example\",
\"mail_from_address\": \"status@acme.example\",
\"meta_title\": \"Acme status\",
\"meta_description\": \"Current availability of Acme\'s services.\",
\"primary_color\": \"#16A34A\",
\"operational_color\": \"#16A34A\",
\"section_titles\": {
\"component_uptime\": \"Our services\"
},
\"theme\": \"system\",
\"show_overall_uptime\": true,
\"uptime_threshold_degraded\": 99.5,
\"is_noindex\": false,
\"header_html\": null,
\"footer_html\": null,
\"custom_css\": null,
\"analytics_provider\": null,
\"analytics_site\": null,
\"analytics_host\": null
}"
const url = new URL(
"https://statuswerk.eu/api/v1/statuspage"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Acme",
"timezone": "Europe\/Berlin",
"language": "de",
"is_public": true,
"access_password": null,
"access_ip_allowlist": [
"203.0.113.0\/24"
],
"allow_subscriptions": true,
"show_uptime": true,
"uptime_days_to_show": 90,
"allow_email_subscribers": true,
"allow_sms_subscribers": false,
"allow_webhook_subscribers": false,
"allow_rss_subscribers": true,
"allow_public_api": true,
"reply_to_email": "support@acme.example",
"mail_from_address": "status@acme.example",
"meta_title": "Acme status",
"meta_description": "Current availability of Acme's services.",
"primary_color": "#16A34A",
"operational_color": "#16A34A",
"section_titles": {
"component_uptime": "Our services"
},
"theme": "system",
"show_overall_uptime": true,
"uptime_threshold_degraded": 99.5,
"is_noindex": false,
"header_html": null,
"footer_html": null,
"custom_css": null,
"analytics_provider": null,
"analytics_site": null,
"analytics_host": null
};
fetch(url, {
method: "PATCH",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get the overall status
requires authentication
The one call a pipeline or health check needs: the page's worst current status and how many incidents are open. uptime is the page's uptime in percent over uptime_days — the number the page shows (average of its visible components with uptime shown), by default over the page's own period.
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/statuspage/status?days=30" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/statuspage/status"
);
const params = {
"days": "30",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"status": "major_outage",
"active_incidents": 1,
"url": "https://acme.statuswerk.eu",
"uptime": 100,
"uptime_days": 90
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Upload the logo, dark-theme logo or favicon
requires authentication
Send the image as multipart form data in file. Logo and dark-theme logo: SVG, PNG, JPEG, WebP or GIF up to 2 MB; favicon: SVG, PNG, ICO, WebP or GIF up to 512 KB. An SVG is stored sanitized (scripts, event handlers and external references removed); one that is no usable SVG afterwards is refused. Replaces the previous one.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/statuspage/logo" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "file=@/tmp/php20d36aj6fs2o2YbPPH8" const url = new URL(
"https://statuswerk.eu/api/v1/statuspage/logo"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('file', document.querySelector('input[name="file"]').files[0]);
fetch(url, {
method: "POST",
headers,
body,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Remove the logo, dark-theme logo or favicon
requires authentication
Example request:
curl --request DELETE \
"https://statuswerk.eu/api/v1/statuspage/favicon" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/statuspage/favicon"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Status pages
All status pages of the workspace: list, create, delete.
RESTful collection for a tenant's statuspages (create / list / show / delete).
Complements the header-based singular endpoints (/api/v1/statuspage) with
explicit-ID resources needed for multi-page orgs and IaC tools (Terraform/CLI).
Updates continue to use PATCH /api/v1/statuspage (with X-Statuspage-Id) for now.
List status pages
requires authentication
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/statuspages" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/statuspages"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": "01a1cca7-529c-73dc-99c0-06ad67b5f04c",
"name": "Acme",
"slug": "acme",
"subdomain": "acme",
"custom_domain": null,
"public_url": "https://acme.statuswerk.eu",
"timezone": "UTC",
"language": "en",
"is_public": true,
"is_password_protected": false,
"access_ip_allowlist": [],
"overall_status": "operational",
"settings": {
"allow_subscriptions": true,
"show_uptime": true,
"uptime_days_to_show": 90,
"allow_email_subscribers": true,
"allow_sms_subscribers": false,
"allow_webhook_subscribers": true,
"allow_rss_subscribers": true,
"allow_public_api": true,
"show_overall_uptime": true,
"uptime_threshold_degraded": 99.5,
"approval_required_for_incidents": false,
"approval_required_for_maintenances": false,
"reply_to_email": null,
"mail_from_address": null
},
"branding": {
"primary_color": "#3B82F6",
"operational_color": null,
"section_titles": [],
"theme": "light",
"logo_path": null,
"logo_dark_path": null,
"favicon_path": null,
"logo_url": null,
"logo_dark_url": null,
"favicon_url": null,
"header_html": null,
"footer_html": null,
"custom_css": null,
"analytics_provider": null,
"analytics_site": null,
"analytics_host": null
},
"seo": {
"meta_title": null,
"meta_description": null,
"is_noindex": false
},
"created_at": "2026-10-19T08:30:00+00:00",
"updated_at": "2026-10-19T08:30:00+00:00"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create a status page
requires authentication
language (de or en, default en) is the language of the public page, its feeds and badge, and of every notification its subscribers receive. Over the plan's page limit: 422 with error: quota_exceeded; a subdomain in use: 422 with error: subdomain_taken; one of ours (www, api, app, mail, login, billing …): error: subdomain_reserved.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/statuspages" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Acme\",
\"subdomain\": \"acme\",
\"timezone\": \"Europe\\/Berlin\",
\"language\": \"de\",
\"reply_to_email\": \"support@acme.example\"
}"
const url = new URL(
"https://statuswerk.eu/api/v1/statuspages"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Acme",
"subdomain": "acme",
"timezone": "Europe\/Berlin",
"language": "de",
"reply_to_email": "support@acme.example"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get a status page
requires authentication
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/statuspages/01a1f3c2-5c00-7a10-8b20-1c2d3e4f5a6b" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/statuspages/01a1f3c2-5c00-7a10-8b20-1c2d3e4f5a6b"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete a status page
requires authentication
With its components, incidents, maintenance windows and subscribers — for good.
Example request:
curl --request DELETE \
"https://statuswerk.eu/api/v1/statuspages/01a1f3c2-5c00-7a10-8b20-1c2d3e4f5a6b" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/statuspages/01a1f3c2-5c00-7a10-8b20-1c2d3e4f5a6b"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Subscribers
People and systems notified about incidents and maintenance: email, SMS, webhook.
Import subscribers from CSV
requires authentication
The dashboard's import: a CSV file (file, up to 1 MB) with one email address per row or a column named email. The addresses are added as confirmed email subscribers — import only people who agreed elsewhere, and confirm it with consent: true, as the dashboard asks (422 otherwise). Duplicates and invalid addresses are skipped, and so is everything over the plan's subscriber limit; the response counts each. While the first invoice of an annual plan on invoice is unpaid: 403 with error: awaiting_payment.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/subscribers/import" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "consent=1"\
--form "file=@/tmp/phpl52c8f27i5di4x5QXX4" const url = new URL(
"https://statuswerk.eu/api/v1/subscribers/import"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('consent', '1');
body.append('file', document.querySelector('input[name="file"]').files[0]);
fetch(url, {
method: "POST",
headers,
body,
}).then(response => response.json());Example response (200):
{
"data": {
"imported": 120,
"skipped_duplicates": 3,
"skipped_invalid": 1,
"skipped_quota": 0
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List subscribers
requires authentication
A read-only token sees email addresses and phone numbers masked (j••••@example.com, ••••••••••567) and only the host of a webhook URL.
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/subscribers?verified=1&channel=email&undeliverable=1&per_page=50" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/subscribers"
);
const params = {
"verified": "1",
"channel": "email",
"undeliverable": "1",
"per_page": "50",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": "01a1bb39-facc-703f-b5da-dc8141951647",
"email": "jane@example.com",
"phone": null,
"webhook_url": null,
"webhook_type": null,
"channels": [
"email"
],
"component_ids": null,
"locale": "en",
"is_verified": true,
"verified_at": "2026-10-19T09:10:00+00:00",
"undeliverable_at": null,
"undeliverable_reason": null,
"created_at": "2026-10-19T09:10:00+00:00",
"updated_at": "2026-10-19T09:10:00+00:00"
}
],
"links": {
"first": "https://statuswerk.eu/api/v1/subscribers?page=1",
"last": "https://statuswerk.eu/api/v1/subscribers?page=1",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"links": [
{
"url": null,
"label": "« Previous",
"page": null,
"active": false
},
{
"url": "https://statuswerk.eu/api/v1/subscribers?page=1",
"label": "1",
"page": 1,
"active": true
},
{
"url": null,
"label": "Next »",
"page": null,
"active": false
}
],
"path": "https://statuswerk.eu/api/v1/subscribers",
"per_page": 50,
"to": 1,
"total": 1
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create a new subscriber.
requires authentication
The subscriber receives a confirmation email (or SMS code) and is notified once they confirm.
With skip_verification the subscriber is confirmed at once — use it only for
people who already agreed elsewhere. A workspace whose first invoice for an annual
plan on invoice is still unpaid gets 403 with error: awaiting_payment for
skip_verification until the payment has arrived; without it the call works as
usual.
Every mail, SMS and webhook text a subscriber gets is in the status page's
language. locale is stored as given but does not change that.
phone is in international format (+491701234567). SMS and webhook subscribers
need the channel switched on for the page and included in the plan, subscribing to
single component_ids needs the plan too — otherwise 403 with
error: channel_unavailable / feature_unavailable. An SMS subscriber always
confirms the number with the code we send: skip_verification with a phone
gets 422 with error: sms_requires_verification. Over the subscriber limit:
422 with error: quota_exceeded.
A webhook-only subscriber is confirmed by its endpoint, as on the public page: we
send one signed test POST right away and a 2xx answer confirms it. Anything else
creates nothing and returns 422 with error: webhook_unreachable. The same
address (email, number or webhook URL) twice returns the existing subscriber.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/subscribers" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"email\": \"ops@example.com\",
\"phone\": \"+3642559314\",
\"webhook_url\": \"http:\\/\\/www.considine.com\\/provident-perspiciatis-quo-omnis-nostrum-aut-adipisci-quidem\",
\"webhook_type\": \"google_chat\",
\"webhook_secret\": \"w\",
\"channels\": [
\"webhook\"
],
\"component_ids\": [
\"445bd3f6-8f2c-38cb-aa04-2f4e1edb32bb\"
],
\"locale\": \"sw_TZ\",
\"skip_verification\": false
}"
const url = new URL(
"https://statuswerk.eu/api/v1/subscribers"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"email": "ops@example.com",
"phone": "+3642559314",
"webhook_url": "http:\/\/www.considine.com\/provident-perspiciatis-quo-omnis-nostrum-aut-adipisci-quidem",
"webhook_type": "google_chat",
"webhook_secret": "w",
"channels": [
"webhook"
],
"component_ids": [
"445bd3f6-8f2c-38cb-aa04-2f4e1edb32bb"
],
"locale": "sw_TZ",
"skip_verification": false
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get a subscriber
requires authentication
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/subscribers/01a1f3c2-a060-7f71-8485-9f0a1b2c3d4e" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/subscribers/01a1f3c2-a060-7f71-8485-9f0a1b2c3d4e"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete a subscriber
requires authentication
Example request:
curl --request DELETE \
"https://statuswerk.eu/api/v1/subscribers/01a1f3c2-a060-7f71-8485-9f0a1b2c3d4e" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/subscribers/01a1f3c2-a060-7f71-8485-9f0a1b2c3d4e"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Resend the confirmation mail
requires authentication
422 when the subscriber is confirmed already or has no email address; 429 with error: too_many_confirmations after three confirmation mails to one address within an hour. Limited to 10 per minute.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/subscribers/01a1f3c2-a060-7f71-8485-9f0a1b2c3d4e/resend-verification" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/subscribers/01a1f3c2-a060-7f71-8485-9f0a1b2c3d4e/resend-verification"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Team
Who is in the workspace, and inviting more people. Removing members and changing roles stays in the dashboard: a token that can do that could rebuild the workspace's access around itself.
List members
requires authentication
Names, email addresses, roles and status page access (statuspage_access: null for every page, otherwise page id => edit, read or none, where a page not listed is none and {} means no page at all; set in the dashboard). The token's owner needs the right to manage the team, as for the team page in the dashboard (403 otherwise).
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/team/members" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/team/members"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": 2,
"name": "Jane Doe",
"email": "jane.doe@acme.example",
"roles": [],
"statuspage_access": null
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List open invitations
requires authentication
The token's owner needs the right to invite members, as in the dashboard (403 otherwise).
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/team/invitations" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/team/invitations"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Invite someone
requires authentication
Sends the invitation mail, as the dashboard does; it is valid for 7 days. Invitations through the API are always for the member role. The token's owner needs the right to invite members (403 otherwise). 422 when the address is already in the team or invited, and with error: quota_exceeded when the plan has no seat left.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/team/invitations" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"email\": \"colleague@example.com\",
\"role\": \"user\"
}"
const url = new URL(
"https://statuswerk.eu/api/v1/team/invitations"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"email": "colleague@example.com",
"role": "user"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Withdraw an invitation
requires authentication
Example request:
curl --request DELETE \
"https://statuswerk.eu/api/v1/team/invitations/01a1f3c2-a170-7081-9596-0a1b2c3d4e5f" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/team/invitations/01a1f3c2-a170-7081-9596-0a1b2c3d4e5f"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Templates
Prepared texts for recurring incidents and maintenance windows. Needs a plan with templates (403 otherwise).
List incident templates
requires authentication
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/incident-templates" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/incident-templates"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create an incident template
requires authentication
Use {key} placeholders in title and message; apply fills them from variables.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/incident-templates" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"b\",
\"title_template\": \"n\",
\"message_template\": \"g\",
\"default_status\": \"investigating\",
\"default_severity\": \"critical\",
\"visible\": false,
\"stickied\": true,
\"notify_subscribers\": false,
\"default_component_ids\": [
\"c90237e9-ced5-3af6-88ea-84aeaa148878\"
]
}"
const url = new URL(
"https://statuswerk.eu/api/v1/incident-templates"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "b",
"title_template": "n",
"message_template": "g",
"default_status": "investigating",
"default_severity": "critical",
"visible": false,
"stickied": true,
"notify_subscribers": false,
"default_component_ids": [
"c90237e9-ced5-3af6-88ea-84aeaa148878"
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"data": {
"id": "01a1544c-7c2f-70af-a6e8-1a99bc95fd92",
"name": "Payment provider down",
"title_template": "{provider} unavailable",
"message_template": "Payments through {provider} are failing. We are in contact with them.",
"default_status": null,
"default_severity": null,
"default_component_ids": [],
"visible": null,
"stickied": null,
"notify_subscribers": null,
"created_at": "2026-10-19T09:10:00+00:00",
"updated_at": "2026-10-19T09:10:00+00:00"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get an incident template
requires authentication
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/incident-templates/01a1f3c2-9a30-7c41-8b52-6c7d8e9f0a1b" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/incident-templates/01a1f3c2-9a30-7c41-8b52-6c7d8e9f0a1b"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update an incident template
requires authentication
Example request:
curl --request PUT \
"https://statuswerk.eu/api/v1/incident-templates/01a1f3c2-9a30-7c41-8b52-6c7d8e9f0a1b" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"b\",
\"title_template\": \"n\",
\"message_template\": \"g\",
\"default_status\": \"monitoring\",
\"default_severity\": \"critical\",
\"visible\": false,
\"stickied\": false,
\"notify_subscribers\": false,
\"default_component_ids\": [
\"c90237e9-ced5-3af6-88ea-84aeaa148878\"
]
}"
const url = new URL(
"https://statuswerk.eu/api/v1/incident-templates/01a1f3c2-9a30-7c41-8b52-6c7d8e9f0a1b"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "b",
"title_template": "n",
"message_template": "g",
"default_status": "monitoring",
"default_severity": "critical",
"visible": false,
"stickied": false,
"notify_subscribers": false,
"default_component_ids": [
"c90237e9-ced5-3af6-88ea-84aeaa148878"
]
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete an incident template
requires authentication
Example request:
curl --request DELETE \
"https://statuswerk.eu/api/v1/incident-templates/01a1f3c2-9a30-7c41-8b52-6c7d8e9f0a1b" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/incident-templates/01a1f3c2-9a30-7c41-8b52-6c7d8e9f0a1b"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Open an incident from a template
requires authentication
Fills the placeholders from variables and opens the incident as POST /incidents would. Over the monthly incident limit: 422 with error: quota_exceeded.
The endpoint CI/CD and alerting hooks use: name the template, optionally pass variables for the placeholders, and every other field comes from the template.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/incident-templates/01a1f3c2-9a30-7c41-8b52-6c7d8e9f0a1b/apply" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"occurred_at\": \"2026-11-12T21:59:18\",
\"variables\": [
\"b\"
]
}"
const url = new URL(
"https://statuswerk.eu/api/v1/incident-templates/01a1f3c2-9a30-7c41-8b52-6c7d8e9f0a1b/apply"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"occurred_at": "2026-11-12T21:59:18",
"variables": [
"b"
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Duplicate an incident template
requires authentication
A copy named "… (copy)", to start a variant from.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/incident-templates/01a1f3c2-9a30-7c41-8b52-6c7d8e9f0a1b/duplicate" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/incident-templates/01a1f3c2-9a30-7c41-8b52-6c7d8e9f0a1b/duplicate"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Save an incident as a template
requires authentication
Title, message, status, severity, components and switches of the incident become a template's defaults.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/incidents/01a1f3c2-7d0e-7a51-9c3b-2f6e8d4a1b90/save-as-template" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Ingest degradation\"
}"
const url = new URL(
"https://statuswerk.eu/api/v1/incidents/01a1f3c2-7d0e-7a51-9c3b-2f6e8d4a1b90/save-as-template"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Ingest degradation"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List maintenance templates
requires authentication
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/maintenance-templates" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/maintenance-templates"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create a maintenance template
requires authentication
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/maintenance-templates" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"b\",
\"title_template\": \"n\",
\"message_template\": \"g\",
\"default_duration_minutes\": 16,
\"notify_subscribers\": false,
\"send_reminder_1h\": false,
\"auto_start\": false,
\"notify_at_start\": true,
\"auto_complete\": false,
\"notify_at_end\": true,
\"update_component_status\": true,
\"default_component_ids\": [
\"977e5426-8d13-3824-86aa-b092f8ae52c5\"
]
}"
const url = new URL(
"https://statuswerk.eu/api/v1/maintenance-templates"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "b",
"title_template": "n",
"message_template": "g",
"default_duration_minutes": 16,
"notify_subscribers": false,
"send_reminder_1h": false,
"auto_start": false,
"notify_at_start": true,
"auto_complete": false,
"notify_at_end": true,
"update_component_status": true,
"default_component_ids": [
"977e5426-8d13-3824-86aa-b092f8ae52c5"
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get a maintenance template
requires authentication
Example request:
curl --request GET \
--get "https://statuswerk.eu/api/v1/maintenance-templates/01a1f3c2-9b50-7e61-b374-8e9f0a1b2c3d" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/maintenance-templates/01a1f3c2-9b50-7e61-b374-8e9f0a1b2c3d"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update a maintenance template
requires authentication
Example request:
curl --request PUT \
"https://statuswerk.eu/api/v1/maintenance-templates/01a1f3c2-9b50-7e61-b374-8e9f0a1b2c3d" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"b\",
\"title_template\": \"n\",
\"message_template\": \"g\",
\"default_duration_minutes\": 16,
\"notify_subscribers\": true,
\"send_reminder_1h\": true,
\"auto_start\": true,
\"notify_at_start\": false,
\"auto_complete\": false,
\"notify_at_end\": false,
\"update_component_status\": false,
\"default_component_ids\": [
\"977e5426-8d13-3824-86aa-b092f8ae52c5\"
]
}"
const url = new URL(
"https://statuswerk.eu/api/v1/maintenance-templates/01a1f3c2-9b50-7e61-b374-8e9f0a1b2c3d"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "b",
"title_template": "n",
"message_template": "g",
"default_duration_minutes": 16,
"notify_subscribers": true,
"send_reminder_1h": true,
"auto_start": true,
"notify_at_start": false,
"auto_complete": false,
"notify_at_end": false,
"update_component_status": false,
"default_component_ids": [
"977e5426-8d13-3824-86aa-b092f8ae52c5"
]
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete a maintenance template
requires authentication
Example request:
curl --request DELETE \
"https://statuswerk.eu/api/v1/maintenance-templates/01a1f3c2-9b50-7e61-b374-8e9f0a1b2c3d" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/maintenance-templates/01a1f3c2-9b50-7e61-b374-8e9f0a1b2c3d"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Schedule maintenance from a template
requires authentication
403 without scheduled maintenance in the plan, 422 when the times are invalid.
This is the endpoint CI/CD and schedulers use: pick the template, give it a start time, and every other field comes from the template.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/maintenance-templates/01a1f3c2-9b50-7e61-b374-8e9f0a1b2c3d/apply" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"scheduled_start_at\": \"2026-11-12T21:59:18\",
\"scheduled_end_at\": \"2052-12-05\",
\"variables\": [
\"n\"
]
}"
const url = new URL(
"https://statuswerk.eu/api/v1/maintenance-templates/01a1f3c2-9b50-7e61-b374-8e9f0a1b2c3d/apply"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"scheduled_start_at": "2026-11-12T21:59:18",
"scheduled_end_at": "2052-12-05",
"variables": [
"n"
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Duplicate a maintenance template
requires authentication
A copy named "… (copy)", to start a variant from.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/maintenance-templates/01a1f3c2-9b50-7e61-b374-8e9f0a1b2c3d/duplicate" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://statuswerk.eu/api/v1/maintenance-templates/01a1f3c2-9b50-7e61-b374-8e9f0a1b2c3d/duplicate"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Save a maintenance window as a template
requires authentication
Title, message, components, switches and the scheduled length (as default duration) become a template's defaults.
Example request:
curl --request POST \
"https://statuswerk.eu/api/v1/maintenances/01a1f3c2-8f40-7d51-a263-7d8e9f0a1b2c/save-as-template" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Monthly database patch\"
}"
const url = new URL(
"https://statuswerk.eu/api/v1/maintenances/01a1f3c2-8f40-7d51-a263-7d8e9f0a1b2c/save-as-template"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Monthly database patch"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.