API ファースト

ヘッドレスステータスページ。
あなたの UI、私たちのデータ。

当社のステータスページが気に入らない? 自作してください。ホステッド版が表示する全バイトが公開 REST API とリアルタイム SSE ストリームで取得可能。完全な OpenAPI 仕様書付き。

なぜヘッドレスか

他のステータスページベンダーはテンプレートにロックインします。当社はデータを渡しつつ使い続けてもらう方針です。

あなたのブランド、あなたのピクセル

メインサイトと完全一致。カスタムフォント、アニメーション、レイアウト。ベンダーフッターも独自ブランドヘッダーもなし。

どこでも描画

Next.js サーバーコンポーネント、Astro アイランド、静的 HTML、Slack ボット、CLI、アプリ内バナー。同一エンドポイント。

自分のドメインで提供

CNAME 不要。サーバーから取得しアプリ内で描画。顧客にサードパーティ URL を見せません。

移行ではなく統合

ドキュメント、管理パネル、顧客ポータルにステータスウィジェットを追加。サイト外へのリダイレクト不要。

1 つの fetch で全部。

slug 付きでステータスエンドポイントに GET、JSON をパース、描画。

curl
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

app/status/page.tsx
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

pages/status.vue
<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

status.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)
})

フレームワーク別ガイド

スタックを選択 — コピペコード付きのガイドを用意しています。

よくある質問

ヘッドレスステータスページとは?

ヘッドレスステータスページは、データ (稼働率、コンポーネント、インシデント) を UI から分離したものです。ベンダーのテンプレートにロックされず、API からデータを取得し自由に描画できます — 独自 React コンポーネント、サーバー描画ページ、ターミナルダッシュボードでも可能です。

ホステッド版を使えばよいのでは?

使えます — 標準動作します。ただしブランド要件でカスタムレイアウト、メインサイトとの密接な統合、CNAME なしで自ドメインに描画したい場合は、ヘッドレスが完全な自由を提供します。同じデータ、任意の UI。

API にレート制限はありますか?

公開ステータスエンドポイントは大量の読み取りトラフィック向けに設計されています (当社のホステッド版とバッジを駆動しています)。妥当な間隔のポーリングなら問題ありません。超高トラフィックなら 10〜30 秒キャッシュするか SSE ストリームを購読してください。

静的サイトジェネレーターで使えますか?

はい。Next.js の getStaticProps、Astro のフロントマター等でビルド時に取得できます。ライブ更新が必要なら短い TTL の ISR/revalidate、あるいはそのページをサーバー描画に切り替えてください。

API は何を返しますか?

ステータスページのメタデータ (タイトル、ブランディング)、全体ステータス、エンドポイントごとのステータスと稼働率、コンポーネント、アクティブインシデント、Uptime バー用 90 日稼働配列、レスポンスタイム sparkline データ。完全仕様は api.pulseapi.tech/docs。

認証は必要ですか?

公開ステータスエンドポイントには不要です。顧客がホステッド版で見る URL と同じです。ダッシュボード API (エンドポイント作成、インシデント書き込み) には API キーが必要です。

ポーリングの代わりにリアルタイム購読できますか?

はい。/sse/status/:slug の SSE エンドポイントに接続し、ステータス変更、新規インシデント、チェック結果をリアルタイムで受け取れます。

プライベートステータスページの認証は?

ダッシュボードで組織 API キーを生成し、サーバーからステータスエンドポイントを呼ぶ際に Authorization ヘッダで送信してください。キーをブラウザに露出しないこと。

あなたの条件でステータスページを公開

無料プラン、クレジットカード不要。ホステッド、ヘッドレス、または両方。