Public status page API
Public, CORS-enabled JSON, markdown, and feed endpoints for any published status page.
Public status page API
Every published status page exposes a small, stable, public API. No auth, no rate-limit headers to negotiate — just edge-cached JSON, markdown, llms.txt, and an Atom feed. The same response is rendered into the in-page API modal in the footer of every status page, so consumers can discover everything from the page itself.
Base path: /api/status-pages/public/{slug} on happyuptime.com, or just
/api, /api.md, /llms.txt, /feed.xml on a custom domain.
| Endpoint | Returns | Cache |
|---|---|---|
GET /api/status-pages/public/{slug} | Full JSON snapshot | 10s edge |
GET /api/status-pages/public/{slug}/markdown | Markdown summary | 30s edge |
GET /api/status-pages/public/{slug}/llms.txt | LLM instructions | 30s edge |
GET /api/status-pages/public/{slug}/feed.xml | Atom feed of incidents | 60s edge |
GET /api/status-pages/public/{slug}/uptime | 90-day daily uptime per component | 30s edge |
CORS: Access-Control-Allow-Origin: * on the JSON endpoint. GET-only.
JSON snapshot
GET /api/status-pages/public/{slug}
bashcurl -s https://happyuptime.com/api/status-pages/public/acme
json{ "schema_version": 1, "generated_at": "2026-04-27T16:30:00.123Z", "page": { "id": "sp_001", "name": "Acme Status", "slug": "acme", "template": "minimal", "brand_color": "#34d399", "logo_url": "/api/status-pages/sp_001/image/...", "favicon_url": "https://acme.com/favicon.ico", "show_branding": true }, "overallStatus": "operational", "summary": { "components_total": 9, "components_operational": 9, "components_degraded": 0, "components_partial_outage": 0, "components_major_outage": 0, "components_maintenance": 0, "incidents_active": 0, "incidents_resolved_30d": 11, "uptime_90d_avg": 99.97 }, "groups": [ { "id": "grp_001", "name": "API Gateway", "description": "Edge + routing tier", "display_order": 0, "is_collapsed": false, "status": "operational", "component_ids": ["comp_001", "comp_002"] } ], "components": [ { "id": "comp_001", "name": "Web App", "description": null, "group_id": "grp_001", "display_order": 0, "show_response_time": 1, "status": "operational", "last_checked_at": "2026-04-27 16:27:43" } ], "dependencies": [ { "id": "dep_001", "service_id": "svc_aws", "name": "AWS", "category": "cloud", "status": "operational", "status_page_url": "https://status.aws.amazon.com", "icon_url": null, "active_incidents": [] } ], "incidents": [ { "id": "inc_xyz", "title": "API latency", "status": "resolved", "severity": "minor", "started_at": "2026-04-25 01:14:39", "resolved_at": "2026-04-25 01:25:54" } ], "uptime": { "comp_001": { "overall": 99.97, "days": [{ "date": "2026-04-27", "uptime": 100 }] } }, "links": { "page_path": "/status/acme", "api_path": "/status/acme/api", "markdown_path": "/status/acme/api.md", "llms_path": "/status/acme/llms.txt", "feed_path": "/status/acme/feed.xml" }}
Top-level fields
| Field | Type | Notes |
|---|---|---|
schema_version | integer | Bumped on breaking changes. Currently 1. |
generated_at | ISO-8601 | When the snapshot was assembled server-side. |
page | object | Page metadata (id, name, slug, template, brand). |
overallStatus | enum | Worst status across all components. See values below. |
summary | object | Component counts, active/30d incidents, 90-day uptime average. |
groups | array | Subsystems with rolled-up status. Each lists its component_ids. |
components | array | Individual components. description is intentionally null on the public payload (descriptions can leak underlying monitor URLs). |
dependencies | array | Third-party services tracked on this page (AWS, Stripe, etc.) with current status + active provider incidents. |
incidents | array | Last 14 days, plus all currently active. Newest first. |
uptime | object | Per-component map of 90-day daily uptime + overall. Only includes components backed by a monitor. |
links | object | Sibling endpoint paths (relative to the page's host). |
Status values
| Value | Meaning |
|---|---|
operational | All checks passing |
degraded | Some checks slow or partial failures |
partial_outage | Some regions failing |
major_outage | All regions failing |
maintenance | Planned maintenance window active |
unknown | Component has a monitor but no recent results |
Markdown summary
GET /api/status-pages/public/{slug}/markdown
A short, opinionated markdown rendering of the same payload — sections for
Endpoints, Subsystems, Components, Dependencies, and Recent Incidents.
Designed to be paste-ready into LLM prompts and to keep response size small.
LLM instructions
GET /api/status-pages/public/{slug}/llms.txt
A plain-text instruction file describing how an LLM should consume the JSON endpoint, including the schema, status enum, and read-only constraint.
Atom feed
GET /api/status-pages/public/{slug}/feed.xml
Atom 1.0 feed of the 50 most-recent incidents (active + resolved). Suitable for RSS readers, Slack RSS apps, and webhook bridges.
Code samples
javascriptconst r = await fetch("https://happyuptime.com/api/status-pages/public/acme");const data = await r.json();console.log(data.overallStatus, data.summary.uptime_90d_avg);
pythonimport requestsr = requests.get("https://happyuptime.com/api/status-pages/public/acme")print(r.json()["overallStatus"])
bashcurl -s https://happyuptime.com/api/status-pages/public/acme | jq .summary
In-page API modal
Every rendered status page now ships an API link in the footer that opens a responsive modal (centered dialog on desktop, bottom drawer on mobile) with:
- The full endpoint URL with one-click copy
- cURL / JavaScript / Python tabs
- Direct links to all sibling endpoints (markdown, llms.txt, feed.xml)
- A collapsible response-schema preview
The modal is server-rendered into the page (no JS framework, ~3KB of inline JS
- CSS). It does not call any external resource and works under strict CSP as
long as inline
<script>and<style>are allowed.
Caching
- JSON is edge-cached for 10 seconds.
- Markdown / llms.txt are cached for 30 seconds.
- Atom feed is cached for 60 seconds.
If you need real-time data, use the WebSocket endpoint at
/api/ws/{projectId} (authenticated; for first-party dashboards).
Compatibility
schema_versionwill only change in lock-step with breaking changes to the shape (renamed/removed fields). Additive fields do not bump it.- The endpoint also returns a few legacy / deprecated fields (
uptimeDatais exposed asuptime, status enum stays insnake_case). Use only the keys documented above.