Setup documentation

Docs

Everything you need to connect a project to Status, expose a working /api/health endpoint, and surface the results on your own site.

Link, embed & JSON API

Every project has a permanent status page at /p/[slug] and a JSON endpoint at /api/status/[slug]. Use either, or both, to surface status to your customers.

Quick link badge

The smallest possible surface. Drops a small “All systems normal” or “Incident” pill in your site footer.

<a href="https://status.bohuvuj.com/p/perfume-vault"
   target="_blank" rel="noreferrer"
   style="display:inline-flex;gap:8px;align-items:center;
          font:600 12px/1 system-ui;
          padding:8px 12px;border-radius:9999px;
          border:1px solid #1e2a45;background:#0d1424;color:#e8ecf6;
          text-decoration:none">
  <span style="width:8px;height:8px;border-radius:9999px;background:#34d399"></span>
  Status
</a>

Color it green (#34d399), amber (#fbbf24) or red (#fb7185) based on the overall field from the JSON API.

iframe embed

The full status page renders cleanly inside an iframe. Give it a fixed height and a sensible width.

<iframe
  src="https://status.bohuvuj.com/p/perfume-vault"
  title="Service status"
  loading="lazy"
  style="width:100%;height:640px;border:0;border-radius:14px;background:#0d1424"
></iframe>

Public JSON API

EndpointPurposeNotes
GET /api/status/[slug]Latest results + 24h/7d/30d history per componentQuery: days=1..90. Public, no auth, CORS allowed.
GET /api/calendar/[slug]One-year per-day rollup and incident listQuery: days=1..365 (default 365), or day=YYYY-MM-DD for the per-component breakdown.

Response shape

{
  "id": "...",
  "slug": "perfume-vault",
  "name": "Perfume Vault",
  "overall": "ok",
  "lastChecked": "2026-08-29T18:30:00.000Z",
  "latest": [
    { "id": "site", "label": "Website",   "status": "ok", "latencyMs": 42 },
    { "id": "db",   "label": "Database",  "status": "ok", "latencyMs": 9 }
  ],
  "history": [
    { "component": "site", "checks": 288, "ok": 288, "degraded": 0, "down": 0 }
  ],
  "stats": [
    { "component": "site", "label": "Website", "checks": 288, "ok": 288, "degraded": 0, "down": 0,
      "avgLatencyMs": 38, "lastCheckedAt": "...", "lastHttpStatus": 200 }
  ],
  "project": {
    "description": "Online perfume store serving Bangladesh.",
    "homepageUrl": "https://perfumevault.com.bd",
    "region": "ap-south-1",
    "tier": "critical",
    "sortOrder": 10
  },
  "summary": {
    "components": 5,
    "avgLatencyMs": 51,
    "checks24h": 1440, "ok24h": 1438, "degraded24h": 2, "down24h": 0,
    "lastCheckedAt": "...", "lastHttpStatus": 200
  }
}

Fetch example (browser)

const res = await fetch('https://status.bohuvuj.com/api/status/perfume-vault?days=1')
const data = await res.json()
const ok = data.overall === 'ok'
const color = ok ? '#34d399' : data.overall === 'degraded' ? '#fbbf24' : '#fb7185'
document.querySelector('#status-dot').style.background = color

Fetch example (server, with revalidation)

// Next.js App Router
const res = await fetch('https://status.bohuvuj.com/api/status/perfume-vault', {
  next: { revalidate: 60 },
})
const data = await res.json()
Heads up: the public JSON API is read-only and anonymous. Internal write endpoints (poll ingest, project CRUD) are guarded by POLL_SECRET and ADMIN_SECRET — see the troubleshooting page for the exact header shape.