Communicate

Status pages

Public status pages fed by your monitors: components and groups, the incidents and maintenance you publish, the uptime history, the public JSON and Atom/RSS feeds, plan limits and custom domains.

A status page is a public, read-only page built from two things. The components are monitors you have chosen to show, each under a public label, with their current state and a day-by-day uptime history — that part is generated from the same results the app uses, so it is never behind. The posts are what you write: the incidents and maintenance you decide to announce, each with its own update timeline.

Status pages are configured in the app (Status Pages in the dashboard). The /api/v1/status-pages endpoints are session-authenticated and deliberately not part of the API-key surface — an API key calling them gets 403 FORBIDDEN. The public read endpoints below need no authentication at all. See REST API for the full list of app-only resources.

Page fields

FieldRules
title1–120 characters.
slugLowercase a-z0-9-, 1–63 characters; derived from the title if blank; globally unique across PulseTrace. The public URL is https://dash.pulsetrace.app/status/<slug>.
descriptionUp to 2000 characters, shown under the title.
is_publicWhen off, the public URL returns not-found. Use it to stage a page before announcing it.
window_daysUptime history window, 1–365; default 90. The strip always renders exactly this many day cells.
timezoneAny IANA zone, e.g. Europe/Berlin; default UTC. Every date and time the page shows — day cells, incident timestamps, maintenance windows — is rendered in it.
accent_colorOptional #rrggbb. Tints the page's headings and links.
support_urlOptional full http(s) link (≤ 300 chars) shown in the footer — your help desk or contact page.
hide_from_searchAdds noindex so the page is reachable by link but stays out of search results.
monitors[]Up to 100 entries of {monitor_id, display_name (≤ 80), group_name (≤ 60), sort_order}.
custom_domainPro and above. A hostname such as status.example.com (≤ 253 chars, unique).
white_labelEnterprise. Removes PulseTrace branding from the page.

Components and groups

Each entry in monitors[] becomes one component. display_name is the only name the public ever sees, so an internal api-prod-eu-1 can appear as "API" — the real monitor name, its target and its configuration never leave the auth boundary. group_name is an optional heading ("Platform", "Game services"); components sharing one sit under it and the group gets its own rolled-up state. Leave it blank and the page renders the flat list it always has.

status-page.jsonjson
{
  "title": "Acme status",
  "slug": "acme",
  "is_public": true,
  "window_days": 90,
  "timezone": "Europe/Berlin",
  "accent_color": "#2563eb",
  "support_url": "https://acme.example.com/support",
  "hide_from_search": false,
  "monitors": [
    { "monitor_id": "…", "display_name": "API",
      "group_name": "Platform", "sort_order": 1 },
    { "monitor_id": "…", "display_name": "Dashboard",
      "group_name": "Platform", "sort_order": 2 },
    { "monitor_id": "…", "display_name": "Matchmaking",
      "group_name": "Game services", "sort_order": 3 }
  ]
}

Publishing an incident

Nothing is announced automatically: an incident PulseTrace opens is an operational fact, and whether customers should hear about it is a decision. Publishing one creates a post — POST /api/v1/status-pages/{id}/posts with kind: "incident" — and every post carries a running timeline you add to as you learn more.

FieldValues
kindincident or maintenance.
titleRequired, ≤ 140 characters.
bodyRequired, ≤ 4000 characters — the first update's text, i.e. what customers should know right now.
impactnone · minor (default) · major · critical. Drives the page banner and its colour.
statusinvestigating (default) · identified · monitoring · resolved.
monitor_ids[]Which components this affects. They must already be on the page; the public post names them by their display labels.
incident_idOptional link to the PulseTrace incident this announces. One incident can be published to a given page once — a second attempt returns 409.
started_atDefaults to now; set it to backfill something that began earlier.

Add to the timeline with POST …/posts/{postID}/updates (status + body). Moving a post to resolved stamps resolved_at and drops it out of the active list into the record below; moving it back off resolved clears the stamp. PUT …/posts/{postID} edits the post itself and DELETE removes it — a post is your writing, so it can be corrected or withdrawn.

