Openstatus sdk
www.openstatus.dev
1# OpenStatus Node.js SDK (Beta)
2
3[](https://jsr.io/@openstatus/sdk-node)
4[](https://www.npmjs.com/package/@openstatus/sdk-node)
5[](https://opensource.org/licenses/MIT)
6
7Official Node.js SDK for [OpenStatus](https://openstatus.dev) - The open-source
8status page with uptime monitoring.
9
10## Table of Contents
11
12- [Features](#features)
13- [Installation](#installation)
14- [Quick Start](#quick-start)
15- [Authentication](#authentication)
16- [SDK Reference](#sdk-reference)
17 - [Monitor Service](#monitor-service)
18 - [Health Service](#health-service)
19 - [Status Report Service](#status-report-service)
20 - [Status Page Service](#status-page-service)
21 - [Maintenance Service](#maintenance-service)
22 - [Notification Service](#notification-service)
23- [Reference](#reference)
24 - [Monitor Options](#monitor-options)
25 - [Assertions](#assertions)
26 - [Regions](#regions)
27 - [Enums](#enums)
28- [Error Handling](#error-handling)
29- [Related](#related)
30
31## Features
32
33### Monitoring
34
35- **HTTP Monitoring** - Monitor websites and APIs with customizable assertions
36- **TCP Monitoring** - Check database connections and other TCP services
37- **DNS Monitoring** - Verify DNS records and resolution
38- **Global Regions** - Monitor from 28 locations worldwide
39
40### Status Page
41
42- **Status Pages** - Create and manage public status pages with custom domains
43- **Page Components** - Add monitor-based or static components with grouping
44- **Subscribers** - Manage email subscriptions for status updates
45- **Status Reports** - Manage incident reports with update timelines
46- **Maintenance Windows** - Schedule and manage planned maintenance periods
47
48### Notifications
49
50- **12 Providers** - Slack, Discord, Email, PagerDuty, Opsgenie, Telegram, and
51 more
52- **Webhook Support** - Custom webhooks with headers for any integration
53- **Monitor Alerts** - Get notified when monitors go down or recover
54
55### Developer Experience
56
57- **Type-safe** - Full TypeScript support with generated types from protobuf
58- **Multiple Runtimes** - Works with Node.js, Deno, and Bun
59
60## Installation
61
62### npm
63
64```bash
65npm install @openstatus/sdk-node
66```
67
68### JSR
69
70```bash
71npx jsr add @openstatus/sdk-node
72```
73
74### Deno
75
76```typescript
77import { createOpenStatusClient } from "jsr:@openstatus/sdk-node";
78```
79
80## Quick Start
81
82```typescript
83import {
84 createOpenStatusClient,
85 HTTPMethod,
86 NumberComparator,
87 Periodicity,
88 Region,
89} from "@openstatus/sdk-node";
90
91// Create a client with your API key
92const client = createOpenStatusClient({
93 apiKey: process.env.OPENSTATUS_API_KEY,
94});
95
96// Create a monitor
97const { monitor } = await client.monitor.v1.MonitorService.createHTTPMonitor({
98 monitor: {
99 name: "My API",
100 url: "https://api.example.com/health",
101 periodicity: Periodicity.PERIODICITY_1M,
102 method: HTTPMethod.HTTP_METHOD_GET,
103 regions: [Region.FLY_AMS, Region.FLY_IAD, Region.FLY_SYD],
104 active: true,
105 statusCodeAssertions: [
106 { comparator: NumberComparator.EQUAL, target: BigInt(200) },
107 ],
108 },
109});
110
111console.log(`Monitor created: ${monitor?.id}`);
112
113// List all monitors
114const { httpMonitors, tcpMonitors, dnsMonitors, totalSize } = await client
115 .monitor.v1.MonitorService.listMonitors({});
116
117console.log(`Found ${totalSize} monitors`);
118```
119
120## Authentication
121
122All API requests require an API key. Get yours from the
123[OpenStatus dashboard](https://www.openstatus.dev/app).
124
125### Recommended: Configure client once
126
127```typescript
128import { createOpenStatusClient } from "@openstatus/sdk-node";
129
130const client = createOpenStatusClient({
131 apiKey: process.env.OPENSTATUS_API_KEY,
132});
133
134// No need to pass headers on each call
135await client.monitor.v1.MonitorService.listMonitors({});
136```
137
138### Alternative: Manual headers
139
140```typescript
141import { openstatus } from "@openstatus/sdk-node";
142
143const headers = {
144 "x-openstatus-key": process.env.OPENSTATUS_API_KEY,
145};
146
147// Pass headers to each service method
148await openstatus.monitor.v1.MonitorService.listMonitors({}, { headers });
149```
150
151### Environment Variables
152
153| Variable | Description | Default |
154| -------------------- | ----------------------- | -------------------------------- |
155| `OPENSTATUS_API_KEY` | Your OpenStatus API key | Required |
156| `OPENSTATUS_API_URL` | Custom API endpoint | `https://api.openstatus.dev/rpc` |
157
158## SDK Reference
159
160> **Note:** All examples below assume you've created a client:
161>
162> ```typescript
163> const client = createOpenStatusClient({
164> apiKey: process.env.OPENSTATUS_API_KEY,
165> });
166> ```
167
168### Monitor Service
169
170Manage HTTP, TCP, and DNS monitors.
171
172#### `createHTTPMonitor(request)`
173
174Create an HTTP/HTTPS monitor.
175
176```typescript
177import {
178 createOpenStatusClient,
179 HTTPMethod,
180 Periodicity,
181 Region,
182} from "@openstatus/sdk-node";
183
184const { monitor } = await client.monitor.v1.MonitorService.createHTTPMonitor({
185 monitor: {
186 name: "My Website",
187 url: "https://example.com",
188 periodicity: Periodicity.PERIODICITY_1M,
189 method: HTTPMethod.HTTP_METHOD_GET,
190 regions: [Region.FLY_AMS, Region.FLY_IAD, Region.FLY_SYD],
191 active: true,
192 },
193});
194```
195
196#### `updateHTTPMonitor(request)`
197
198Update an existing HTTP monitor.
199
200```typescript
201const { monitor } = await client.monitor.v1.MonitorService.updateHTTPMonitor({
202 id: "mon_123",
203 monitor: {
204 name: "Updated Name",
205 active: false,
206 },
207});
208```
209
210#### `createTCPMonitor(request)`
211
212Create a TCP connection monitor.
213
214```typescript
215const { monitor } = await client.monitor.v1.MonitorService.createTCPMonitor({
216 monitor: {
217 name: "Database",
218 uri: "db.example.com:5432",
219 periodicity: Periodicity.PERIODICITY_5M,
220 regions: [Region.FLY_AMS, Region.FLY_IAD],
221 active: true,
222 },
223});
224```
225
226#### `updateTCPMonitor(request)`
227
228Update an existing TCP monitor.
229
230```typescript
231const { monitor } = await client.monitor.v1.MonitorService.updateTCPMonitor({
232 id: "mon_123",
233 monitor: {
234 name: "Updated Database Monitor",
235 },
236});
237```
238
239#### `createDNSMonitor(request)`
240
241Create a DNS resolution monitor.
242
243```typescript
244import { Periodicity, RecordComparator, Region } from "@openstatus/sdk-node";
245
246const { monitor } = await client.monitor.v1.MonitorService.createDNSMonitor({
247 monitor: {
248 name: "DNS Check",
249 uri: "example.com",
250 periodicity: Periodicity.PERIODICITY_10M,
251 regions: [Region.FLY_AMS],
252 active: true,
253 recordAssertions: [
254 {
255 record: "A",
256 comparator: RecordComparator.EQUAL,
257 target: "93.184.216.34",
258 },
259 ],
260 },
261});
262```
263
264#### `updateDNSMonitor(request)`
265
266Update an existing DNS monitor.
267
268```typescript
269const { monitor } = await client.monitor.v1.MonitorService.updateDNSMonitor({
270 id: "mon_123",
271 monitor: {
272 name: "Updated DNS Check",
273 },
274});
275```
276
277#### `listMonitors(request)`
278
279List all monitors with pagination. Returns monitors grouped by type.
280
281```typescript
282const { httpMonitors, tcpMonitors, dnsMonitors, nextPageToken, totalSize } =
283 await client.monitor.v1.MonitorService.listMonitors({
284 pageSize: 10,
285 pageToken: "",
286 });
287```
288
289#### `getMonitor(request)`
290
291Get a single monitor by ID. Returns the monitor configuration (HTTP, TCP, or
292DNS).
293
294```typescript
295const { monitor } = await client.monitor.v1.MonitorService.getMonitor({
296 id: "mon_123",
297});
298
299// Handle the monitor type
300if (monitor?.config.case === "http") {
301 console.log(`HTTP Monitor: ${monitor.config.value.name}`);
302} else if (monitor?.config.case === "tcp") {
303 console.log(`TCP Monitor: ${monitor.config.value.name}`);
304} else if (monitor?.config.case === "dns") {
305 console.log(`DNS Monitor: ${monitor.config.value.name}`);
306}
307```
308
309#### `triggerMonitor(request)`
310
311Trigger an immediate check.
312
313```typescript
314const { success } = await client.monitor.v1.MonitorService.triggerMonitor({
315 id: "mon_123",
316});
317```
318
319#### `deleteMonitor(request)`
320
321Delete a monitor.
322
323```typescript
324const { success } = await client.monitor.v1.MonitorService.deleteMonitor({
325 id: "mon_123",
326});
327```
328
329#### `getMonitorStatus(request)`
330
331Get the current status of a monitor across all configured regions.
332
333```typescript
334import { MonitorStatus, Region } from "@openstatus/sdk-node";
335
336const { id, regions } = await client.monitor.v1.MonitorService.getMonitorStatus(
337 { id: "mon_123" },
338);
339
340for (const { region, status } of regions) {
341 console.log(`${Region[region]}: ${MonitorStatus[status]}`);
342}
343```
344
345#### `getMonitorSummary(request)`
346
347Get aggregated metrics and latency percentiles for a monitor.
348
349```typescript
350import { TimeRange } from "@openstatus/sdk-node";
351
352const summary = await client.monitor.v1.MonitorService.getMonitorSummary({
353 id: "mon_123",
354 timeRange: TimeRange.TIME_RANGE_7D,
355 regions: [], // optional: filter by specific regions
356});
357
358console.log(`Last ping: ${summary.lastPingAt}`);
359console.log(`Success: ${summary.totalSuccessful}`);
360console.log(`Failed: ${summary.totalFailed}`);
361console.log(`P50 latency: ${summary.p50}ms`);
362console.log(`P95 latency: ${summary.p95}ms`);
363console.log(`P99 latency: ${summary.p99}ms`);
364```
365
366---
367
368### Health Service
369
370Check API health status (no authentication required).
371
372```typescript
373import { openstatus, ServingStatus } from "@openstatus/sdk-node";
374
375const { status } = await openstatus.health.v1.HealthService.check({});
376console.log(ServingStatus[status]); // "SERVING"
377```
378
379---
380
381### Status Report Service
382
383Manage incident reports with update timelines.
384
385#### `createStatusReport(request)`
386
387Create a new status report.
388
389```typescript
390import { StatusReportStatus } from "@openstatus/sdk-node";
391
392const { statusReport } = await client.statusReport.v1.StatusReportService
393 .createStatusReport({
394 title: "API Degradation",
395 status: StatusReportStatus.INVESTIGATING,
396 message: "We are investigating reports of increased latency.",
397 date: "2024-01-15T10:30:00Z",
398 pageId: "page_123",
399 pageComponentIds: ["comp_456"],
400 notify: true,
401 });
402
403console.log(`Status report created: ${statusReport?.id}`);
404```
405
406#### `getStatusReport(request)`
407
408Get a status report by ID (includes full update timeline).
409
410```typescript
411import { StatusReportStatus } from "@openstatus/sdk-node";
412
413const { statusReport } = await client.statusReport.v1.StatusReportService
414 .getStatusReport({
415 id: "sr_123",
416 });
417
418console.log(`Title: ${statusReport?.title}`);
419console.log(`Status: ${StatusReportStatus[statusReport?.status ?? 0]}`);
420
421for (const update of statusReport?.updates ?? []) {
422 console.log(`${update.date}: ${update.message}`);
423}
424```
425
426#### `listStatusReports(request)`
427
428List all status reports with pagination and optional filtering.
429
430```typescript
431import { StatusReportStatus } from "@openstatus/sdk-node";
432
433const { statusReports, totalSize } = await client.statusReport.v1
434 .StatusReportService.listStatusReports({
435 limit: 10,
436 offset: 0,
437 statuses: [StatusReportStatus.INVESTIGATING, StatusReportStatus.IDENTIFIED],
438 });
439
440console.log(`Found ${totalSize} status reports`);
441```
442
443#### `updateStatusReport(request)`
444
445Update status report metadata.
446
447```typescript
448const { statusReport } = await client.statusReport.v1.StatusReportService
449 .updateStatusReport({
450 id: "sr_123",
451 title: "Updated Title",
452 pageComponentIds: ["comp_456", "comp_789"],
453 });
454```
455
456#### `deleteStatusReport(request)`
457
458Delete a status report and all its updates.
459
460```typescript
461const { success } = await client.statusReport.v1.StatusReportService
462 .deleteStatusReport({
463 id: "sr_123",
464 });
465```
466
467#### `addStatusReportUpdate(request)`
468
469Add a new update to an existing status report timeline.
470
471```typescript
472import { StatusReportStatus } from "@openstatus/sdk-node";
473
474const { statusReport } = await client.statusReport.v1.StatusReportService
475 .addStatusReportUpdate({
476 statusReportId: "sr_123",
477 status: StatusReportStatus.IDENTIFIED,
478 message: "The issue has been identified as a database connection problem.",
479 date: "2024-01-15T11:00:00Z", // optional, defaults to current time
480 notify: true,
481 });
482```
483
484---
485
486### Status Page Service
487
488Manage status pages, components, and subscribers.
489
490#### `createStatusPage(request)`
491
492Create a new status page.
493
494```typescript
495const { statusPage } = await client.statusPage.v1.StatusPageService
496 .createStatusPage({
497 title: "My Service Status",
498 slug: "my-service",
499 description: "Status page for My Service",
500 homepageUrl: "https://example.com",
501 contactUrl: "https://example.com/contact",
502 });
503
504console.log(`Status page created: ${statusPage?.id}`);
505```
506
507#### `getStatusPage(request)`
508
509Get a status page by ID.
510
511```typescript
512const { statusPage } = await client.statusPage.v1.StatusPageService
513 .getStatusPage({
514 id: "page_123",
515 });
516```
517
518#### `listStatusPages(request)`
519
520List all status pages with pagination.
521
522```typescript
523const { statusPages, totalSize } = await client.statusPage.v1.StatusPageService
524 .listStatusPages({ limit: 10, offset: 0 });
525
526console.log(`Found ${totalSize} status pages`);
527```
528
529#### `updateStatusPage(request)`
530
531Update a status page.
532
533```typescript
534const { statusPage } = await client.statusPage.v1.StatusPageService
535 .updateStatusPage({
536 id: "page_123",
537 title: "Updated Title",
538 description: "Updated description",
539 });
540```
541
542#### `deleteStatusPage(request)`
543
544Delete a status page.
545
546```typescript
547const { success } = await client.statusPage.v1.StatusPageService
548 .deleteStatusPage({
549 id: "page_123",
550 });
551```
552
553#### `addMonitorComponent(request)`
554
555Add a monitor-based component to a status page.
556
557```typescript
558const { component } = await client.statusPage.v1.StatusPageService
559 .addMonitorComponent({
560 pageId: "page_123",
561 monitorId: "mon_456",
562 name: "API Server",
563 description: "Main API endpoint",
564 order: 1,
565 });
566```
567
568#### `addStaticComponent(request)`
569
570Add a static component (not linked to a monitor).
571
572```typescript
573const { component } = await client.statusPage.v1.StatusPageService
574 .addStaticComponent({
575 pageId: "page_123",
576 name: "Third-party Service",
577 description: "External dependency",
578 order: 2,
579 });
580```
581
582#### `updateComponent(request)`
583
584Update a component.
585
586```typescript
587const { component } = await client.statusPage.v1.StatusPageService
588 .updateComponent({
589 id: "comp_123",
590 name: "Updated Component Name",
591 order: 3,
592 });
593```
594
595#### `removeComponent(request)`
596
597Remove a component from a status page.
598
599```typescript
600const { success } = await client.statusPage.v1.StatusPageService
601 .removeComponent({
602 id: "comp_123",
603 });
604```
605
606#### `createComponentGroup(request)`
607
608Create a component group.
609
610```typescript
611const { group } = await client.statusPage.v1.StatusPageService
612 .createComponentGroup({
613 pageId: "page_123",
614 name: "Core Services",
615 });
616```
617
618#### `updateComponentGroup(request)`
619
620Update a component group.
621
622```typescript
623const { group } = await client.statusPage.v1.StatusPageService
624 .updateComponentGroup({
625 id: "group_123",
626 name: "Updated Group Name",
627 });
628```
629
630#### `deleteComponentGroup(request)`
631
632Delete a component group.
633
634```typescript
635const { success } = await client.statusPage.v1.StatusPageService
636 .deleteComponentGroup({
637 id: "group_123",
638 });
639```
640
641#### `subscribeToPage(request)`
642
643Subscribe an email to status page updates.
644
645```typescript
646const { subscriber } = await client.statusPage.v1.StatusPageService
647 .subscribeToPage({
648 pageId: "page_123",
649 email: "user@example.com",
650 });
651```
652
653#### `unsubscribeFromPage(request)`
654
655Unsubscribe from a status page.
656
657```typescript
658// By email
659const { success } = await client.statusPage.v1.StatusPageService
660 .unsubscribeFromPage({
661 pageId: "page_123",
662 identifier: { case: "email", value: "user@example.com" },
663 });
664
665// Or by subscriber ID
666const { success: success2 } = await client.statusPage.v1.StatusPageService
667 .unsubscribeFromPage({
668 pageId: "page_123",
669 identifier: { case: "id", value: "sub_456" },
670 });
671```
672
673#### `listSubscribers(request)`
674
675List all subscribers for a status page.
676
677```typescript
678const { subscribers, totalSize } = await client.statusPage.v1.StatusPageService
679 .listSubscribers({
680 pageId: "page_123",
681 limit: 50,
682 offset: 0,
683 includeUnsubscribed: false,
684 });
685```
686
687#### `getStatusPageContent(request)`
688
689Get full status page content including components, groups, and active reports.
690
691```typescript
692const content = await client.statusPage.v1.StatusPageService
693 .getStatusPageContent({
694 identifier: { case: "slug", value: "my-service" },
695 });
696
697console.log(`Page: ${content.statusPage?.title}`);
698console.log(`Components: ${content.components.length}`);
699console.log(`Active reports: ${content.statusReports.length}`);
700```
701
702#### `getOverallStatus(request)`
703
704Get the aggregated status of a status page.
705
706```typescript
707import { OverallStatus } from "@openstatus/sdk-node";
708
709const { overallStatus, componentStatuses } = await client.statusPage.v1
710 .StatusPageService.getOverallStatus({
711 identifier: { case: "id", value: "page_123" },
712 });
713
714console.log(`Overall: ${OverallStatus[overallStatus]}`);
715for (const { componentId, status } of componentStatuses) {
716 console.log(` ${componentId}: ${OverallStatus[status]}`);
717}
718```
719
720---
721
722### Maintenance Service
723
724Manage scheduled maintenance windows.
725
726#### `createMaintenance(request)`
727
728Create a new maintenance window.
729
730```typescript
731const { maintenance } = await client.maintenance.v1.MaintenanceService
732 .createMaintenance({
733 title: "Database Upgrade",
734 message: "We will be upgrading our database infrastructure.",
735 from: "2024-01-20T02:00:00Z",
736 to: "2024-01-20T04:00:00Z",
737 pageId: "page_123",
738 pageComponentIds: ["comp_456"],
739 notify: true,
740 });
741
742console.log(`Maintenance created: ${maintenance?.id}`);
743```
744
745#### `getMaintenance(request)`
746
747Get a maintenance window by ID.
748
749```typescript
750const { maintenance } = await client.maintenance.v1.MaintenanceService
751 .getMaintenance({
752 id: "maint_123",
753 });
754
755console.log(`Title: ${maintenance?.title}`);
756console.log(`From: ${maintenance?.from}`);
757console.log(`To: ${maintenance?.to}`);
758```
759
760#### `listMaintenances(request)`
761
762List all maintenance windows with pagination and optional filtering.
763
764```typescript
765const { maintenances, totalSize } = await client.maintenance.v1
766 .MaintenanceService.listMaintenances({
767 limit: 10,
768 offset: 0,
769 pageId: "page_123", // optional filter
770 });
771
772console.log(`Found ${totalSize} maintenance windows`);
773```
774
775#### `updateMaintenance(request)`
776
777Update a maintenance window.
778
779```typescript
780const { maintenance } = await client.maintenance.v1.MaintenanceService
781 .updateMaintenance({
782 id: "maint_123",
783 title: "Extended Database Upgrade",
784 to: "2024-01-20T06:00:00Z",
785 });
786```
787
788#### `deleteMaintenance(request)`
789
790Delete a maintenance window.
791
792```typescript
793const { success } = await client.maintenance.v1.MaintenanceService
794 .deleteMaintenance({
795 id: "maint_123",
796 });
797```
798
799---
800
801### Notification Service
802
803Manage notification channels for monitor alerts. Supports 12 providers including
804Slack, Discord, Email, PagerDuty, and custom webhooks.
805
806#### `createNotification(request)`
807
808Create a new notification channel.
809
810```typescript
811import { NotificationProvider } from "@openstatus/sdk-node";
812
813const { notification } = await client.notification.v1.NotificationService
814 .createNotification({
815 name: "Slack Alerts",
816 provider: NotificationProvider.SLACK,
817 data: {
818 data: {
819 case: "slack",
820 value: { webhookUrl: "https://hooks.slack.com/services/..." },
821 },
822 },
823 monitorIds: ["mon_123", "mon_456"],
824 });
825
826console.log(`Notification created: ${notification?.id}`);
827```
828
829#### `getNotification(request)`
830
831Get a notification channel by ID.
832
833```typescript
834import { NotificationProvider } from "@openstatus/sdk-node";
835
836const { notification } = await client.notification.v1.NotificationService
837 .getNotification({
838 id: "notif_123",
839 });
840
841console.log(`Name: ${notification?.name}`);
842console.log(`Provider: ${NotificationProvider[notification?.provider ?? 0]}`);
843```
844
845#### `listNotifications(request)`
846
847List all notification channels with pagination.
848
849```typescript
850const { notifications, totalSize } = await client.notification.v1
851 .NotificationService.listNotifications({ limit: 10, offset: 0 });
852
853console.log(`Found ${totalSize} notification channels`);
854```
855
856#### `updateNotification(request)`
857
858Update a notification channel.
859
860```typescript
861const { notification } = await client.notification.v1.NotificationService
862 .updateNotification({
863 id: "notif_123",
864 name: "Updated Slack Alerts",
865 monitorIds: ["mon_123", "mon_456", "mon_789"],
866 });
867```
868
869#### `deleteNotification(request)`
870
871Delete a notification channel.
872
873```typescript
874const { success } = await client.notification.v1.NotificationService
875 .deleteNotification({
876 id: "notif_123",
877 });
878```
879
880#### `sendTestNotification(request)`
881
882Send a test notification to verify configuration.
883
884```typescript
885import { NotificationProvider } from "@openstatus/sdk-node";
886
887const { success, errorMessage } = await client.notification.v1
888 .NotificationService.sendTestNotification({
889 provider: NotificationProvider.SLACK,
890 data: {
891 data: {
892 case: "slack",
893 value: { webhookUrl: "https://hooks.slack.com/services/..." },
894 },
895 },
896 });
897
898if (success) {
899 console.log("Test notification sent successfully");
900} else {
901 console.log(`Test failed: ${errorMessage}`);
902}
903```
904
905#### `checkNotificationLimit(request)`
906
907Check if the workspace has reached its notification limit.
908
909```typescript
910const { limitReached, currentCount, maxCount } = await client.notification.v1
911 .NotificationService.checkNotificationLimit({});
912
913console.log(`${currentCount}/${maxCount} notification channels used`);
914```
915
916#### Provider Configuration Examples
917
918<details>
919<summary><strong>Slack</strong></summary>
920
921```typescript
922{
923 provider: NotificationProvider.SLACK,
924 data: {
925 data: {
926 case: "slack",
927 value: { webhookUrl: "https://hooks.slack.com/services/..." }
928 }
929 }
930}
931```
932
933</details>
934
935<details>
936<summary><strong>Discord</strong></summary>
937
938```typescript
939{
940 provider: NotificationProvider.DISCORD,
941 data: {
942 data: {
943 case: "discord",
944 value: { webhookUrl: "https://discord.com/api/webhooks/..." }
945 }
946 }
947}
948```
949
950</details>
951
952<details>
953<summary><strong>Email</strong></summary>
954
955```typescript
956{
957 provider: NotificationProvider.EMAIL,
958 data: {
959 data: {
960 case: "email",
961 value: { email: "alerts@example.com" }
962 }
963 }
964}
965```
966
967</details>
968
969<details>
970<summary><strong>PagerDuty</strong></summary>
971
972```typescript
973{
974 provider: NotificationProvider.PAGERDUTY,
975 data: {
976 data: {
977 case: "pagerduty",
978 value: { integrationKey: "your-integration-key" }
979 }
980 }
981}
982```
983
984</details>
985
986<details>
987<summary><strong>Opsgenie</strong></summary>
988
989```typescript
990import { OpsgenieRegion } from "@openstatus/sdk-node";
991
992{
993 provider: NotificationProvider.OPSGENIE,
994 data: {
995 data: {
996 case: "opsgenie",
997 value: { apiKey: "your-api-key", region: OpsgenieRegion.US }
998 }
999 }
1000}
1001```
1002
1003</details>
1004
1005<details>
1006<summary><strong>Telegram</strong></summary>
1007
1008```typescript
1009{
1010 provider: NotificationProvider.TELEGRAM,
1011 data: {
1012 data: {
1013 case: "telegram",
1014 value: { chatId: "123456789" }
1015 }
1016 }
1017}
1018```
1019
1020</details>
1021
1022<details>
1023<summary><strong>Google Chat</strong></summary>
1024
1025```typescript
1026{
1027 provider: NotificationProvider.GOOGLE_CHAT,
1028 data: {
1029 data: {
1030 case: "googleChat",
1031 value: { webhookUrl: "https://chat.googleapis.com/v1/spaces/..." }
1032 }
1033 }
1034}
1035```
1036
1037</details>
1038
1039<details>
1040<summary><strong>Grafana OnCall</strong></summary>
1041
1042```typescript
1043{
1044 provider: NotificationProvider.GRAFANA_ONCALL,
1045 data: {
1046 data: {
1047 case: "grafanaOncall",
1048 value: { webhookUrl: "https://oncall.example.com/..." }
1049 }
1050 }
1051}
1052```
1053
1054</details>
1055
1056<details>
1057<summary><strong>Ntfy</strong></summary>
1058
1059```typescript
1060{
1061 provider: NotificationProvider.NTFY,
1062 data: {
1063 data: {
1064 case: "ntfy",
1065 value: {
1066 topic: "my-alerts",
1067 serverUrl: "https://ntfy.sh", // optional, defaults to ntfy.sh
1068 token: "tk_..." // optional auth token
1069 }
1070 }
1071 }
1072}
1073```
1074
1075</details>
1076
1077<details>
1078<summary><strong>SMS</strong></summary>
1079
1080```typescript
1081{
1082 provider: NotificationProvider.SMS,
1083 data: {
1084 data: {
1085 case: "sms",
1086 value: { phoneNumber: "+1234567890" }
1087 }
1088 }
1089}
1090```
1091
1092</details>
1093
1094<details>
1095<summary><strong>WhatsApp</strong></summary>
1096
1097```typescript
1098{
1099 provider: NotificationProvider.WHATSAPP,
1100 data: {
1101 data: {
1102 case: "whatsapp",
1103 value: { phoneNumber: "+1234567890" }
1104 }
1105 }
1106}
1107```
1108
1109</details>
1110
1111<details>
1112<summary><strong>Custom Webhook</strong></summary>
1113
1114```typescript
1115{
1116 provider: NotificationProvider.WEBHOOK,
1117 data: {
1118 data: {
1119 case: "webhook",
1120 value: {
1121 endpoint: "https://api.example.com/webhook",
1122 headers: [
1123 { key: "Authorization", value: "Bearer token" },
1124 { key: "X-Custom-Header", value: "value" }
1125 ]
1126 }
1127 }
1128 }
1129}
1130```
1131
1132</details>
1133
1134---
1135
1136## Reference
1137
1138### Monitor Options
1139
1140#### HTTP Monitor
1141
1142| Option | Type | Required | Description |
1143| ---------------------- | ------------------- | -------- | ------------------------------------------- |
1144| `name` | string | Yes | Monitor name (max 256 chars) |
1145| `url` | string | Yes | URL to monitor (max 2048 chars) |
1146| `periodicity` | Periodicity | Yes | Check interval |
1147| `method` | HTTPMethod | No | HTTP method (default: GET) |
1148| `body` | string | No | Request body |
1149| `headers` | Headers[] | No | Custom headers `{ key, value }[]` |
1150| `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) |
1151| `retry` | bigint | No | Retry attempts (default: 3, max: 10) |
1152| `followRedirects` | boolean | No | Follow redirects (default: true) |
1153| `regions` | Region[] | No | Regions for checks |
1154| `active` | boolean | No | Enable monitoring (default: false) |
1155| `public` | boolean | No | Public visibility (default: false) |
1156| `degradedAt` | bigint | No | Latency threshold (ms) for degraded status |
1157| `description` | string | No | Monitor description (max 1024 chars) |
1158| `statusCodeAssertions` | array | No | Status code assertions |
1159| `bodyAssertions` | array | No | Body assertions |
1160| `headerAssertions` | array | No | Header assertions |
1161| `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration |
1162
1163#### TCP Monitor
1164
1165| Option | Type | Required | Description |
1166| --------------- | ------------------- | -------- | ------------------------------------------- |
1167| `name` | string | Yes | Monitor name (max 256 chars) |
1168| `uri` | string | Yes | `host:port` to monitor (max 2048 chars) |
1169| `periodicity` | Periodicity | Yes | Check interval |
1170| `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) |
1171| `retry` | bigint | No | Retry attempts (default: 3, max: 10) |
1172| `regions` | Region[] | No | Regions for checks |
1173| `active` | boolean | No | Enable monitoring (default: false) |
1174| `public` | boolean | No | Public visibility (default: false) |
1175| `degradedAt` | bigint | No | Latency threshold (ms) for degraded status |
1176| `description` | string | No | Monitor description (max 1024 chars) |
1177| `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration |
1178
1179#### DNS Monitor
1180
1181| Option | Type | Required | Description |
1182| ------------------ | ------------------- | -------- | ------------------------------------------- |
1183| `name` | string | Yes | Monitor name (max 256 chars) |
1184| `uri` | string | Yes | Domain to resolve (max 2048 chars) |
1185| `periodicity` | Periodicity | Yes | Check interval |
1186| `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) |
1187| `retry` | bigint | No | Retry attempts (default: 3, max: 10) |
1188| `regions` | Region[] | No | Regions for checks |
1189| `active` | boolean | No | Enable monitoring (default: false) |
1190| `public` | boolean | No | Public visibility (default: false) |
1191| `degradedAt` | bigint | No | Latency threshold (ms) for degraded status |
1192| `description` | string | No | Monitor description (max 1024 chars) |
1193| `recordAssertions` | array | No | DNS record assertions |
1194| `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration |
1195
1196---
1197
1198### Assertions
1199
1200#### Status Code Assertions
1201
1202Validate HTTP response status codes using `NumberComparator`.
1203
1204```typescript
1205import { NumberComparator } from "@openstatus/sdk-node";
1206
1207{
1208 statusCodeAssertions: [
1209 { comparator: NumberComparator.EQUAL, target: BigInt(200) },
1210 { comparator: NumberComparator.LESS_THAN, target: BigInt(400) },
1211 ];
1212}
1213```
1214
1215#### Body Assertions
1216
1217Validate response body content using `StringComparator`.
1218
1219```typescript
1220import { StringComparator } from "@openstatus/sdk-node";
1221
1222{
1223 bodyAssertions: [
1224 { comparator: StringComparator.CONTAINS, target: '"status":"ok"' },
1225 { comparator: StringComparator.NOT_EMPTY, target: "" },
1226 ];
1227}
1228```
1229
1230#### Header Assertions
1231
1232Validate response headers using `StringComparator`.
1233
1234```typescript
1235import { StringComparator } from "@openstatus/sdk-node";
1236
1237{
1238 headerAssertions: [
1239 {
1240 key: "content-type",
1241 comparator: StringComparator.CONTAINS,
1242 target: "application/json",
1243 },
1244 ];
1245}
1246```
1247
1248#### DNS Record Assertions
1249
1250Validate DNS records using `RecordComparator`.
1251
1252```typescript
1253import { RecordComparator } from "@openstatus/sdk-node";
1254
1255{
1256 recordAssertions: [
1257 {
1258 record: "A",
1259 comparator: RecordComparator.EQUAL,
1260 target: "93.184.216.34",
1261 },
1262 { record: "CNAME", comparator: RecordComparator.CONTAINS, target: "cdn" },
1263 ];
1264}
1265```
1266
1267**Supported record types:** `A`, `AAAA`, `CNAME`, `MX`, `TXT`
1268
1269---
1270
1271### Regions
1272
1273Monitor from 28 global locations across multiple providers.
1274
1275```typescript
1276import { Region } from "@openstatus/sdk-node";
1277
1278regions: [Region.FLY_AMS, Region.FLY_IAD, Region.KOYEB_FRA];
1279```
1280
1281#### Fly.io Regions (18)
1282
1283| Enum Value | Location |
1284| ---------- | --------------- |
1285| `FLY_AMS` | Amsterdam |
1286| `FLY_ARN` | Stockholm |
1287| `FLY_BOM` | Mumbai |
1288| `FLY_CDG` | Paris |
1289| `FLY_DFW` | Dallas |
1290| `FLY_EWR` | Newark |
1291| `FLY_FRA` | Frankfurt |
1292| `FLY_GRU` | São Paulo |
1293| `FLY_IAD` | Washington D.C. |
1294| `FLY_JNB` | Johannesburg |
1295| `FLY_LAX` | Los Angeles |
1296| `FLY_LHR` | London |
1297| `FLY_NRT` | Tokyo |
1298| `FLY_ORD` | Chicago |
1299| `FLY_SJC` | San Jose |
1300| `FLY_SIN` | Singapore |
1301| `FLY_SYD` | Sydney |
1302| `FLY_YYZ` | Toronto |
1303
1304#### Koyeb Regions (6)
1305
1306| Enum Value | Location |
1307| ----------- | ------------- |
1308| `KOYEB_FRA` | Frankfurt |
1309| `KOYEB_PAR` | Paris |
1310| `KOYEB_SFO` | San Francisco |
1311| `KOYEB_SIN` | Singapore |
1312| `KOYEB_TYO` | Tokyo |
1313| `KOYEB_WAS` | Washington |
1314
1315#### Railway Regions (4)
1316
1317| Enum Value | Location |
1318| ------------------------- | -------------- |
1319| `RAILWAY_US_WEST2` | US West |
1320| `RAILWAY_US_EAST4` | US East |
1321| `RAILWAY_EUROPE_WEST4` | Europe West |
1322| `RAILWAY_ASIA_SOUTHEAST1` | Asia Southeast |
1323
1324---
1325
1326### Enums
1327
1328#### Periodicity
1329
1330| Value | Description |
1331| ----------------- | ----------- |
1332| `PERIODICITY_30S` | Every 30s |
1333| `PERIODICITY_1M` | Every 1m |
1334| `PERIODICITY_5M` | Every 5m |
1335| `PERIODICITY_10M` | Every 10m |
1336| `PERIODICITY_30M` | Every 30m |
1337| `PERIODICITY_1H` | Every 1h |
1338
1339#### HTTPMethod
1340
1341| Value | Description |
1342| --------------------- | ----------- |
1343| `HTTP_METHOD_GET` | GET |
1344| `HTTP_METHOD_POST` | POST |
1345| `HTTP_METHOD_HEAD` | HEAD |
1346| `HTTP_METHOD_PUT` | PUT |
1347| `HTTP_METHOD_PATCH` | PATCH |
1348| `HTTP_METHOD_DELETE` | DELETE |
1349| `HTTP_METHOD_TRACE` | TRACE |
1350| `HTTP_METHOD_CONNECT` | CONNECT |
1351| `HTTP_METHOD_OPTIONS` | OPTIONS |
1352
1353#### MonitorStatus
1354
1355| Value | Description |
1356| ---------- | -------------------------- |
1357| `ACTIVE` | Monitor is healthy |
1358| `DEGRADED` | Latency threshold exceeded |
1359| `ERROR` | Monitor is failing |
1360
1361#### TimeRange
1362
1363| Value | Description |
1364| ---------------- | ------------ |
1365| `TIME_RANGE_1D` | Last 1 day |
1366| `TIME_RANGE_7D` | Last 7 days |
1367| `TIME_RANGE_14D` | Last 14 days |
1368
1369#### StatusReportStatus
1370
1371| Value | Description |
1372| --------------- | -------------------------------- |
1373| `INVESTIGATING` | Actively investigating the issue |
1374| `IDENTIFIED` | Root cause has been identified |
1375| `MONITORING` | Fix deployed, monitoring |
1376| `RESOLVED` | Issue fully resolved |
1377
1378#### OverallStatus
1379
1380| Value | Description |
1381| ---------------- | --------------------------- |
1382| `OPERATIONAL` | All systems operational |
1383| `DEGRADED` | Performance is degraded |
1384| `PARTIAL_OUTAGE` | Some systems are down |
1385| `MAJOR_OUTAGE` | Major systems are down |
1386| `MAINTENANCE` | Scheduled maintenance |
1387| `UNKNOWN` | Status cannot be determined |
1388
1389#### NotificationProvider
1390
1391| Value | Description |
1392| ---------------- | ------------------- |
1393| `DISCORD` | Discord webhook |
1394| `EMAIL` | Email notification |
1395| `GOOGLE_CHAT` | Google Chat webhook |
1396| `GRAFANA_ONCALL` | Grafana OnCall |
1397| `NTFY` | Ntfy push service |
1398| `PAGERDUTY` | PagerDuty |
1399| `OPSGENIE` | Opsgenie |
1400| `SLACK` | Slack webhook |
1401| `SMS` | SMS notification |
1402| `TELEGRAM` | Telegram bot |
1403| `WEBHOOK` | Custom webhook |
1404| `WHATSAPP` | WhatsApp |
1405
1406#### OpsgenieRegion
1407
1408| Value | Description |
1409| ----- | ----------- |
1410| `US` | US region |
1411| `EU` | EU region |
1412
1413#### PageAccessType
1414
1415| Value | Description |
1416| -------------------- | ----------------------- |
1417| `PUBLIC` | Publicly accessible |
1418| `PASSWORD_PROTECTED` | Requires password |
1419| `AUTHENTICATED` | Requires authentication |
1420
1421#### PageTheme
1422
1423| Value | Description |
1424| -------- | ------------------- |
1425| `SYSTEM` | Follow system theme |
1426| `LIGHT` | Light theme |
1427| `DARK` | Dark theme |
1428
1429#### PageComponentType
1430
1431| Value | Description |
1432| --------- | ------------------------- |
1433| `MONITOR` | Linked to a monitor |
1434| `STATIC` | Static component (manual) |
1435
1436#### NumberComparator
1437
1438| Value | Description |
1439| ----------------------- | --------------------- |
1440| `EQUAL` | Equal to target |
1441| `NOT_EQUAL` | Not equal to target |
1442| `GREATER_THAN` | Greater than target |
1443| `GREATER_THAN_OR_EQUAL` | Greater than or equal |
1444| `LESS_THAN` | Less than target |
1445| `LESS_THAN_OR_EQUAL` | Less than or equal |
1446
1447#### StringComparator
1448
1449| Value | Description |
1450| ----------------------- | --------------------------- |
1451| `CONTAINS` | Contains target string |
1452| `NOT_CONTAINS` | Does not contain target |
1453| `EQUAL` | Equal to target |
1454| `NOT_EQUAL` | Not equal to target |
1455| `EMPTY` | Value is empty |
1456| `NOT_EMPTY` | Value is not empty |
1457| `GREATER_THAN` | Lexicographically greater |
1458| `GREATER_THAN_OR_EQUAL` | Lexicographically >= target |
1459| `LESS_THAN` | Lexicographically less |
1460| `LESS_THAN_OR_EQUAL` | Lexicographically <= target |
1461
1462#### RecordComparator
1463
1464| Value | Description |
1465| -------------- | ----------------------- |
1466| `EQUAL` | Equal to target |
1467| `NOT_EQUAL` | Not equal to target |
1468| `CONTAINS` | Contains target string |
1469| `NOT_CONTAINS` | Does not contain target |
1470
1471---
1472
1473## Error Handling
1474
1475The SDK uses Connect RPC. Errors include a `code` and `message`:
1476
1477```typescript
1478import { ConnectError } from "@connectrpc/connect";
1479
1480try {
1481 await client.monitor.v1.MonitorService.deleteMonitor({ id: "invalid" });
1482} catch (error) {
1483 if (error instanceof ConnectError) {
1484 console.error(`Error ${error.code}: ${error.message}`);
1485 }
1486}
1487```
1488
1489## Related
1490
1491- [OpenStatus](https://openstatus.dev) - Open-source monitoring platform
1492- [Documentation](https://docs.openstatus.dev) - Full API documentation
1493- [Status Page](https://status.openstatus.dev) - OpenStatus service status
1494
1495## License
1496
1497MIT