1. Documentation
  2. Configuration
  3. Metrics and badges
ReadmenpmGitHub
  • Introduction
  • Quickstart
  • Configuration file
  • Monitors
  • Checks and scheduling
  • Notifications
  • Incidents and maintenance
  • Subscribers
  • Metrics and badges
  • Identity and appearance
  • Telemetry
  • The check run
  • Uptime and history
  • Automatic incidents
  • Notification delivery
  • Public subscriptions
  • StatusPage component
  • Themes
  • UI primitives
  • Colour mode
  • React Router
  • Next.js
  • Astro
  • SQLite
  • Cloudflare D1
  • PostgreSQL
  • Schema and migrations
  • Cloudflare Workers
  • Vercel
  • Self-hosting
  • API overview
  • Status endpoints
  • Incident and maintenance endpoints
  • Subscriber endpoints
  • Badges, feeds and metrics
  • Admin endpoints
  • CLI commands
  • Package exports
  • Security
  • Troubleshooting

Metrics and badges

Control what the page shows, and expose badges and Prometheus metrics.

metrics does two jobs: it decides which numbers the UI renders, and it enables the two machine-readable surfaces — SVG badges and a Prometheus exposition.

ts
metrics: {  showLatency: true,  showLatencyChart: true,  showUptimePercent: true,  uptimePeriods: ["24h", "7d", "30d", "90d"],  badges: true,  prometheus: false,},
showLatencybooleanoptional

Defaults to true. Shows the most recent latency on monitor cards.

showLatencyChartbooleanoptional

Defaults to true. Renders the latency sparkline.

showUptimePercentbooleanoptional

Defaults to true. Shows the uptime meters.

uptimePeriods("24h" | "7d" | "30d" | "90d")[]optional

Defaults to all four. Which meters appear, in order. No duplicates.

badgesbooleanoptional

Defaults to true. Serves /badge/:name.svg.

prometheusbooleanoptional

Defaults to false. Serves /metrics when enabled.

The first four options are presentation only — the data is always computed and always available over the API. They are forwarded to the UI through the metrics prop:

tsx
<StatusPage snapshot={snapshot} metrics={statusPage.metrics} />
Periods are bounded by displayDays

A 90d meter can only report what exists. With checks.displayDays: 30 the 90-day value covers 30 days of history, because nothing older is read.

Badges

text
GET /api/heyo-status/badge/API.svgGET /api/heyo-status/badge/overall.svg?metric=statusGET /api/heyo-status/badge/API.svg?metric=uptime&period=30dGET /api/heyo-status/badge/API.svg?metric=latency&label=Latency
QueryValuesDefault
metricstatus, uptime, latencystatus
period24h, 7d, 30d, 90d24h (uptime only)
labelany stringthe monitor name, or status

The reserved name overall renders the page-level state. Percent-encode names containing spaces: /badge/Web%20App.svg.

Badges are SVG, served with cache-control: public, max-age=60, which keeps an embedded badge fresh without turning every README view into a database read. Colours follow the value: green above 99.9% uptime or healthy, amber above 95% or degraded, red below, grey when there is no data.

md
![API](https://status.acme.com/api/heyo-status/badge/API.svg)![Uptime](https://status.acme.com/api/heyo-status/badge/API.svg?metric=uptime&period=30d)

With badges: false, the route answers 404.

Prometheus

Set prometheus: true to register /metrics, served as text/plain; version=0.0.4.

MetricLabelsMeaning
heyo_status_upmonitor, type, group1 operational, 0 failing.
heyo_status_latency_millisecondsmonitor, type, groupLatency of the most recent check.
heyo_status_uptime_ratiomonitor, periodUptime per period, 0–1.
heyo_status_last_check_timestamp_secondsmonitorUnix time of the last check.
heyo_status_overallstateOne-hot overall state.
heyo_status_monitors—Number of public monitors.
heyo_status_active_incidents—Count of active incidents.
heyo_status_scheduled_maintenances—Count of scheduled or running windows.
heyo_status_snapshot_timestamp_seconds—When the snapshot was generated.
prometheus.yml
scrape_configs:  - job_name: heyo-status    metrics_path: /api/heyo-status/metrics    scheme: https    static_configs:      - targets: ["status.acme.com"]

Only aggregate, already-public data is exposed: no incident text, no monitor targets, and nothing from a private monitor.

/metrics is public

The exposition is not behind the admin token. If a scrape endpoint should not be world-readable, keep prometheus: false and read the same numbers from /status behind your own gateway, or restrict the path at the edge.

Generate the same exposition yourself from any snapshot:

ts
import { createPrometheusMetrics, prometheusContentType } from "@heyo-sh/heyo-status/metrics";const body = createPrometheusMetrics(await statusPage.api.getSnapshot());return new Response(body, { headers: { "content-type": prometheusContentType } });

Building badges programmatically

ts
import { createMonitorBadge, createOverallBadge } from "@heyo-sh/heyo-status/badge";const snapshot = await statusPage.api.getSnapshot();const monitor = snapshot.monitors.find((candidate) => candidate.name === "API")!;createMonitorBadge(monitor, { metric: "uptime", period: "30d", label: "API uptime" });createOverallBadge(snapshot, { label: "Acme" });

Related

  • Badge, feed and metric endpoints
  • How uptime is calculated
  • Status page props
Subscribers< PreviousIdentity and appearanceNext >

Powered by heyo

On this page

BadgesPrometheusBuilding badges programmatically