Headless 状态页。
你的 UI,我们的数据。
不喜欢我们的状态页? 自己构建。托管版显示的每个字节都可通过公共 REST API 和实时 SSE 流获取。完整 OpenAPI 规范。
为什么 headless
其他所有状态页厂商都把你锁在他们的模板里。我们让你带着数据走,但仍继续使用我们。
你的品牌,你的像素
与主站完全一致。自定义字体、动画、布局。无厂商页脚,无品牌化头部。
随处渲染
Next.js 服务器组件、Astro island、静态 HTML、Slack bot、CLI、应用内横幅。同一端点。
保留在你的域名下
无需 CNAME。从你的服务器获取,在你的应用内渲染。客户永远看不到第三方 URL。
集成,而非迁移
在你的文档、管理面板或客户门户中添加状态小部件,无需将用户重定向到站外。
一次 fetch,应有尽有。
对带 slug 的状态端点发起 GET,解析 JSON,渲染。
curl https://api.pulseapi.tech/status/acme{
"page": {
"id": "acme",
"title": "Acme API Status",
"language": "en",
"customDomain": "status.acme.com"
},
"overallStatus": "operational",
"endpoints": [
{
"id": "ep_1",
"name": "API",
"status": "operational",
"uptime24h": 99.98,
"avgResponseTime": 127,
"sparkline": [120, 118, 131, 127, 125],
"uptime90d": [100, 100, 99.9, 100, ...]
}
],
"components": [...],
"incidents": [...]
}放入你的技术栈
React
export default async function Status() {
const res = await fetch('https://api.pulseapi.tech/status/acme', {
next: { revalidate: 30 },
})
const data = await res.json()
return (
<section>
<h1>{data.page.title}</h1>
<StatusBanner status={data.overallStatus} />
{data.endpoints.map((ep) => (
<EndpointRow key={ep.id} endpoint={ep} />
))}
</section>
)
}Vue / Nuxt
<script setup lang="ts">
const { data } = await useFetch('https://api.pulseapi.tech/status/acme', {
key: 'status',
server: true,
})
</script>
<template>
<h1>{{ data.page.title }}</h1>
<p>Status: {{ data.overallStatus }}</p>
<ul>
<li v-for="ep in data.endpoints" :key="ep.id">
{{ ep.name }} — {{ ep.status }} ({{ ep.uptime24h }}%)
</li>
</ul>
</template>Vanilla JS
async function renderStatus() {
const res = await fetch('https://api.pulseapi.tech/status/acme')
const data = await res.json()
document.getElementById('status').innerHTML = `
<h2>${data.page.title}</h2>
<p>${data.overallStatus}</p>
`
}
renderStatus()
setInterval(renderStatus, 30_000)通过 SSE 实时 — 无需轮询
实时订阅事件更新、状态转换和检查结果。
const es = new EventSource('https://api.pulseapi.tech/sse/status/acme')
es.addEventListener('status:changed', (e) => {
const payload = JSON.parse(e.data)
updateBanner(payload.status)
})
es.addEventListener('incident:created', (e) => {
showNotification(JSON.parse(e.data))
})
es.addEventListener('check:completed', (e) => {
const check = JSON.parse(e.data)
appendToSparkline(check.endpointId, check.responseTime)
})按框架的指南
选择你的技术栈 — 我们提供了可复制粘贴代码的指南。
常见问题
什么是 headless 状态页?
Headless 状态页把数据(正常运行时间、组件、事件)与 UI 分离。不被锁在厂商模板里,而是通过 API 获取数据并以任意方式渲染 — 你自己的 React 组件、服务器渲染页面,甚至终端仪表板。
为什么不直接用你们的托管状态页?
可以 — 开箱即用。但如果你的品牌需要自定义布局、与主站深度集成,或者在自己的域名下无需 CNAME 地渲染,headless 给你完全自由。同样的数据,任何 UI。
API 有速率限制吗?
公共状态端点为高读流量而设计(它驱动着我们自己的托管状态页和嵌入徽章)。合理轮询没问题。超高流量请缓存响应 10–30 秒,或订阅 SSE 流。
能配合静态站点生成器使用吗?
可以。使用 Next.js getStaticProps、Astro frontmatter 或等价机制在构建时获取我们的 API。需要实时更新时,使用短 TTL 的 ISR/revalidate,或把该页面切到服务器渲染。
API 返回什么?
状态页元数据 (标题、品牌)、总体状态、按端点的状态和正常运行时间、组件、活跃事件、用于正常运行条的 90 天数组,以及响应时间 sparkline 数据。完整规范见 api.pulseapi.tech/docs。
需要认证吗?
公共状态端点 — 不需要。这与客户在托管版本中看到的是同一个 URL。仪表板 API (创建端点、写入事件) 需要 API key。
能否订阅实时更新而不是轮询?
可以。连接到 /sse/status/:slug 的 SSE 端点,即时接收状态变化、新事件和检查结果。
私有状态页如何处理认证?
在仪表板中生成组织 API key,并在服务器调用状态端点时作为 Authorization 头发送。绝不要把 key 暴露给浏览器。