> ## Documentation Index
> Fetch the complete documentation index at: https://docs.happyuptime.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 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}`

```bash
curl -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

```javascript
const 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);
```

```python
import requests
r = requests.get("https://happyuptime.com/api/status-pages/public/acme")
print(r.json()["overallStatus"])
```

```bash
curl -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_version` will 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 (`uptimeData` is
  exposed as `uptime`, status enum stays in `snake_case`). Use only the keys
  documented above.