Status Page Service #
Manage status pages, components, component groups, and subscribers. The Status Page Service provides 19 RPC methods.
Status Page CRUD #
Create Status Page #
const { statusPage } = await client.statusPage.v1.StatusPageService
.createStatusPage({
title: "My Service Status",
slug: "my-service",
description: "Status page for My Service",
homepageUrl: "https://example.com",
contactUrl: "https://example.com/contact",
});
console.log(`Status page created: ${statusPage?.id}`);
Custom Theme #
customTheme holds per-mode CSS variable overrides that are merged over the
page theme. Both light and dark are plain Record<string, string> maps
keyed by CSS variable name, and the field is only set when configured.
const { statusPage } = await client.statusPage.v1.StatusPageService
.updateStatusPage({
id: "page_123",
customTheme: {
light: { "--primary": "hsl(24 94% 50%)", "--radius": "0.75rem" },
dark: { "--primary": "hsl(24 94% 60%)" },
},
});
console.log(statusPage?.customTheme?.light["--primary"]);
Get Status Page #
const { statusPage } = await client.statusPage.v1.StatusPageService
.getStatusPage({ id: "page_123" });
List Status Pages #
const { statusPages, totalSize } = await client.statusPage.v1.StatusPageService
.listStatusPages({ limit: 10, offset: 0 });
console.log(`Found ${totalSize} status pages`);
Update Status Page #
const { statusPage } = await client.statusPage.v1.StatusPageService
.updateStatusPage({
id: "page_123",
title: "Updated Title",
description: "Updated description",
});
Delete Status Page #
const { success } = await client.statusPage.v1.StatusPageService
.deleteStatusPage({ id: "page_123" });
Components #
Components represent individual services on a status page. They can be linked to a monitor (automatically reflects monitor status) or static (manually managed).
Add Monitor Component #
const { component } = await client.statusPage.v1.StatusPageService
.addMonitorComponent({
pageId: "page_123",
monitorId: "123457",
name: "API Server",
description: "Main API endpoint",
order: 1,
groupId: "group_789",
});
Add Static Component #
const { component } = await client.statusPage.v1.StatusPageService
.addStaticComponent({
pageId: "page_123",
name: "Third-party Service",
description: "External dependency",
order: 2,
});
Update Component #
const { component } = await client.statusPage.v1.StatusPageService
.updateComponent({
id: "comp_123",
name: "Updated Component Name",
description: "Updated description",
order: 3,
groupId: "group_789",
groupOrder: 1,
});
Remove Component #
const { success } = await client.statusPage.v1.StatusPageService
.removeComponent({ id: "comp_123" });
Get Page Component #
Returns a single component by ID, scoped to the authenticated workspace. Use it
to resolve a component ID to its name (and other fields) instead of fetching the
whole page with getStatusPageContent and filtering .components.
const { component } = await client.statusPage.v1.StatusPageService
.getPageComponent({ id: "comp_123" });
console.log(`${component?.name}: ${component?.description}`);
Component Groups #
Group related components together on a status page.
Create Component Group #
const { group } = await client.statusPage.v1.StatusPageService
.createComponentGroup({
pageId: "page_123",
name: "Core Services",
});
Update Component Group #
const { group } = await client.statusPage.v1.StatusPageService
.updateComponentGroup({
id: "group_123",
name: "Updated Group Name",
});
Delete Component Group #
const { success } = await client.statusPage.v1.StatusPageService
.deleteComponentGroup({ id: "group_123" });
Subscribers #
Manage email and webhook subscriptions to status page updates.
Subscribe to Page #
Self-signup with double opt-in: a verification email is sent and the subscription activates only after the recipient confirms.
const { subscriber } = await client.statusPage.v1.StatusPageService
.subscribeToPage({
pageId: "page_123",
email: "user@example.com",
});
Create Page Subscription #
Operator-added subscriber (email or webhook) with no verification flow — use it
when consent is established out-of-band. Set exactly one channel via the
channel oneof. Webhook payload flavor (Slack / Discord / generic) is
auto-detected from the URL.
// Email channel
const { subscriber } = await client.statusPage.v1.StatusPageService
.createPageSubscription({
pageId: "page_123",
name: "Partner #incidents", // optional label
componentIds: ["comp_456"], // optional scope, empty = entire page
channel: { case: "emailChannel", value: { email: "partner@example.com" } },
});
// Webhook channel
const { subscriber: webhookSub } = await client.statusPage.v1.StatusPageService
.createPageSubscription({
pageId: "page_123",
channel: {
case: "webhookChannel",
value: {
webhookUrl: "https://hooks.slack.com/services/...",
headers: [{ key: "Authorization", value: "Bearer token" }], // optional
},
},
});
Unsubscribe from Page #
Unsubscribe by email or subscriber ID using the identifier oneof:
// By email
const { success } = await client.statusPage.v1.StatusPageService
.unsubscribeFromPage({
pageId: "page_123",
identifier: { case: "email", value: "user@example.com" },
});
// By subscriber ID
const { success: success2 } = await client.statusPage.v1.StatusPageService
.unsubscribeFromPage({
pageId: "page_123",
identifier: { case: "id", value: "sub_456" },
});
List Subscribers #
const { subscribers, totalSize } = await client.statusPage.v1.StatusPageService
.listSubscribers({
pageId: "page_123",
limit: 50,
offset: 0,
includeUnsubscribed: false,
});
Get Status Page Content #
Get the full content of a status page including components, groups, active status reports, and maintenance windows. Identify the page by ID or slug.
const content = await client.statusPage.v1.StatusPageService
.getStatusPageContent({
identifier: { case: "slug", value: "my-service" },
});
console.log(`Page: ${content.statusPage?.title}`);
console.log(`Components: ${content.components.length}`);
console.log(`Groups: ${content.groups.length}`);
console.log(`Active reports: ${content.statusReports.length}`);
console.log(`Maintenances: ${content.maintenances.length}`);
Get Overall Status #
Get the aggregated status of a status page and per-component statuses.
import { createOpenStatusClient, OverallStatus } from "@openstatus/sdk-node";
const client = createOpenStatusClient({
apiKey: process.env.OPENSTATUS_API_KEY,
});
const { overallStatus, componentStatuses } = await client.statusPage.v1
.StatusPageService.getOverallStatus({
identifier: { case: "id", value: "page_123" },
});
console.log(`Overall: ${OverallStatus[overallStatus]}`);
for (const { componentId, status } of componentStatuses) {
console.log(` ${componentId}: ${OverallStatus[status]}`);
}
Get Status Page Overview #
Everything about a single status page in one authenticated call: the page, its
rich rendering configuration, components, groups, active/recent status reports,
maintenances, and the computed overall + per-component statuses.
Workspace-scoped by id — unlike getStatusPageContent there is no public slug
access path. It does not include uptime time series; use
Get Page Component Daily Summary for that.
import {
createOpenStatusClient,
OverallStatus,
PageBarType,
PageMetricType,
} from "@openstatus/sdk-node";
const client = createOpenStatusClient({
apiKey: process.env.OPENSTATUS_API_KEY,
});
const overview = await client.statusPage.v1.StatusPageService
.getStatusPageOverview({ id: "page_123" });
console.log(`Page: ${overview.statusPage?.title}`);
console.log(`Overall: ${OverallStatus[overview.overallStatus]}`);
console.log(`Components: ${overview.components.length}`);
console.log(`Groups: ${overview.groups.length}`);
console.log(`Reports: ${overview.statusReports.length}`);
console.log(`Maintenances: ${overview.maintenances.length}`);
const config = overview.configuration;
if (config) {
console.log(
`Bars: ${PageMetricType[config.metricType]} / ` +
`${PageBarType[config.barType]} over ${config.days} days ` +
`(uptime shown: ${config.showUptime}, theme: ${config.themeKey})`,
);
}
for (const { componentId, status } of overview.componentStatuses) {
console.log(` ${componentId}: ${OverallStatus[status]}`);
}
configuration is a PageConfiguration with metricType
(PageMetricType), barType
(PageBarType), showUptime, themeKey (free-form
string from the theme catalog), and days (30 or 45).
Get Page Component Daily Summary #
Per-component daily status buckets (ok/degraded/error/count plus a
resolved status) merged with the incident, maintenance, and status-report
timeline over the last N days (max 45). This is the single source of truth for
rendering status bars and uptime calendars. Identify the page by ID
(authenticated) or slug (public, requires a published PUBLIC page).
import {
ComponentDayStatus,
createOpenStatusClient,
} from "@openstatus/sdk-node";
const client = createOpenStatusClient({
apiKey: process.env.OPENSTATUS_API_KEY,
});
const { components } = await client.statusPage.v1.StatusPageService
.getPageComponentDailySummary({
identifier: { case: "id", value: "page_123" },
componentIds: [], // optional, empty = all components
days: 45, // optional, 1–45, defaults to 45
});
for (const component of components) {
console.log(`${component.name} (${component.componentId})`);
for (const bucket of component.buckets) {
console.log(
` ${bucket.day}: ${bucket.ok}/${bucket.count} ok, ` +
`${bucket.degraded} degraded, ${bucket.error} error ` +
`[${ComponentDayStatus[bucket.status]}]`,
);
}
for (const event of component.events) {
console.log(
` event: ${event.name} (${event.from} → ${event.to ?? "ongoing"})`,
);
}
}
Each PageComponentDailySummary has componentId, type
(PageComponentType), optional monitorId, name, buckets[], and
events[]. Each ComponentDayBucket has day (RFC 3339, UTC midnight), the
bigint counts count/ok/degraded/error, a resolved status
(ComponentDayStatus), and an optional impact (PageComponentImpact). Each
ComponentEvent has id, name, type (ComponentEventType), status
(ComponentEventStatus), from, optional to, and optional impact.