Status page API
These reads do not use a dashboard login. Replace {slug} with the
published page slug. The same JSON is on the page host at
/status/{slug}/api/v2/{file}. RSS and Atom are at
/status/{slug}/rss and /status/{slug}/atom.
Add ?lang= only when extra languages are enabled for that workspace.
- GET /public/status-pages/{slug}/v2/status.json
- GET /public/status-pages/{slug}/v2/summary.json
- GET /public/status-pages/{slug}/v2/components.json
- GET /public/status-pages/{slug}/v2/incidents.json
- GET /public/status-pages/{slug}/v2/scheduled-maintenances.json
- GET /public/status-pages/{slug}/rss
- GET /public/status-pages/{slug}/atom
- GET /public/status-pages/{slug}/maintenance.ics
An anonymous page sends
Cache-Control: public, max-age=15, s-maxage=30, stale-while-revalidate=30.
A password-protected or IP-restricted page returns 401 or 403 and
Cache-Control: private, no-store instead of the body.
An unknown or unpublished slug is 404. Public reads are limited to 150 requests
per minute per client IP. Subscribe is 5 requests per 10 minutes per client IP.
status.json
{
"page": {
"id": "page-id",
"name": "Example",
"url": "https://example.com/status/example",
"updated_at": "2026-10-23T12:00:00.000Z"
},
"status": { "indicator": "none", "description": "All Systems Operational" }
} indicator is none, minor, major,
critical, or maintenance. updated_at is the
last observation time when one exists, otherwise the page update time.
components.json
{
"page": { "id": "page-id", "name": "Example", "url": "https://example.com/status/example", "updated_at": "2026-10-23T12:00:00.000Z" },
"components": [
{
"id": "component-id",
"name": "API",
"status": "operational",
"description": null,
"position": 1,
"showcase": true,
"group_id": null
}
]
}
Component status is operational, degraded_performance,
partial_outage, major_outage, or under_maintenance.
incidents.json
{
"page": { "id": "page-id", "name": "Example", "url": "https://example.com/status/example" },
"incidents": [
{
"id": "incident-id",
"name": "Elevated errors",
"status": "investigating",
"created_at": "2026-10-23T12:00:00.000Z",
"updated_at": "2026-10-23T12:05:00.000Z",
"monitoring_at": null,
"resolved_at": null,
"shortlink": "https://example.com/status/example#incident-id",
"page_id": "page-id",
"incident_updates": [
{
"id": "update-id",
"status": "investigating",
"body": "We are investigating.",
"created_at": "2026-10-23T12:05:00.000Z",
"updated_at": "2026-10-23T12:05:00.000Z",
"display_at": "2026-10-23T12:05:00.000Z",
"incident_id": "incident-id"
}
]
}
]
}
Incident status is investigating, identified,
monitoring, or resolved. Only incidents published to the
status page are included.
scheduled-maintenances.json
{
"page": { "id": "page-id", "name": "Example", "url": "https://example.com/status/example", "updated_at": "2026-10-23T12:00:00.000Z" },
"scheduled_maintenances": [
{
"id": "window-id",
"name": "Database upgrade",
"status": "scheduled",
"impact": "maintenance",
"scheduled_for": "2026-10-24T01:00:00.000Z",
"scheduled_until": "2026-10-24T02:00:00.000Z",
"shortlink": "https://example.com/status/example#window-id",
"created_at": "2026-10-23T12:00:00.000Z",
"updated_at": "2026-10-23T12:00:00.000Z",
"page_id": "page-id",
"incident_updates": [
{
"id": "window-id-update",
"status": "scheduled",
"body": "Database upgrade",
"created_at": "2026-10-23T12:00:00.000Z",
"updated_at": "2026-10-23T12:00:00.000Z",
"display_at": "2026-10-24T01:00:00.000Z",
"incident_id": "window-id"
}
]
}
]
}
Maintenance status is scheduled, in_progress,
or completed. summary.json is the status, components,
incidents, and scheduled maintenances in one document.
RSS, Atom, and the calendar
RSS is application/rss+xml. Each public incident is an item whose
description is the latest update. Atom is application/atom+xml with
the same incidents. The maintenance calendar is text/calendar at
/public/status-pages/{slug}/maintenance.ics and on the page host
at /status/{slug}/maintenance.ics. It lists the same public
maintenance windows. That feed returns 403 FEATURE_DISABLED until
the calendar capability is enabled. It does not change the JSON, RSS, or Atom routes.
Subscribe
POST /public/status-pages/{slug}/subscribe with an email starts
confirmation. The address is not active until the link in that message is opened.
Unsubscribe uses the token in the message. A password-protected page requires
access before subscribe returns content. Teams is rejected. Slack is connected
by the page owner, not by this public call.
Errors
{ "error": { "code": "NOT_FOUND", "message": "Status page not found", "statusCode": 404 } }
{ "error": { "code": "PASSWORD_REQUIRED", "message": "This status page requires a password", "statusCode": 401 } }
{ "error": { "code": "FEATURE_DISABLED", "message": "…", "statusCode": 403 } }
{ "error": "Too many requests, please try again later.", "retryAfter": 30, "resetAt": "2026-10-23T12:01:00.000Z" }
IP restriction uses 403. The 429 body is the rate-limit shape, with
Retry-After and X-RateLimit-* headers. The v2, RSS,
Atom, and calendar bodies are not wrapped in a data field.