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
| Endpoint | Purpose | Notes |
|---|---|---|
| GET /api/status/[slug] | Latest results + 24h/7d/30d history per component | Query: days=1..90. Public, no auth, CORS allowed. |
| GET /api/calendar/[slug] | One-year per-day rollup and incident list | Query: 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 = colorFetch 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.