Maintenance

A maintenance post is the same object with kind: "maintenance". impact is forced to maintenance, and the statuses are scheduled (default) · in_progress · completed. It requires scheduled_for and scheduled_until, and the window must end after it starts. Planned work appears under its own heading before it begins, the affected components read maintenance rather than down while it runs, and the days it covered are marked as planned work in the history strip instead of counting as an outage.

A maintenance window and a maintenance post are different things and you usually want both: the window stops the monitor paging you, the post tells your customers. Link them with maintenance_window_id, which has the same publish-once rule as incident_id.

The public page and its JSON

Visitors see the rendered page; the same view is available as JSON at GET /api/v1/public/status-pages/{slug} (no authentication, cached for 60 seconds) for embedding in your own site or a bot. A page that does not exist and a page with is_public off return an identical 404.

public-status.jsonjson
{
  "title": "Acme status",
  "slug": "acme",
  "window_days": 90,
  "timezone": "Europe/Berlin",
  "accent_color": "#2563eb",
  "support_url": "https://acme.example.com/support",
  "hide_from_search": false,
  "white_label": false,
  "generated_at": "2026-09-22T20:00:00Z",
  // operational | degraded | partial_outage |
  // major_outage | maintenance
  "overall_status": "partial_outage",
  "history_days": 14,        // how far back the posts below reach
  "monitors": [              // flat, in page order
    { "name": "API", "group": "Platform", "status": "operational",
      "uptime_percent": 99.98,
      "days_measured": 90, "days_in_window": 90,
      "history": [
        { "date": "2026-09-22", "uptime_percent": 100 }
      ] }
  ],
  "groups": [                // the same, under their headings
    { "name": "Platform", "status": "operational",
      "uptime_percent": 99.97, "monitors": [] }
  ],
  "active_incidents": [
    { "id": "…", "kind": "incident",
      "title": "Elevated error rates on the API",
      "impact": "major", "status": "identified",
      "started_at": "2026-09-22T18:04:00Z",
      "components": ["API"],
      "updates": [
        { "status": "identified", "body": "…", "created_at": "…" }
      ] }
  ],
  "maintenance": [],         // scheduled and in-progress work
  "past_posts": []           // what happened, in that window
}

A component's status is the public vocabulary — operational, degraded, down, maintenance or unknown — and never the internal monitor state. overall_status and each group's status are rolled up from the components on this page plus the maintenance currently published on it, so a page showing three of your forty monitors is never coloured by the other thirty-seven.

Uptime history, honestly

days_measured and days_in_window sit next to every uptime figure. A component created four days ago cannot claim ninety days of uptime, and the page says "4 of 90 days measured" rather than implying a record it does not have. Days with published maintenance are marked maintenance: true in the strip so planned work never reads as an outage.

Feeds

Every page publishes its posts as Atom and RSS — the one way to follow a status page that needs no address, no confirmation and nothing to unsubscribe from:

  • GET /api/v1/public/status-pages/{slug}/feed.atom
  • GET /api/v1/public/status-pages/{slug}/feed.rss

Both carry up to 50 posts from the last year, each entry holding the post's title, its impact or window, the components it names and its full update timeline in the page's timezone. The public page links to them in its footer and advertises them in <link rel="alternate">, so a reader app finds them from the page URL alone.

Plan limits

PlanPagesCustom domainWhite-label
Free1——
Team5——
ProUnlimitedYes—
EnterpriseUnlimitedYesYes

Components, groups, posts and feeds are on every plan, including Free.

Custom domains: current state

In the current build the custom domain is stored but not yet served: there is no DNS verification step and no automatic certificate for it. Point a CNAME at PulseTrace after saving; DNS verification and certificate issuance are in progress and this page will be updated when they ship. Until then the page is reachable at its /status/<slug> URL.
  • Trust pages publish security grades alongside uptime for one monitor or the whole organization.
  • Maintenance windows keep planned work from opening incidents in the first place.
  • Incidents are the internal record a published post can be linked to.

Try it on your own endpoints.

Ten monitors, one region and a status page are free — no card.

Start free