# OpenStatus Node.js SDK (Beta) [![JSR](https://jsr.io/badges/@openstatus/sdk-node)](https://jsr.io/@openstatus/sdk-node) [![npm](https://img.shields.io/npm/v/@openstatus/sdk-node)](https://www.npmjs.com/package/@openstatus/sdk-node) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) Official Node.js SDK for [OpenStatus](https://openstatus.dev) - The open-source status page with uptime monitoring. ## Table of Contents - [Features](#features) - [Installation](#installation) - [Quick Start](#quick-start) - [Authentication](#authentication) - [SDK Reference](#sdk-reference) - [Monitor Service](#monitor-service) - [Health Service](#health-service) - [Status Report Service](#status-report-service) - [Status Page Service](#status-page-service) - [Maintenance Service](#maintenance-service) - [Notification Service](#notification-service) - [Reference](#reference) - [Monitor Options](#monitor-options) - [Assertions](#assertions) - [Regions](#regions) - [Enums](#enums) - [Error Handling](#error-handling) - [Related](#related) ## Features ### Monitoring - **HTTP Monitoring** - Monitor websites and APIs with customizable assertions - **TCP Monitoring** - Check database connections and other TCP services - **DNS Monitoring** - Verify DNS records and resolution - **Global Regions** - Monitor from 28 locations worldwide ### Status Page - **Status Pages** - Create and manage public status pages with custom domains - **Page Components** - Add monitor-based or static components with grouping - **Subscribers** - Manage email subscriptions for status updates - **Status Reports** - Manage incident reports with update timelines - **Maintenance Windows** - Schedule and manage planned maintenance periods ### Notifications - **12 Providers** - Slack, Discord, Email, PagerDuty, Opsgenie, Telegram, and more - **Webhook Support** - Custom webhooks with headers for any integration - **Monitor Alerts** - Get notified when monitors go down or recover ### Developer Experience - **Type-safe** - Full TypeScript support with generated types from protobuf - **Multiple Runtimes** - Works with Node.js, Deno, and Bun ## Installation ### npm ```bash npm install @openstatus/sdk-node ``` ### JSR ```bash npx jsr add @openstatus/sdk-node ``` ### Deno ```typescript import { createOpenStatusClient } from "jsr:@openstatus/sdk-node"; ``` ## Quick Start ```typescript import { createOpenStatusClient, HTTPMethod, NumberComparator, Periodicity, Region, } from "@openstatus/sdk-node"; // Create a client with your API key const client = createOpenStatusClient({ apiKey: process.env.OPENSTATUS_API_KEY, }); // Create a monitor const { monitor } = await client.monitor.v1.MonitorService.createHTTPMonitor({ monitor: { name: "My API", url: "https://api.example.com/health", periodicity: Periodicity.PERIODICITY_1M, method: HTTPMethod.HTTP_METHOD_GET, regions: [Region.FLY_AMS, Region.FLY_IAD, Region.FLY_SYD], active: true, statusCodeAssertions: [ { comparator: NumberComparator.EQUAL, target: BigInt(200) }, ], }, }); console.log(`Monitor created: ${monitor?.id}`); // List all monitors const { httpMonitors, tcpMonitors, dnsMonitors, totalSize } = await client .monitor.v1.MonitorService.listMonitors({}); console.log(`Found ${totalSize} monitors`); ``` ## Authentication All API requests require an API key. Get yours from the [OpenStatus dashboard](https://www.openstatus.dev/app). ### Recommended: Configure client once ```typescript import { createOpenStatusClient } from "@openstatus/sdk-node"; const client = createOpenStatusClient({ apiKey: process.env.OPENSTATUS_API_KEY, }); // No need to pass headers on each call await client.monitor.v1.MonitorService.listMonitors({}); ``` ### Alternative: Manual headers ```typescript import { openstatus } from "@openstatus/sdk-node"; const headers = { "x-openstatus-key": process.env.OPENSTATUS_API_KEY, }; // Pass headers to each service method await openstatus.monitor.v1.MonitorService.listMonitors({}, { headers }); ``` ### Environment Variables | Variable | Description | Default | | -------------------- | ----------------------- | -------------------------------- | | `OPENSTATUS_API_KEY` | Your OpenStatus API key | Required | | `OPENSTATUS_API_URL` | Custom API endpoint | `https://api.openstatus.dev/rpc` | ## SDK Reference > **Note:** All examples below assume you've created a client: > > ```typescript > const client = createOpenStatusClient({ > apiKey: process.env.OPENSTATUS_API_KEY, > }); > ``` ### Monitor Service Manage HTTP, TCP, and DNS monitors. #### `createHTTPMonitor(request)` Create an HTTP/HTTPS monitor. ```typescript import { createOpenStatusClient, HTTPMethod, Periodicity, Region, } from "@openstatus/sdk-node"; const { monitor } = await client.monitor.v1.MonitorService.createHTTPMonitor({ monitor: { name: "My Website", url: "https://example.com", periodicity: Periodicity.PERIODICITY_1M, method: HTTPMethod.HTTP_METHOD_GET, regions: [Region.FLY_AMS, Region.FLY_IAD, Region.FLY_SYD], active: true, }, }); ``` #### `updateHTTPMonitor(request)` Update an existing HTTP monitor. ```typescript const { monitor } = await client.monitor.v1.MonitorService.updateHTTPMonitor({ id: "mon_123", monitor: { name: "Updated Name", active: false, }, }); ``` #### `createTCPMonitor(request)` Create a TCP connection monitor. ```typescript const { monitor } = await client.monitor.v1.MonitorService.createTCPMonitor({ monitor: { name: "Database", uri: "db.example.com:5432", periodicity: Periodicity.PERIODICITY_5M, regions: [Region.FLY_AMS, Region.FLY_IAD], active: true, }, }); ``` #### `updateTCPMonitor(request)` Update an existing TCP monitor. ```typescript const { monitor } = await client.monitor.v1.MonitorService.updateTCPMonitor({ id: "mon_123", monitor: { name: "Updated Database Monitor", }, }); ``` #### `createDNSMonitor(request)` Create a DNS resolution monitor. ```typescript import { Periodicity, RecordComparator, Region } from "@openstatus/sdk-node"; const { monitor } = await client.monitor.v1.MonitorService.createDNSMonitor({ monitor: { name: "DNS Check", uri: "example.com", periodicity: Periodicity.PERIODICITY_10M, regions: [Region.FLY_AMS], active: true, recordAssertions: [ { record: "A", comparator: RecordComparator.EQUAL, target: "93.184.216.34", }, ], }, }); ``` #### `updateDNSMonitor(request)` Update an existing DNS monitor. ```typescript const { monitor } = await client.monitor.v1.MonitorService.updateDNSMonitor({ id: "mon_123", monitor: { name: "Updated DNS Check", }, }); ``` #### `listMonitors(request)` List all monitors with pagination. Returns monitors grouped by type. ```typescript const { httpMonitors, tcpMonitors, dnsMonitors, nextPageToken, totalSize } = await client.monitor.v1.MonitorService.listMonitors({ pageSize: 10, pageToken: "", }); ``` #### `getMonitor(request)` Get a single monitor by ID. Returns the monitor configuration (HTTP, TCP, or DNS). ```typescript const { monitor } = await client.monitor.v1.MonitorService.getMonitor({ id: "mon_123", }); // Handle the monitor type if (monitor?.config.case === "http") { console.log(`HTTP Monitor: ${monitor.config.value.name}`); } else if (monitor?.config.case === "tcp") { console.log(`TCP Monitor: ${monitor.config.value.name}`); } else if (monitor?.config.case === "dns") { console.log(`DNS Monitor: ${monitor.config.value.name}`); } ``` #### `triggerMonitor(request)` Trigger an immediate check. ```typescript const { success } = await client.monitor.v1.MonitorService.triggerMonitor({ id: "mon_123", }); ``` #### `deleteMonitor(request)` Delete a monitor. ```typescript const { success } = await client.monitor.v1.MonitorService.deleteMonitor({ id: "mon_123", }); ``` #### `getMonitorStatus(request)` Get the current status of a monitor across all configured regions. ```typescript import { MonitorStatus, Region } from "@openstatus/sdk-node"; const { id, regions } = await client.monitor.v1.MonitorService.getMonitorStatus( { id: "mon_123" }, ); for (const { region, status } of regions) { console.log(`${Region[region]}: ${MonitorStatus[status]}`); } ``` #### `getMonitorSummary(request)` Get aggregated metrics and latency percentiles for a monitor. ```typescript import { TimeRange } from "@openstatus/sdk-node"; const summary = await client.monitor.v1.MonitorService.getMonitorSummary({ id: "mon_123", timeRange: TimeRange.TIME_RANGE_7D, regions: [], // optional: filter by specific regions }); console.log(`Last ping: ${summary.lastPingAt}`); console.log(`Success: ${summary.totalSuccessful}`); console.log(`Failed: ${summary.totalFailed}`); console.log(`P50 latency: ${summary.p50}ms`); console.log(`P95 latency: ${summary.p95}ms`); console.log(`P99 latency: ${summary.p99}ms`); ``` --- ### Health Service Check API health status (no authentication required). ```typescript import { openstatus, ServingStatus } from "@openstatus/sdk-node"; const { status } = await openstatus.health.v1.HealthService.check({}); console.log(ServingStatus[status]); // "SERVING" ``` --- ### Status Report Service Manage incident reports with update timelines. #### `createStatusReport(request)` Create a new status report. ```typescript import { StatusReportStatus } from "@openstatus/sdk-node"; const { statusReport } = await client.statusReport.v1.StatusReportService .createStatusReport({ title: "API Degradation", status: StatusReportStatus.INVESTIGATING, message: "We are investigating reports of increased latency.", date: "2024-01-15T10:30:00Z", pageId: "page_123", pageComponentIds: ["comp_456"], notify: true, }); console.log(`Status report created: ${statusReport?.id}`); ``` #### `getStatusReport(request)` Get a status report by ID (includes full update timeline). ```typescript import { StatusReportStatus } from "@openstatus/sdk-node"; const { statusReport } = await client.statusReport.v1.StatusReportService .getStatusReport({ id: "sr_123", }); console.log(`Title: ${statusReport?.title}`); console.log(`Status: ${StatusReportStatus[statusReport?.status ?? 0]}`); for (const update of statusReport?.updates ?? []) { console.log(`${update.date}: ${update.message}`); } ``` #### `listStatusReports(request)` List all status reports with pagination and optional filtering. ```typescript import { StatusReportStatus } from "@openstatus/sdk-node"; const { statusReports, totalSize } = await client.statusReport.v1 .StatusReportService.listStatusReports({ limit: 10, offset: 0, statuses: [StatusReportStatus.INVESTIGATING, StatusReportStatus.IDENTIFIED], }); console.log(`Found ${totalSize} status reports`); ``` #### `updateStatusReport(request)` Update status report metadata. ```typescript const { statusReport } = await client.statusReport.v1.StatusReportService .updateStatusReport({ id: "sr_123", title: "Updated Title", pageComponentIds: ["comp_456", "comp_789"], }); ``` #### `deleteStatusReport(request)` Delete a status report and all its updates. ```typescript const { success } = await client.statusReport.v1.StatusReportService .deleteStatusReport({ id: "sr_123", }); ``` #### `addStatusReportUpdate(request)` Add a new update to an existing status report timeline. ```typescript import { StatusReportStatus } from "@openstatus/sdk-node"; const { statusReport } = await client.statusReport.v1.StatusReportService .addStatusReportUpdate({ statusReportId: "sr_123", status: StatusReportStatus.IDENTIFIED, message: "The issue has been identified as a database connection problem.", date: "2024-01-15T11:00:00Z", // optional, defaults to current time notify: true, }); ``` --- ### Status Page Service Manage status pages, components, and subscribers. #### `createStatusPage(request)` Create a new status page. ```typescript 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}`); ``` #### `getStatusPage(request)` Get a status page by ID. ```typescript const { statusPage } = await client.statusPage.v1.StatusPageService .getStatusPage({ id: "page_123", }); ``` #### `listStatusPages(request)` List all status pages with pagination. ```typescript const { statusPages, totalSize } = await client.statusPage.v1.StatusPageService .listStatusPages({ limit: 10, offset: 0 }); console.log(`Found ${totalSize} status pages`); ``` #### `updateStatusPage(request)` Update a status page. ```typescript const { statusPage } = await client.statusPage.v1.StatusPageService .updateStatusPage({ id: "page_123", title: "Updated Title", description: "Updated description", }); ``` #### `deleteStatusPage(request)` Delete a status page. ```typescript const { success } = await client.statusPage.v1.StatusPageService .deleteStatusPage({ id: "page_123", }); ``` #### `addMonitorComponent(request)` Add a monitor-based component to a status page. ```typescript const { component } = await client.statusPage.v1.StatusPageService .addMonitorComponent({ pageId: "page_123", monitorId: "mon_456", name: "API Server", description: "Main API endpoint", order: 1, }); ``` #### `addStaticComponent(request)` Add a static component (not linked to a monitor). ```typescript const { component } = await client.statusPage.v1.StatusPageService .addStaticComponent({ pageId: "page_123", name: "Third-party Service", description: "External dependency", order: 2, }); ``` #### `updateComponent(request)` Update a component. ```typescript const { component } = await client.statusPage.v1.StatusPageService .updateComponent({ id: "comp_123", name: "Updated Component Name", order: 3, }); ``` #### `removeComponent(request)` Remove a component from a status page. ```typescript const { success } = await client.statusPage.v1.StatusPageService .removeComponent({ id: "comp_123", }); ``` #### `createComponentGroup(request)` Create a component group. ```typescript const { group } = await client.statusPage.v1.StatusPageService .createComponentGroup({ pageId: "page_123", name: "Core Services", }); ``` #### `updateComponentGroup(request)` Update a component group. ```typescript const { group } = await client.statusPage.v1.StatusPageService .updateComponentGroup({ id: "group_123", name: "Updated Group Name", }); ``` #### `deleteComponentGroup(request)` Delete a component group. ```typescript const { success } = await client.statusPage.v1.StatusPageService .deleteComponentGroup({ id: "group_123", }); ``` #### `subscribeToPage(request)` Subscribe an email to status page updates. ```typescript const { subscriber } = await client.statusPage.v1.StatusPageService .subscribeToPage({ pageId: "page_123", email: "user@example.com", }); ``` #### `unsubscribeFromPage(request)` Unsubscribe from a status page. ```typescript // By email const { success } = await client.statusPage.v1.StatusPageService .unsubscribeFromPage({ pageId: "page_123", identifier: { case: "email", value: "user@example.com" }, }); // Or by subscriber ID const { success: success2 } = await client.statusPage.v1.StatusPageService .unsubscribeFromPage({ pageId: "page_123", identifier: { case: "id", value: "sub_456" }, }); ``` #### `listSubscribers(request)` List all subscribers for a status page. ```typescript const { subscribers, totalSize } = await client.statusPage.v1.StatusPageService .listSubscribers({ pageId: "page_123", limit: 50, offset: 0, includeUnsubscribed: false, }); ``` #### `getStatusPageContent(request)` Get full status page content including components, groups, and active reports. ```typescript 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(`Active reports: ${content.statusReports.length}`); ``` #### `getOverallStatus(request)` Get the aggregated status of a status page. ```typescript import { OverallStatus } from "@openstatus/sdk-node"; 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]}`); } ``` --- ### Maintenance Service Manage scheduled maintenance windows. #### `createMaintenance(request)` Create a new maintenance window. ```typescript const { maintenance } = await client.maintenance.v1.MaintenanceService .createMaintenance({ title: "Database Upgrade", message: "We will be upgrading our database infrastructure.", from: "2024-01-20T02:00:00Z", to: "2024-01-20T04:00:00Z", pageId: "page_123", pageComponentIds: ["comp_456"], notify: true, }); console.log(`Maintenance created: ${maintenance?.id}`); ``` #### `getMaintenance(request)` Get a maintenance window by ID. ```typescript const { maintenance } = await client.maintenance.v1.MaintenanceService .getMaintenance({ id: "maint_123", }); console.log(`Title: ${maintenance?.title}`); console.log(`From: ${maintenance?.from}`); console.log(`To: ${maintenance?.to}`); ``` #### `listMaintenances(request)` List all maintenance windows with pagination and optional filtering. ```typescript const { maintenances, totalSize } = await client.maintenance.v1 .MaintenanceService.listMaintenances({ limit: 10, offset: 0, pageId: "page_123", // optional filter }); console.log(`Found ${totalSize} maintenance windows`); ``` #### `updateMaintenance(request)` Update a maintenance window. ```typescript const { maintenance } = await client.maintenance.v1.MaintenanceService .updateMaintenance({ id: "maint_123", title: "Extended Database Upgrade", to: "2024-01-20T06:00:00Z", }); ``` #### `deleteMaintenance(request)` Delete a maintenance window. ```typescript const { success } = await client.maintenance.v1.MaintenanceService .deleteMaintenance({ id: "maint_123", }); ``` --- ### Notification Service Manage notification channels for monitor alerts. Supports 12 providers including Slack, Discord, Email, PagerDuty, and custom webhooks. #### `createNotification(request)` Create a new notification channel. ```typescript import { NotificationProvider } from "@openstatus/sdk-node"; const { notification } = await client.notification.v1.NotificationService .createNotification({ name: "Slack Alerts", provider: NotificationProvider.SLACK, data: { data: { case: "slack", value: { webhookUrl: "https://hooks.slack.com/services/..." }, }, }, monitorIds: ["mon_123", "mon_456"], }); console.log(`Notification created: ${notification?.id}`); ``` #### `getNotification(request)` Get a notification channel by ID. ```typescript import { NotificationProvider } from "@openstatus/sdk-node"; const { notification } = await client.notification.v1.NotificationService .getNotification({ id: "notif_123", }); console.log(`Name: ${notification?.name}`); console.log(`Provider: ${NotificationProvider[notification?.provider ?? 0]}`); ``` #### `listNotifications(request)` List all notification channels with pagination. ```typescript const { notifications, totalSize } = await client.notification.v1 .NotificationService.listNotifications({ limit: 10, offset: 0 }); console.log(`Found ${totalSize} notification channels`); ``` #### `updateNotification(request)` Update a notification channel. ```typescript const { notification } = await client.notification.v1.NotificationService .updateNotification({ id: "notif_123", name: "Updated Slack Alerts", monitorIds: ["mon_123", "mon_456", "mon_789"], }); ``` #### `deleteNotification(request)` Delete a notification channel. ```typescript const { success } = await client.notification.v1.NotificationService .deleteNotification({ id: "notif_123", }); ``` #### `sendTestNotification(request)` Send a test notification to verify configuration. ```typescript import { NotificationProvider } from "@openstatus/sdk-node"; const { success, errorMessage } = await client.notification.v1 .NotificationService.sendTestNotification({ provider: NotificationProvider.SLACK, data: { data: { case: "slack", value: { webhookUrl: "https://hooks.slack.com/services/..." }, }, }, }); if (success) { console.log("Test notification sent successfully"); } else { console.log(`Test failed: ${errorMessage}`); } ``` #### `checkNotificationLimit(request)` Check if the workspace has reached its notification limit. ```typescript const { limitReached, currentCount, maxCount } = await client.notification.v1 .NotificationService.checkNotificationLimit({}); console.log(`${currentCount}/${maxCount} notification channels used`); ``` #### Provider Configuration Examples
Slack ```typescript { provider: NotificationProvider.SLACK, data: { data: { case: "slack", value: { webhookUrl: "https://hooks.slack.com/services/..." } } } } ```
Discord ```typescript { provider: NotificationProvider.DISCORD, data: { data: { case: "discord", value: { webhookUrl: "https://discord.com/api/webhooks/..." } } } } ```
Email ```typescript { provider: NotificationProvider.EMAIL, data: { data: { case: "email", value: { email: "alerts@example.com" } } } } ```
PagerDuty ```typescript { provider: NotificationProvider.PAGERDUTY, data: { data: { case: "pagerduty", value: { integrationKey: "your-integration-key" } } } } ```
Opsgenie ```typescript import { OpsgenieRegion } from "@openstatus/sdk-node"; { provider: NotificationProvider.OPSGENIE, data: { data: { case: "opsgenie", value: { apiKey: "your-api-key", region: OpsgenieRegion.US } } } } ```
Telegram ```typescript { provider: NotificationProvider.TELEGRAM, data: { data: { case: "telegram", value: { chatId: "123456789" } } } } ```
Google Chat ```typescript { provider: NotificationProvider.GOOGLE_CHAT, data: { data: { case: "googleChat", value: { webhookUrl: "https://chat.googleapis.com/v1/spaces/..." } } } } ```
Grafana OnCall ```typescript { provider: NotificationProvider.GRAFANA_ONCALL, data: { data: { case: "grafanaOncall", value: { webhookUrl: "https://oncall.example.com/..." } } } } ```
Ntfy ```typescript { provider: NotificationProvider.NTFY, data: { data: { case: "ntfy", value: { topic: "my-alerts", serverUrl: "https://ntfy.sh", // optional, defaults to ntfy.sh token: "tk_..." // optional auth token } } } } ```
SMS ```typescript { provider: NotificationProvider.SMS, data: { data: { case: "sms", value: { phoneNumber: "+1234567890" } } } } ```
WhatsApp ```typescript { provider: NotificationProvider.WHATSAPP, data: { data: { case: "whatsapp", value: { phoneNumber: "+1234567890" } } } } ```
Custom Webhook ```typescript { provider: NotificationProvider.WEBHOOK, data: { data: { case: "webhook", value: { endpoint: "https://api.example.com/webhook", headers: [ { key: "Authorization", value: "Bearer token" }, { key: "X-Custom-Header", value: "value" } ] } } } } ```
--- ## Reference ### Monitor Options #### HTTP Monitor | Option | Type | Required | Description | | ---------------------- | ------------------- | -------- | ------------------------------------------- | | `name` | string | Yes | Monitor name (max 256 chars) | | `url` | string | Yes | URL to monitor (max 2048 chars) | | `periodicity` | Periodicity | Yes | Check interval | | `method` | HTTPMethod | No | HTTP method (default: GET) | | `body` | string | No | Request body | | `headers` | Headers[] | No | Custom headers `{ key, value }[]` | | `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) | | `retry` | bigint | No | Retry attempts (default: 3, max: 10) | | `followRedirects` | boolean | No | Follow redirects (default: true) | | `regions` | Region[] | No | Regions for checks | | `active` | boolean | No | Enable monitoring (default: false) | | `public` | boolean | No | Public visibility (default: false) | | `degradedAt` | bigint | No | Latency threshold (ms) for degraded status | | `description` | string | No | Monitor description (max 1024 chars) | | `statusCodeAssertions` | array | No | Status code assertions | | `bodyAssertions` | array | No | Body assertions | | `headerAssertions` | array | No | Header assertions | | `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration | #### TCP Monitor | Option | Type | Required | Description | | --------------- | ------------------- | -------- | ------------------------------------------- | | `name` | string | Yes | Monitor name (max 256 chars) | | `uri` | string | Yes | `host:port` to monitor (max 2048 chars) | | `periodicity` | Periodicity | Yes | Check interval | | `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) | | `retry` | bigint | No | Retry attempts (default: 3, max: 10) | | `regions` | Region[] | No | Regions for checks | | `active` | boolean | No | Enable monitoring (default: false) | | `public` | boolean | No | Public visibility (default: false) | | `degradedAt` | bigint | No | Latency threshold (ms) for degraded status | | `description` | string | No | Monitor description (max 1024 chars) | | `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration | #### DNS Monitor | Option | Type | Required | Description | | ------------------ | ------------------- | -------- | ------------------------------------------- | | `name` | string | Yes | Monitor name (max 256 chars) | | `uri` | string | Yes | Domain to resolve (max 2048 chars) | | `periodicity` | Periodicity | Yes | Check interval | | `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) | | `retry` | bigint | No | Retry attempts (default: 3, max: 10) | | `regions` | Region[] | No | Regions for checks | | `active` | boolean | No | Enable monitoring (default: false) | | `public` | boolean | No | Public visibility (default: false) | | `degradedAt` | bigint | No | Latency threshold (ms) for degraded status | | `description` | string | No | Monitor description (max 1024 chars) | | `recordAssertions` | array | No | DNS record assertions | | `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration | --- ### Assertions #### Status Code Assertions Validate HTTP response status codes using `NumberComparator`. ```typescript import { NumberComparator } from "@openstatus/sdk-node"; { statusCodeAssertions: [ { comparator: NumberComparator.EQUAL, target: BigInt(200) }, { comparator: NumberComparator.LESS_THAN, target: BigInt(400) }, ]; } ``` #### Body Assertions Validate response body content using `StringComparator`. ```typescript import { StringComparator } from "@openstatus/sdk-node"; { bodyAssertions: [ { comparator: StringComparator.CONTAINS, target: '"status":"ok"' }, { comparator: StringComparator.NOT_EMPTY, target: "" }, ]; } ``` #### Header Assertions Validate response headers using `StringComparator`. ```typescript import { StringComparator } from "@openstatus/sdk-node"; { headerAssertions: [ { key: "content-type", comparator: StringComparator.CONTAINS, target: "application/json", }, ]; } ``` #### DNS Record Assertions Validate DNS records using `RecordComparator`. ```typescript import { RecordComparator } from "@openstatus/sdk-node"; { recordAssertions: [ { record: "A", comparator: RecordComparator.EQUAL, target: "93.184.216.34", }, { record: "CNAME", comparator: RecordComparator.CONTAINS, target: "cdn" }, ]; } ``` **Supported record types:** `A`, `AAAA`, `CNAME`, `MX`, `TXT` --- ### Regions Monitor from 28 global locations across multiple providers. ```typescript import { Region } from "@openstatus/sdk-node"; regions: [Region.FLY_AMS, Region.FLY_IAD, Region.KOYEB_FRA]; ``` #### Fly.io Regions (18) | Enum Value | Location | | ---------- | --------------- | | `FLY_AMS` | Amsterdam | | `FLY_ARN` | Stockholm | | `FLY_BOM` | Mumbai | | `FLY_CDG` | Paris | | `FLY_DFW` | Dallas | | `FLY_EWR` | Newark | | `FLY_FRA` | Frankfurt | | `FLY_GRU` | São Paulo | | `FLY_IAD` | Washington D.C. | | `FLY_JNB` | Johannesburg | | `FLY_LAX` | Los Angeles | | `FLY_LHR` | London | | `FLY_NRT` | Tokyo | | `FLY_ORD` | Chicago | | `FLY_SJC` | San Jose | | `FLY_SIN` | Singapore | | `FLY_SYD` | Sydney | | `FLY_YYZ` | Toronto | #### Koyeb Regions (6) | Enum Value | Location | | ----------- | ------------- | | `KOYEB_FRA` | Frankfurt | | `KOYEB_PAR` | Paris | | `KOYEB_SFO` | San Francisco | | `KOYEB_SIN` | Singapore | | `KOYEB_TYO` | Tokyo | | `KOYEB_WAS` | Washington | #### Railway Regions (4) | Enum Value | Location | | ------------------------- | -------------- | | `RAILWAY_US_WEST2` | US West | | `RAILWAY_US_EAST4` | US East | | `RAILWAY_EUROPE_WEST4` | Europe West | | `RAILWAY_ASIA_SOUTHEAST1` | Asia Southeast | --- ### Enums #### Periodicity | Value | Description | | ----------------- | ----------- | | `PERIODICITY_30S` | Every 30s | | `PERIODICITY_1M` | Every 1m | | `PERIODICITY_5M` | Every 5m | | `PERIODICITY_10M` | Every 10m | | `PERIODICITY_30M` | Every 30m | | `PERIODICITY_1H` | Every 1h | #### HTTPMethod | Value | Description | | --------------------- | ----------- | | `HTTP_METHOD_GET` | GET | | `HTTP_METHOD_POST` | POST | | `HTTP_METHOD_HEAD` | HEAD | | `HTTP_METHOD_PUT` | PUT | | `HTTP_METHOD_PATCH` | PATCH | | `HTTP_METHOD_DELETE` | DELETE | | `HTTP_METHOD_TRACE` | TRACE | | `HTTP_METHOD_CONNECT` | CONNECT | | `HTTP_METHOD_OPTIONS` | OPTIONS | #### MonitorStatus | Value | Description | | ---------- | -------------------------- | | `ACTIVE` | Monitor is healthy | | `DEGRADED` | Latency threshold exceeded | | `ERROR` | Monitor is failing | #### TimeRange | Value | Description | | ---------------- | ------------ | | `TIME_RANGE_1D` | Last 1 day | | `TIME_RANGE_7D` | Last 7 days | | `TIME_RANGE_14D` | Last 14 days | #### StatusReportStatus | Value | Description | | --------------- | -------------------------------- | | `INVESTIGATING` | Actively investigating the issue | | `IDENTIFIED` | Root cause has been identified | | `MONITORING` | Fix deployed, monitoring | | `RESOLVED` | Issue fully resolved | #### OverallStatus | Value | Description | | ---------------- | --------------------------- | | `OPERATIONAL` | All systems operational | | `DEGRADED` | Performance is degraded | | `PARTIAL_OUTAGE` | Some systems are down | | `MAJOR_OUTAGE` | Major systems are down | | `MAINTENANCE` | Scheduled maintenance | | `UNKNOWN` | Status cannot be determined | #### NotificationProvider | Value | Description | | ---------------- | ------------------- | | `DISCORD` | Discord webhook | | `EMAIL` | Email notification | | `GOOGLE_CHAT` | Google Chat webhook | | `GRAFANA_ONCALL` | Grafana OnCall | | `NTFY` | Ntfy push service | | `PAGERDUTY` | PagerDuty | | `OPSGENIE` | Opsgenie | | `SLACK` | Slack webhook | | `SMS` | SMS notification | | `TELEGRAM` | Telegram bot | | `WEBHOOK` | Custom webhook | | `WHATSAPP` | WhatsApp | #### OpsgenieRegion | Value | Description | | ----- | ----------- | | `US` | US region | | `EU` | EU region | #### PageAccessType | Value | Description | | -------------------- | ----------------------- | | `PUBLIC` | Publicly accessible | | `PASSWORD_PROTECTED` | Requires password | | `AUTHENTICATED` | Requires authentication | #### PageTheme | Value | Description | | -------- | ------------------- | | `SYSTEM` | Follow system theme | | `LIGHT` | Light theme | | `DARK` | Dark theme | #### PageComponentType | Value | Description | | --------- | ------------------------- | | `MONITOR` | Linked to a monitor | | `STATIC` | Static component (manual) | #### NumberComparator | Value | Description | | ----------------------- | --------------------- | | `EQUAL` | Equal to target | | `NOT_EQUAL` | Not equal to target | | `GREATER_THAN` | Greater than target | | `GREATER_THAN_OR_EQUAL` | Greater than or equal | | `LESS_THAN` | Less than target | | `LESS_THAN_OR_EQUAL` | Less than or equal | #### StringComparator | Value | Description | | ----------------------- | --------------------------- | | `CONTAINS` | Contains target string | | `NOT_CONTAINS` | Does not contain target | | `EQUAL` | Equal to target | | `NOT_EQUAL` | Not equal to target | | `EMPTY` | Value is empty | | `NOT_EMPTY` | Value is not empty | | `GREATER_THAN` | Lexicographically greater | | `GREATER_THAN_OR_EQUAL` | Lexicographically >= target | | `LESS_THAN` | Lexicographically less | | `LESS_THAN_OR_EQUAL` | Lexicographically <= target | #### RecordComparator | Value | Description | | -------------- | ----------------------- | | `EQUAL` | Equal to target | | `NOT_EQUAL` | Not equal to target | | `CONTAINS` | Contains target string | | `NOT_CONTAINS` | Does not contain target | --- ## Error Handling The SDK uses Connect RPC. Errors include a `code` and `message`: ```typescript import { ConnectError } from "@connectrpc/connect"; try { await client.monitor.v1.MonitorService.deleteMonitor({ id: "invalid" }); } catch (error) { if (error instanceof ConnectError) { console.error(`Error ${error.code}: ${error.message}`); } } ``` ## Related - [OpenStatus](https://openstatus.dev) - Open-source monitoring platform - [Documentation](https://docs.openstatus.dev) - Full API documentation - [Status Page](https://status.openstatus.dev) - OpenStatus service status ## License MIT