···11+[← Back to index](./index.md)
22+33+# Authentication
44+55+## Recommended: createOpenStatusClient
66+77+Create a client with your API key. The key is automatically included in all requests via an interceptor.
88+99+```typescript
1010+import { createOpenStatusClient } from "@openstatus/sdk-node";
1111+1212+const client = createOpenStatusClient({
1313+ apiKey: process.env.OPENSTATUS_API_KEY,
1414+});
1515+1616+// No headers needed on individual calls
1717+const { httpMonitors } = await client.monitor.v1.MonitorService.listMonitors({});
1818+```
1919+2020+## Alternative: Manual Headers
2121+2222+Use the default `openstatus` client and pass headers on each call.
2323+2424+```typescript
2525+import { openstatus } from "@openstatus/sdk-node";
2626+2727+const headers = {
2828+ "x-openstatus-key": process.env.OPENSTATUS_API_KEY,
2929+};
3030+3131+await openstatus.monitor.v1.MonitorService.listMonitors({}, { headers });
3232+```
3333+3434+## Environment Variables
3535+3636+| Variable | Description | Default |
3737+|----------|-------------|---------|
3838+| `OPENSTATUS_API_KEY` | Your OpenStatus API key | Required for authenticated calls |
3939+| `OPENSTATUS_API_URL` | Custom API endpoint | `https://api.openstatus.dev/rpc` |
4040+4141+Get your API key from the [OpenStatus dashboard](https://www.openstatus.dev/app).
4242+4343+## Custom Base URL
4444+4545+For self-hosted instances or staging environments:
4646+4747+```typescript
4848+import { createOpenStatusClient } from "@openstatus/sdk-node";
4949+5050+const client = createOpenStatusClient({
5151+ apiKey: process.env.OPENSTATUS_API_KEY,
5252+ baseUrl: "https://api.staging.example.com/rpc",
5353+});
5454+```
5555+5656+The `baseUrl` option takes precedence over the `OPENSTATUS_API_URL` environment variable.
+59
docs/error-handling.md
···11+[← Back to index](./index.md)
22+33+# Error Handling
44+55+The SDK uses ConnectRPC. Errors are thrown as `ConnectError` instances from the `@connectrpc/connect` package.
66+77+```typescript
88+import { ConnectError } from "@connectrpc/connect";
99+1010+try {
1111+ await client.monitor.v1.MonitorService.deleteMonitor({ id: "invalid" });
1212+} catch (error) {
1313+ if (error instanceof ConnectError) {
1414+ console.error(`Code: ${error.code}`);
1515+ console.error(`Message: ${error.message}`);
1616+ }
1717+}
1818+```
1919+2020+## Common Error Codes
2121+2222+| Code | Description |
2323+|------|-------------|
2424+| `unauthenticated` | Missing or invalid API key |
2525+| `not_found` | Resource does not exist |
2626+| `invalid_argument` | Validation failure (e.g., missing required field, value out of range) |
2727+| `permission_denied` | No access to this workspace or resource |
2828+| `already_exists` | Duplicate resource (e.g., slug already taken) |
2929+3030+## Retry Strategy
3131+3232+ConnectRPC does not retry by default. For transient failures (`unavailable`, `deadline_exceeded`), implement your own retry logic:
3333+3434+```typescript
3535+import { ConnectError } from "@connectrpc/connect";
3636+3737+async function withRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {
3838+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
3939+ try {
4040+ return await fn();
4141+ } catch (error) {
4242+ if (
4343+ error instanceof ConnectError &&
4444+ (error.code === "unavailable" || error.code === "deadline_exceeded") &&
4545+ attempt < maxRetries
4646+ ) {
4747+ await new Promise((resolve) => setTimeout(resolve, 1000 * 2 ** attempt));
4848+ continue;
4949+ }
5050+ throw error;
5151+ }
5252+ }
5353+ throw new Error("Unreachable");
5454+}
5555+5656+const { httpMonitors } = await withRetry(() =>
5757+ client.monitor.v1.MonitorService.listMonitors({})
5858+);
5959+```
+140
docs/getting-started.md
···11+[← Back to index](./index.md)
22+33+# Getting Started
44+55+## Installation
66+77+### npm
88+99+```bash
1010+npm install @openstatus/sdk-node
1111+```
1212+1313+### JSR
1414+1515+```bash
1616+npx jsr add @openstatus/sdk-node
1717+```
1818+1919+### Deno
2020+2121+```typescript
2222+import { createOpenStatusClient } from "jsr:@openstatus/sdk-node";
2323+```
2424+2525+### Bun
2626+2727+```bash
2828+bun add @openstatus/sdk-node
2929+```
3030+3131+## Quick Start
3232+3333+```typescript
3434+import {
3535+ createOpenStatusClient,
3636+ Periodicity,
3737+ Region,
3838+} from "@openstatus/sdk-node";
3939+4040+const client = createOpenStatusClient({
4141+ apiKey: process.env.OPENSTATUS_API_KEY,
4242+});
4343+4444+// Create an HTTP monitor
4545+const { monitor } = await client.monitor.v1.MonitorService.createHTTPMonitor({
4646+ monitor: {
4747+ name: "My API",
4848+ url: "https://api.example.com/health",
4949+ periodicity: Periodicity.PERIODICITY_1M,
5050+ regions: [Region.FLY_AMS, Region.FLY_IAD, Region.FLY_SYD],
5151+ active: true,
5252+ },
5353+});
5454+5555+console.log(`Monitor created: ${monitor?.id}`);
5656+5757+// List all monitors
5858+const { httpMonitors, tcpMonitors, dnsMonitors, totalSize } =
5959+ await client.monitor.v1.MonitorService.listMonitors({});
6060+6161+console.log(`Found ${totalSize} monitors`);
6262+```
6363+6464+## Runtime Support
6565+6666+| Runtime | Version | Module Format |
6767+|---------|---------|---------------|
6868+| Node.js | >= 18 | ESM and CJS |
6969+| Deno | >= 2 | ESM (native) |
7070+| Bun | Latest | ESM |
7171+7272+## Full Workflow Example
7373+7474+A complete example: create a monitor, set up a status page, add the monitor as a component, configure a Slack notification, and check overall status.
7575+7676+```typescript
7777+import {
7878+ createOpenStatusClient,
7979+ NotificationProvider,
8080+ Periodicity,
8181+ Region,
8282+} from "@openstatus/sdk-node";
8383+8484+const client = createOpenStatusClient({
8585+ apiKey: process.env.OPENSTATUS_API_KEY,
8686+});
8787+8888+// 1. Check API health
8989+const health = await client.health.v1.HealthService.check({});
9090+console.log(`API status: ${health.status}`);
9191+9292+// 2. Create an HTTP monitor
9393+const { monitor } = await client.monitor.v1.MonitorService.createHTTPMonitor({
9494+ monitor: {
9595+ name: "Production API",
9696+ url: "https://api.example.com/health",
9797+ periodicity: Periodicity.PERIODICITY_1M,
9898+ regions: [Region.FLY_AMS, Region.FLY_IAD, Region.FLY_SYD],
9999+ active: true,
100100+ },
101101+});
102102+103103+// 3. Create a status page
104104+const { statusPage } = await client.statusPage.v1.StatusPageService
105105+ .createStatusPage({
106106+ title: "Example Status",
107107+ slug: "example-status",
108108+ description: "Status page for Example services",
109109+ });
110110+111111+// 4. Add the monitor as a component
112112+const { component } = await client.statusPage.v1.StatusPageService
113113+ .addMonitorComponent({
114114+ pageId: statusPage!.id,
115115+ monitorId: monitor!.id,
116116+ name: "Production API",
117117+ });
118118+119119+// 5. Set up Slack notifications
120120+const { notification } = await client.notification.v1.NotificationService
121121+ .createNotification({
122122+ name: "Slack Alerts",
123123+ provider: NotificationProvider.SLACK,
124124+ data: {
125125+ data: {
126126+ case: "slack",
127127+ value: { webhookUrl: "https://hooks.slack.com/services/..." },
128128+ },
129129+ },
130130+ monitorIds: [monitor!.id],
131131+ });
132132+133133+// 6. Check overall status
134134+const { overallStatus } = await client.statusPage.v1.StatusPageService
135135+ .getOverallStatus({
136136+ identifier: { case: "id", value: statusPage!.id },
137137+ });
138138+139139+console.log(`Overall status: ${overallStatus}`);
140140+```
+22
docs/health-service.md
···11+[← Back to index](./index.md)
22+33+# Health Service
44+55+Check API health status. No authentication required.
66+77+```typescript
88+import { openstatus, ServingStatus } from "@openstatus/sdk-node";
99+1010+const { status } = await openstatus.health.v1.HealthService.check({});
1111+console.log(ServingStatus[status]); // "SERVING"
1212+```
1313+1414+Or with a configured client:
1515+1616+```typescript
1717+import { createOpenStatusClient, ServingStatus } from "@openstatus/sdk-node";
1818+1919+const client = createOpenStatusClient();
2020+const { status } = await client.health.v1.HealthService.check({});
2121+console.log(ServingStatus[status]); // "SERVING"
2222+```
+65
docs/index.md
···11+# OpenStatus Node.js SDK Documentation
22+33+Official documentation for [`@openstatus/sdk-node`](https://www.npmjs.com/package/@openstatus/sdk-node) — the TypeScript SDK for the [OpenStatus](https://openstatus.dev) monitoring platform.
44+55+---
66+77+## Table of Contents
88+99+- [Getting Started](./getting-started.md)
1010+ - Installation
1111+ - Quick Start
1212+ - Runtime Support
1313+ - Full Workflow Example
1414+- [Authentication](./authentication.md)
1515+ - createOpenStatusClient
1616+ - Manual Headers
1717+ - Environment Variables
1818+ - Custom Base URL
1919+- [Monitor Service](./monitor-service.md)
2020+ - HTTP Monitors
2121+ - TCP Monitors
2222+ - DNS Monitors
2323+ - List Monitors
2424+ - Get Monitor
2525+ - Trigger Monitor
2626+ - Delete Monitor
2727+ - Get Monitor Status
2828+ - Get Monitor Summary
2929+- [Status Page Service](./status-page-service.md)
3030+ - Status Page CRUD
3131+ - Components
3232+ - Component Groups
3333+ - Subscribers
3434+ - Get Status Page Content
3535+ - Get Overall Status
3636+- [Status Report Service](./status-report-service.md)
3737+ - Create Status Report
3838+ - Add Status Report Update
3939+ - List Status Reports
4040+ - Get / Update / Delete Status Reports
4141+- [Maintenance Service](./maintenance-service.md)
4242+ - Create Maintenance Window
4343+ - List Maintenances
4444+ - Get / Update / Delete Maintenance Windows
4545+- [Notification Service](./notification-service.md)
4646+ - Create Notification
4747+ - Provider Configurations
4848+ - Send Test Notification
4949+ - Check Notification Limits
5050+ - List / Get / Update / Delete Notifications
5151+- [Health Service](./health-service.md)
5252+ - Health Check
5353+- [Reference](./reference.md)
5454+ - Enums
5555+ - Regions
5656+ - Assertions
5757+ - TypeScript Type Exports
5858+- [Error Handling](./error-handling.md)
5959+ - ConnectError
6060+ - Common Error Codes
6161+ - Retry Strategy
6262+- [TypeScript Tips](./typescript-tips.md)
6363+ - Working with bigint Fields
6464+ - Handling oneof Types
6565+ - Migrating from Default Client to createOpenStatusClient
+70
docs/maintenance-service.md
···11+[← Back to index](./index.md)
22+33+# Maintenance Service
44+55+Manage scheduled maintenance windows. The Maintenance Service provides 5 RPC methods.
66+77+## Create Maintenance Window
88+99+```typescript
1010+const { maintenance } = await client.maintenance.v1.MaintenanceService
1111+ .createMaintenance({
1212+ title: "Database Upgrade",
1313+ message: "We will be upgrading our database infrastructure.",
1414+ from: "2024-01-20T02:00:00Z",
1515+ to: "2024-01-20T04:00:00Z",
1616+ pageId: "page_123",
1717+ pageComponentIds: ["comp_456"],
1818+ notify: true,
1919+ });
2020+2121+console.log(`Maintenance created: ${maintenance?.id}`);
2222+```
2323+2424+All date fields (`from`, `to`) must be in RFC 3339 format.
2525+2626+## List Maintenances
2727+2828+List maintenance windows with optional page filtering.
2929+3030+```typescript
3131+const { maintenances, totalSize } = await client.maintenance.v1
3232+ .MaintenanceService.listMaintenances({
3333+ limit: 10,
3434+ offset: 0,
3535+ pageId: "page_123",
3636+ });
3737+3838+console.log(`Found ${totalSize} maintenance windows`);
3939+```
4040+4141+## Get / Update / Delete Maintenance Windows
4242+4343+### Get Maintenance
4444+4545+```typescript
4646+const { maintenance } = await client.maintenance.v1.MaintenanceService
4747+ .getMaintenance({ id: "maint_123" });
4848+4949+console.log(`Title: ${maintenance?.title}`);
5050+console.log(`From: ${maintenance?.from}`);
5151+console.log(`To: ${maintenance?.to}`);
5252+```
5353+5454+### Update Maintenance
5555+5656+```typescript
5757+const { maintenance } = await client.maintenance.v1.MaintenanceService
5858+ .updateMaintenance({
5959+ id: "maint_123",
6060+ title: "Extended Database Upgrade",
6161+ to: "2024-01-20T06:00:00Z",
6262+ });
6363+```
6464+6565+### Delete Maintenance
6666+6767+```typescript
6868+const { success } = await client.maintenance.v1.MaintenanceService
6969+ .deleteMaintenance({ id: "maint_123" });
7070+```
+346
docs/monitor-service.md
···11+[← Back to index](./index.md)
22+33+# Monitor Service
44+55+Manage HTTP, TCP, and DNS monitors. The Monitor Service provides 12 RPC methods for creating, updating, listing, triggering, deleting, and querying monitor status and metrics.
66+77+All examples assume you have created a client:
88+99+```typescript
1010+import { createOpenStatusClient } from "@openstatus/sdk-node";
1111+1212+const client = createOpenStatusClient({
1313+ apiKey: process.env.OPENSTATUS_API_KEY,
1414+});
1515+```
1616+1717+## HTTP Monitors
1818+1919+### Create HTTP Monitor
2020+2121+```typescript
2222+import {
2323+ createOpenStatusClient,
2424+ HTTPMethod,
2525+ NumberComparator,
2626+ Periodicity,
2727+ Region,
2828+ StringComparator,
2929+} from "@openstatus/sdk-node";
3030+3131+const client = createOpenStatusClient({
3232+ apiKey: process.env.OPENSTATUS_API_KEY,
3333+});
3434+3535+const { monitor } = await client.monitor.v1.MonitorService.createHTTPMonitor({
3636+ monitor: {
3737+ name: "My API",
3838+ url: "https://api.example.com/health",
3939+ periodicity: Periodicity.PERIODICITY_1M,
4040+ method: HTTPMethod.HTTP_METHOD_GET,
4141+ regions: [Region.FLY_AMS, Region.FLY_IAD, Region.FLY_SYD],
4242+ active: true,
4343+ timeout: BigInt(30000),
4444+ retry: BigInt(3),
4545+ followRedirects: true,
4646+ degradedAt: BigInt(5000),
4747+ headers: [
4848+ { key: "Authorization", value: "Bearer my-token" },
4949+ ],
5050+ statusCodeAssertions: [
5151+ { comparator: NumberComparator.EQUAL, target: BigInt(200) },
5252+ ],
5353+ bodyAssertions: [
5454+ { comparator: StringComparator.CONTAINS, target: '"status":"ok"' },
5555+ ],
5656+ headerAssertions: [
5757+ {
5858+ key: "content-type",
5959+ comparator: StringComparator.CONTAINS,
6060+ target: "application/json",
6161+ },
6262+ ],
6363+ description: "Health check for the production API",
6464+ public: false,
6565+ openTelemetry: {
6666+ endpoint: "https://otel.example.com/v1/traces",
6767+ headers: [{ key: "Authorization", value: "Bearer otel-token" }],
6868+ },
6969+ },
7070+});
7171+7272+console.log(`Created monitor: ${monitor?.id}`);
7373+```
7474+7575+### Update HTTP Monitor
7676+7777+Updates are partial — only include the fields you want to change.
7878+7979+```typescript
8080+const { monitor } = await client.monitor.v1.MonitorService.updateHTTPMonitor({
8181+ id: "mon_123",
8282+ monitor: {
8383+ name: "Updated API Monitor",
8484+ active: false,
8585+ },
8686+});
8787+```
8888+8989+### HTTP Monitor Options
9090+9191+| Option | Type | Required | Description |
9292+|--------|------|----------|-------------|
9393+| `name` | string | Yes | Monitor name (max 256 chars) |
9494+| `url` | string | Yes | URL to monitor (max 2048 chars) |
9595+| `periodicity` | Periodicity | Yes | Check interval |
9696+| `method` | HTTPMethod | No | HTTP method (default: GET) |
9797+| `body` | string | No | Request body |
9898+| `headers` | Headers[] | No | Custom headers `{ key, value }[]` |
9999+| `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) |
100100+| `retry` | bigint | No | Retry attempts (default: 3, max: 10) |
101101+| `followRedirects` | boolean | No | Follow redirects (default: true) |
102102+| `regions` | Region[] | No | Regions for checks |
103103+| `active` | boolean | No | Enable monitoring (default: false) |
104104+| `public` | boolean | No | Public visibility (default: false) |
105105+| `degradedAt` | bigint | No | Latency threshold (ms) for degraded status |
106106+| `description` | string | No | Monitor description (max 1024 chars) |
107107+| `statusCodeAssertions` | StatusCodeAssertion[] | No | Status code assertions |
108108+| `bodyAssertions` | BodyAssertion[] | No | Body assertions |
109109+| `headerAssertions` | HeaderAssertion[] | No | Header assertions |
110110+| `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration |
111111+112112+## TCP Monitors
113113+114114+### Create TCP Monitor
115115+116116+```typescript
117117+import {
118118+ createOpenStatusClient,
119119+ Periodicity,
120120+ Region,
121121+} from "@openstatus/sdk-node";
122122+123123+const client = createOpenStatusClient({
124124+ apiKey: process.env.OPENSTATUS_API_KEY,
125125+});
126126+127127+const { monitor } = await client.monitor.v1.MonitorService.createTCPMonitor({
128128+ monitor: {
129129+ name: "Database",
130130+ uri: "db.example.com:5432",
131131+ periodicity: Periodicity.PERIODICITY_5M,
132132+ regions: [Region.FLY_AMS, Region.FLY_IAD],
133133+ active: true,
134134+ },
135135+});
136136+```
137137+138138+### Update TCP Monitor
139139+140140+```typescript
141141+const { monitor } = await client.monitor.v1.MonitorService.updateTCPMonitor({
142142+ id: "mon_123",
143143+ monitor: {
144144+ name: "Updated Database Monitor",
145145+ },
146146+});
147147+```
148148+149149+### TCP Monitor Options
150150+151151+| Option | Type | Required | Description |
152152+|--------|------|----------|-------------|
153153+| `name` | string | Yes | Monitor name (max 256 chars) |
154154+| `uri` | string | Yes | `host:port` to monitor (max 2048 chars) |
155155+| `periodicity` | Periodicity | Yes | Check interval |
156156+| `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) |
157157+| `retry` | bigint | No | Retry attempts (default: 3, max: 10) |
158158+| `regions` | Region[] | No | Regions for checks |
159159+| `active` | boolean | No | Enable monitoring (default: false) |
160160+| `public` | boolean | No | Public visibility (default: false) |
161161+| `degradedAt` | bigint | No | Latency threshold (ms) for degraded status |
162162+| `description` | string | No | Monitor description (max 1024 chars) |
163163+| `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration |
164164+165165+## DNS Monitors
166166+167167+### Create DNS Monitor
168168+169169+```typescript
170170+import {
171171+ createOpenStatusClient,
172172+ Periodicity,
173173+ RecordComparator,
174174+ Region,
175175+} from "@openstatus/sdk-node";
176176+177177+const client = createOpenStatusClient({
178178+ apiKey: process.env.OPENSTATUS_API_KEY,
179179+});
180180+181181+const { monitor } = await client.monitor.v1.MonitorService.createDNSMonitor({
182182+ monitor: {
183183+ name: "DNS Check",
184184+ uri: "example.com",
185185+ periodicity: Periodicity.PERIODICITY_10M,
186186+ regions: [Region.FLY_AMS],
187187+ active: true,
188188+ recordAssertions: [
189189+ {
190190+ record: "A",
191191+ comparator: RecordComparator.EQUAL,
192192+ target: "93.184.216.34",
193193+ },
194194+ {
195195+ record: "CNAME",
196196+ comparator: RecordComparator.CONTAINS,
197197+ target: "cdn",
198198+ },
199199+ ],
200200+ },
201201+});
202202+```
203203+204204+### Update DNS Monitor
205205+206206+```typescript
207207+const { monitor } = await client.monitor.v1.MonitorService.updateDNSMonitor({
208208+ id: "mon_123",
209209+ monitor: {
210210+ name: "Updated DNS Check",
211211+ },
212212+});
213213+```
214214+215215+### DNS Monitor Options
216216+217217+| Option | Type | Required | Description |
218218+|--------|------|----------|-------------|
219219+| `name` | string | Yes | Monitor name (max 256 chars) |
220220+| `uri` | string | Yes | Domain to resolve (max 2048 chars) |
221221+| `periodicity` | Periodicity | Yes | Check interval |
222222+| `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) |
223223+| `retry` | bigint | No | Retry attempts (default: 3, max: 10) |
224224+| `regions` | Region[] | No | Regions for checks |
225225+| `active` | boolean | No | Enable monitoring (default: false) |
226226+| `public` | boolean | No | Public visibility (default: false) |
227227+| `degradedAt` | bigint | No | Latency threshold (ms) for degraded status |
228228+| `description` | string | No | Monitor description (max 1024 chars) |
229229+| `recordAssertions` | RecordAssertion[] | No | DNS record assertions |
230230+| `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration |
231231+232232+## List Monitors
233233+234234+List all monitors with offset-based pagination. Returns monitors grouped by type.
235235+236236+```typescript
237237+const { httpMonitors, tcpMonitors, dnsMonitors, totalSize } =
238238+ await client.monitor.v1.MonitorService.listMonitors({
239239+ limit: 10,
240240+ offset: 0,
241241+ });
242242+243243+console.log(`Total: ${totalSize}`);
244244+console.log(`HTTP: ${httpMonitors.length}`);
245245+console.log(`TCP: ${tcpMonitors.length}`);
246246+console.log(`DNS: ${dnsMonitors.length}`);
247247+```
248248+249249+Pagination parameters:
250250+251251+| Parameter | Type | Description |
252252+|-----------|------|-------------|
253253+| `limit` | number (optional) | Max results to return (1–100, default 50) |
254254+| `offset` | number (optional) | Number of results to skip (default 0) |
255255+256256+## Get Monitor
257257+258258+Get a single monitor by ID. The response uses a `MonitorConfig` oneof type that contains one of HTTP, TCP, or DNS configuration.
259259+260260+```typescript
261261+const { monitor } = await client.monitor.v1.MonitorService.getMonitor({
262262+ id: "mon_123",
263263+});
264264+265265+if (monitor?.config.case === "http") {
266266+ console.log(`HTTP Monitor: ${monitor.config.value.name} — ${monitor.config.value.url}`);
267267+} else if (monitor?.config.case === "tcp") {
268268+ console.log(`TCP Monitor: ${monitor.config.value.name} — ${monitor.config.value.uri}`);
269269+} else if (monitor?.config.case === "dns") {
270270+ console.log(`DNS Monitor: ${monitor.config.value.name} — ${monitor.config.value.uri}`);
271271+}
272272+```
273273+274274+## Trigger Monitor
275275+276276+Trigger an immediate check for a monitor.
277277+278278+```typescript
279279+const { success } = await client.monitor.v1.MonitorService.triggerMonitor({
280280+ id: "mon_123",
281281+});
282282+283283+console.log(`Trigger successful: ${success}`);
284284+```
285285+286286+## Delete Monitor
287287+288288+```typescript
289289+const { success } = await client.monitor.v1.MonitorService.deleteMonitor({
290290+ id: "mon_123",
291291+});
292292+```
293293+294294+## Get Monitor Status
295295+296296+Get the current status of a monitor across all configured regions.
297297+298298+```typescript
299299+import {
300300+ createOpenStatusClient,
301301+ MonitorStatus,
302302+ Region,
303303+} from "@openstatus/sdk-node";
304304+305305+const client = createOpenStatusClient({
306306+ apiKey: process.env.OPENSTATUS_API_KEY,
307307+});
308308+309309+const { id, regions } = await client.monitor.v1.MonitorService.getMonitorStatus(
310310+ { id: "mon_123" },
311311+);
312312+313313+for (const { region, status } of regions) {
314314+ console.log(`${Region[region]}: ${MonitorStatus[status]}`);
315315+}
316316+```
317317+318318+## Get Monitor Summary
319319+320320+Get aggregated metrics and latency percentiles for a monitor over a time range.
321321+322322+```typescript
323323+import { createOpenStatusClient, TimeRange } from "@openstatus/sdk-node";
324324+325325+const client = createOpenStatusClient({
326326+ apiKey: process.env.OPENSTATUS_API_KEY,
327327+});
328328+329329+const summary = await client.monitor.v1.MonitorService.getMonitorSummary({
330330+ id: "mon_123",
331331+ timeRange: TimeRange.TIME_RANGE_7D,
332332+ regions: [],
333333+});
334334+335335+console.log(`Last ping: ${summary.lastPingAt}`);
336336+console.log(`Successful: ${summary.totalSuccessful}`);
337337+console.log(`Degraded: ${summary.totalDegraded}`);
338338+console.log(`Failed: ${summary.totalFailed}`);
339339+console.log(`P50: ${summary.p50}ms`);
340340+console.log(`P75: ${summary.p75}ms`);
341341+console.log(`P90: ${summary.p90}ms`);
342342+console.log(`P95: ${summary.p95}ms`);
343343+console.log(`P99: ${summary.p99}ms`);
344344+```
345345+346346+The latency fields (`p50`, `p75`, `p90`, `p95`, `p99`) and count fields (`totalSuccessful`, `totalDegraded`, `totalFailed`) are `bigint` values. The `regions` parameter is optional — pass an empty array to get metrics across all regions.