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## Features
11
12### Status Page
13
14- **Status Pages** - Create and manage public status pages with custom domains
15- **Page Components** - Add monitor-based or static components with grouping
16- **Subscribers** - Manage email subscriptions for status updates
17- **Status Reports** - Manage incident reports with update timelines
18- **Maintenance Windows** - Schedule and manage planned maintenance periods
19
20### Monitoring
21
22- **HTTP Monitoring** - Monitor websites and APIs with customizable assertions
23- **TCP Monitoring** - Check database connections and other TCP services
24- **DNS Monitoring** - Verify DNS records and resolution
25
26- **Global Regions** - Monitor from 28 locations worldwide
27- **Type-safe** - Full TypeScript support with generated types from protobuf
28
29## Installation
30
31### JSR
32
33```bash
34npx jsr add @openstatus/sdk-node
35```
36
37### npm
38
39```bash
40npm install @openstatus/sdk-node
41```
42
43### Deno
44
45```typescript
46import { openstatus } from "jsr:@openstatus/sdk-node";
47```
48
49## Quick Start
50
51```typescript
52import {
53 HTTPMethod,
54 NumberComparator,
55 openstatus,
56 Periodicity,
57 Region,
58} from "@openstatus/sdk-node";
59
60const headers = {
61 "x-openstatus-key": `${process.env.OPENSTATUS_API_KEY}`,
62};
63
64// Create a monitor
65const { monitor } = await openstatus.monitor.v1.MonitorService
66 .createHTTPMonitor(
67 {
68 monitor: {
69 name: "My API",
70 url: "https://api.example.com/health",
71 periodicity: Periodicity.PERIODICITY_1M,
72 method: HTTPMethod.HTTP_METHOD_GET,
73 regions: [Region.FLY_AMS, Region.FLY_IAD, Region.FLY_SYD],
74 active: true,
75 statusCodeAssertions: [
76 { comparator: NumberComparator.EQUAL, target: BigInt(200) },
77 ],
78 },
79 },
80 { headers },
81 );
82
83console.log(`Monitor created: ${monitor?.id}`);
84
85// List all monitors
86const { httpMonitors, tcpMonitors, dnsMonitors, totalSize } = await openstatus
87 .monitor.v1.MonitorService.listMonitors({}, { headers });
88
89console.log(`Found ${totalSize} monitors`);
90```
91
92## Authentication
93
94All API requests require an API key. Get yours from the
95[OpenStatus dashboard](https://www.openstatus.dev/app).
96
97```typescript
98const headers = {
99 "x-openstatus-key": `${process.env.OPENSTATUS_API_KEY}`,
100};
101
102// Pass headers to any service method
103await openstatus.monitor.v1.MonitorService.listMonitors({}, { headers });
104```
105
106## Environment Variables
107
108| Variable | Description | Default |
109| -------------------- | ----------------------- | -------------------------------- |
110| `OPENSTATUS_API_KEY` | Your OpenStatus API key | - |
111| `OPENSTATUS_API_URL` | Custom API endpoint | `https://api.openstatus.dev/rpc` |
112
113## API Reference
114
115### Monitor Service
116
117#### `createHTTPMonitor(request, options)`
118
119Create an HTTP/HTTPS monitor.
120
121```typescript
122import { HTTPMethod, Periodicity, Region } from "@openstatus/sdk-node";
123
124const { monitor } = await openstatus.monitor.v1.MonitorService
125 .createHTTPMonitor(
126 {
127 monitor: {
128 name: "My Website",
129 url: "https://example.com",
130 periodicity: Periodicity.PERIODICITY_1M,
131 method: HTTPMethod.HTTP_METHOD_GET,
132 regions: [Region.FLY_AMS, Region.FLY_IAD, Region.FLY_SYD],
133 active: true,
134 },
135 },
136 { headers },
137 );
138```
139
140#### `updateHTTPMonitor(request, options)`
141
142Update an existing HTTP monitor.
143
144```typescript
145const { monitor } = await openstatus.monitor.v1.MonitorService
146 .updateHTTPMonitor(
147 {
148 id: "mon_123",
149 monitor: {
150 name: "Updated Name",
151 active: false,
152 },
153 },
154 { headers },
155 );
156```
157
158#### `createTCPMonitor(request, options)`
159
160Create a TCP connection monitor.
161
162```typescript
163const { monitor } = await openstatus.monitor.v1.MonitorService.createTCPMonitor(
164 {
165 monitor: {
166 name: "Database",
167 uri: "db.example.com:5432",
168 periodicity: Periodicity.PERIODICITY_5M,
169 regions: [Region.FLY_AMS, Region.FLY_IAD],
170 active: true,
171 },
172 },
173 { headers },
174);
175```
176
177#### `updateTCPMonitor(request, options)`
178
179Update an existing TCP monitor.
180
181```typescript
182const { monitor } = await openstatus.monitor.v1.MonitorService.updateTCPMonitor(
183 {
184 id: "mon_123",
185 monitor: {
186 name: "Updated Database Monitor",
187 },
188 },
189 { headers },
190);
191```
192
193#### `createDNSMonitor(request, options)`
194
195Create a DNS resolution monitor.
196
197```typescript
198import { RecordComparator } from "@openstatus/sdk-node";
199
200const { monitor } = await openstatus.monitor.v1.MonitorService.createDNSMonitor(
201 {
202 monitor: {
203 name: "DNS Check",
204 uri: "example.com",
205 periodicity: Periodicity.PERIODICITY_10M,
206 regions: [Region.FLY_AMS],
207 active: true,
208 recordAssertions: [
209 {
210 record: "A",
211 comparator: RecordComparator.EQUAL,
212 target: "93.184.216.34",
213 },
214 ],
215 },
216 },
217 { headers },
218);
219```
220
221#### `updateDNSMonitor(request, options)`
222
223Update an existing DNS monitor.
224
225```typescript
226const { monitor } = await openstatus.monitor.v1.MonitorService.updateDNSMonitor(
227 {
228 id: "mon_123",
229 monitor: {
230 name: "Updated DNS Check",
231 },
232 },
233 { headers },
234);
235```
236
237#### `listMonitors(request, options)`
238
239List all monitors with pagination. Returns monitors grouped by type.
240
241```typescript
242const { httpMonitors, tcpMonitors, dnsMonitors, nextPageToken, totalSize } =
243 await openstatus.monitor.v1.MonitorService.listMonitors(
244 { pageSize: 10, pageToken: "" },
245 { headers },
246 );
247```
248
249#### `triggerMonitor(request, options)`
250
251Trigger an immediate check.
252
253```typescript
254const { success } = await openstatus.monitor.v1.MonitorService.triggerMonitor(
255 { id: "mon_123" },
256 { headers },
257);
258```
259
260#### `deleteMonitor(request, options)`
261
262Delete a monitor.
263
264```typescript
265const { success } = await openstatus.monitor.v1.MonitorService.deleteMonitor(
266 { id: "mon_123" },
267 { headers },
268);
269```
270
271#### `getMonitorStatus(request, options)`
272
273Get the current status of a monitor across all configured regions.
274
275```typescript
276import { MonitorStatus, Region } from "@openstatus/sdk-node";
277
278const { id, regions } = await openstatus.monitor.v1.MonitorService
279 .getMonitorStatus(
280 { id: "mon_123" },
281 { headers },
282 );
283
284// regions is an array of { region, status }
285// region: Region enum value (e.g., Region.FLY_AMS)
286// status: MonitorStatus.ACTIVE, MonitorStatus.DEGRADED, or MonitorStatus.ERROR
287for (const { region, status } of regions) {
288 console.log(`${Region[region]}: ${MonitorStatus[status]}`);
289}
290```
291
292#### `getMonitorSummary(request, options)`
293
294Get aggregated metrics and latency percentiles for a monitor.
295
296```typescript
297import { TimeRange } from "@openstatus/sdk-node";
298
299const summary = await openstatus.monitor.v1.MonitorService.getMonitorSummary(
300 {
301 id: "mon_123",
302 timeRange: TimeRange.TIME_RANGE_7D, // TIME_RANGE_1D, TIME_RANGE_7D, or TIME_RANGE_14D
303 regions: [], // optional: filter by specific regions
304 },
305 { headers },
306);
307
308console.log(`Last ping: ${summary.lastPingAt}`);
309console.log(`Success: ${summary.totalSuccessful}`);
310console.log(`Degraded: ${summary.totalDegraded}`);
311console.log(`Failed: ${summary.totalFailed}`);
312console.log(`P50 latency: ${summary.p50}ms`);
313console.log(`P75 latency: ${summary.p75}ms`);
314console.log(`P90 latency: ${summary.p90}ms`);
315console.log(`P95 latency: ${summary.p95}ms`);
316console.log(`P99 latency: ${summary.p99}ms`);
317```
318
319### Health Service
320
321Check API health status (no authentication required).
322
323```typescript
324import { ServingStatus } from "@openstatus/sdk-node";
325
326const { status } = await openstatus.health.v1.HealthService.check({});
327console.log(ServingStatus[status]); // "SERVING"
328```
329
330### Status Report Service
331
332Manage incident and maintenance reports with update timelines.
333
334#### `createStatusReport(request, options)`
335
336Create a new status report.
337
338```typescript
339import { StatusReportStatus } from "@openstatus/sdk-node";
340
341const { statusReport } = await openstatus.statusReport.v1.StatusReportService
342 .createStatusReport(
343 {
344 title: "API Degradation",
345 status: StatusReportStatus.INVESTIGATING,
346 message: "We are investigating reports of increased latency.",
347 date: "2024-01-15T10:30:00",
348 pageId: "page_123",
349 pageComponentIds: ["comp_456"],
350 notify: true,
351 },
352 { headers },
353 );
354
355console.log(`Status report created: ${statusReport?.id}`);
356```
357
358#### `getStatusReport(request, options)`
359
360Get a status report by ID (includes full update timeline).
361
362```typescript
363const { statusReport } = await openstatus.statusReport.v1.StatusReportService
364 .getStatusReport(
365 { id: "sr_123" },
366 { headers },
367 );
368
369console.log(`Title: ${statusReport?.title}`);
370console.log(`Status: ${StatusReportStatus[statusReport?.status ?? 0]}`);
371
372// Access update timeline
373for (const update of statusReport?.updates ?? []) {
374 console.log(`${update.date}: ${update.message}`);
375}
376```
377
378#### `listStatusReports(request, options)`
379
380List all status reports with pagination and optional filtering.
381
382```typescript
383import { StatusReportStatus } from "@openstatus/sdk-node";
384
385const { statusReports, totalSize } = await openstatus.statusReport.v1
386 .StatusReportService.listStatusReports(
387 {
388 limit: 10,
389 offset: 0,
390 statuses: [
391 StatusReportStatus.INVESTIGATING,
392 StatusReportStatus.IDENTIFIED,
393 ],
394 },
395 { headers },
396 );
397
398console.log(`Found ${totalSize} status reports`);
399```
400
401#### `updateStatusReport(request, options)`
402
403Update status report metadata (title, page components).
404
405```typescript
406const { statusReport } = await openstatus.statusReport.v1.StatusReportService
407 .updateStatusReport(
408 {
409 id: "sr_123",
410 title: "Updated Title",
411 pageComponentIds: ["comp_456", "comp_789"],
412 },
413 { headers },
414 );
415```
416
417#### `deleteStatusReport(request, options)`
418
419Delete a status report and all its updates.
420
421```typescript
422const { success } = await openstatus.statusReport.v1.StatusReportService
423 .deleteStatusReport(
424 { id: "sr_123" },
425 { headers },
426 );
427```
428
429#### `addStatusReportUpdate(request, options)`
430
431Add a new update to an existing status report timeline.
432
433```typescript
434import { StatusReportStatus } from "@openstatus/sdk-node";
435
436const { statusReport } = await openstatus.statusReport.v1.StatusReportService
437 .addStatusReportUpdate(
438 {
439 statusReportId: "sr_123",
440 status: StatusReportStatus.IDENTIFIED,
441 message:
442 "The issue has been identified as a database connection problem.",
443 date: "2024-01-15T11:00:00", // optional, defaults to current time
444 notify: true,
445 },
446 { headers },
447 );
448```
449
450### Status Report Status
451
452| Enum Value | Description |
453| --------------- | -------------------------------- |
454| `UNSPECIFIED` | Default/unspecified status |
455| `INVESTIGATING` | Actively investigating the issue |
456| `IDENTIFIED` | Root cause has been identified |
457| `MONITORING` | Fix deployed, monitoring |
458| `RESOLVED` | Issue fully resolved |
459
460### Status Page Service
461
462Manage status pages, components, and subscribers.
463
464#### `createStatusPage(request, options)`
465
466Create a new status page.
467
468```typescript
469const { statusPage } = await openstatus.statusPage.v1.StatusPageService
470 .createStatusPage(
471 {
472 title: "My Service Status",
473 slug: "my-service",
474 description: "Status page for My Service",
475 homepageUrl: "https://example.com",
476 contactUrl: "https://example.com/contact",
477 },
478 { headers },
479 );
480
481console.log(`Status page created: ${statusPage?.id}`);
482```
483
484#### `getStatusPage(request, options)`
485
486Get a status page by ID.
487
488```typescript
489const { statusPage } = await openstatus.statusPage.v1.StatusPageService
490 .getStatusPage(
491 { id: "page_123" },
492 { headers },
493 );
494```
495
496#### `listStatusPages(request, options)`
497
498List all status pages with pagination.
499
500```typescript
501const { statusPages, totalSize } = await openstatus.statusPage.v1
502 .StatusPageService.listStatusPages(
503 { limit: 10, offset: 0 },
504 { headers },
505 );
506
507console.log(`Found ${totalSize} status pages`);
508```
509
510#### `updateStatusPage(request, options)`
511
512Update a status page.
513
514```typescript
515const { statusPage } = await openstatus.statusPage.v1.StatusPageService
516 .updateStatusPage(
517 {
518 id: "page_123",
519 title: "Updated Title",
520 description: "Updated description",
521 },
522 { headers },
523 );
524```
525
526#### `deleteStatusPage(request, options)`
527
528Delete a status page.
529
530```typescript
531const { success } = await openstatus.statusPage.v1.StatusPageService
532 .deleteStatusPage(
533 { id: "page_123" },
534 { headers },
535 );
536```
537
538#### `addMonitorComponent(request, options)`
539
540Add a monitor-based component to a status page.
541
542```typescript
543const { component } = await openstatus.statusPage.v1.StatusPageService
544 .addMonitorComponent(
545 {
546 pageId: "page_123",
547 monitorId: "mon_456",
548 name: "API Server",
549 description: "Main API endpoint",
550 order: 1,
551 },
552 { headers },
553 );
554```
555
556#### `addStaticComponent(request, options)`
557
558Add a static component (not linked to a monitor).
559
560```typescript
561const { component } = await openstatus.statusPage.v1.StatusPageService
562 .addStaticComponent(
563 {
564 pageId: "page_123",
565 name: "Third-party Service",
566 description: "External dependency",
567 order: 2,
568 },
569 { headers },
570 );
571```
572
573#### `updateComponent(request, options)`
574
575Update a component.
576
577```typescript
578const { component } = await openstatus.statusPage.v1.StatusPageService
579 .updateComponent(
580 {
581 id: "comp_123",
582 name: "Updated Component Name",
583 order: 3,
584 },
585 { headers },
586 );
587```
588
589#### `removeComponent(request, options)`
590
591Remove a component from a status page.
592
593```typescript
594const { success } = await openstatus.statusPage.v1.StatusPageService
595 .removeComponent(
596 { id: "comp_123" },
597 { headers },
598 );
599```
600
601#### `createComponentGroup(request, options)`
602
603Create a component group.
604
605```typescript
606const { group } = await openstatus.statusPage.v1.StatusPageService
607 .createComponentGroup(
608 {
609 pageId: "page_123",
610 name: "Core Services",
611 },
612 { headers },
613 );
614```
615
616#### `updateComponentGroup(request, options)`
617
618Update a component group.
619
620```typescript
621const { group } = await openstatus.statusPage.v1.StatusPageService
622 .updateComponentGroup(
623 {
624 id: "group_123",
625 name: "Updated Group Name",
626 },
627 { headers },
628 );
629```
630
631#### `deleteComponentGroup(request, options)`
632
633Delete a component group.
634
635```typescript
636const { success } = await openstatus.statusPage.v1.StatusPageService
637 .deleteComponentGroup(
638 { id: "group_123" },
639 { headers },
640 );
641```
642
643#### `subscribeToPage(request, options)`
644
645Subscribe an email to status page updates.
646
647```typescript
648const { subscriber } = await openstatus.statusPage.v1.StatusPageService
649 .subscribeToPage(
650 {
651 pageId: "page_123",
652 email: "user@example.com",
653 },
654 { headers },
655 );
656```
657
658#### `unsubscribeFromPage(request, options)`
659
660Unsubscribe from a status page.
661
662```typescript
663// By email
664const { success } = await openstatus.statusPage.v1.StatusPageService
665 .unsubscribeFromPage(
666 {
667 pageId: "page_123",
668 identifier: { case: "email", value: "user@example.com" },
669 },
670 { headers },
671 );
672
673// Or by subscriber ID
674const { success: success2 } = await openstatus.statusPage.v1.StatusPageService
675 .unsubscribeFromPage(
676 {
677 pageId: "page_123",
678 identifier: { case: "id", value: "sub_456" },
679 },
680 { headers },
681 );
682```
683
684#### `listSubscribers(request, options)`
685
686List all subscribers for a status page.
687
688```typescript
689const { subscribers, totalSize } = await openstatus.statusPage.v1
690 .StatusPageService.listSubscribers(
691 {
692 pageId: "page_123",
693 limit: 50,
694 offset: 0,
695 includeUnsubscribed: false,
696 },
697 { headers },
698 );
699```
700
701#### `getStatusPageContent(request, options)`
702
703Get full status page content including components, groups, and active reports.
704
705```typescript
706const content = await openstatus.statusPage.v1.StatusPageService
707 .getStatusPageContent(
708 { identifier: { case: "slug", value: "my-service" } },
709 { headers },
710 );
711
712console.log(`Page: ${content.statusPage?.title}`);
713console.log(`Components: ${content.components.length}`);
714console.log(`Active reports: ${content.statusReports.length}`);
715```
716
717#### `getOverallStatus(request, options)`
718
719Get the aggregated status of a status page.
720
721```typescript
722import { OverallStatus } from "@openstatus/sdk-node";
723
724const { overallStatus, componentStatuses } = await openstatus.statusPage.v1
725 .StatusPageService.getOverallStatus(
726 { identifier: { case: "id", value: "page_123" } },
727 { headers },
728 );
729
730console.log(`Overall: ${OverallStatus[overallStatus]}`);
731for (const { componentId, status } of componentStatuses) {
732 console.log(` ${componentId}: ${OverallStatus[status]}`);
733}
734```
735
736### Maintenance Service
737
738Manage scheduled maintenance windows.
739
740#### `createMaintenance(request, options)`
741
742Create a new maintenance window.
743
744```typescript
745const { maintenance } = await openstatus.maintenance.v1.MaintenanceService
746 .createMaintenance(
747 {
748 title: "Database Upgrade",
749 message: "We will be upgrading our database infrastructure.",
750 from: "2024-01-20T02:00:00Z",
751 to: "2024-01-20T04:00:00Z",
752 pageId: "page_123",
753 pageComponentIds: ["comp_456"],
754 notify: true,
755 },
756 { headers },
757 );
758
759console.log(`Maintenance created: ${maintenance?.id}`);
760```
761
762#### `getMaintenance(request, options)`
763
764Get a maintenance window by ID.
765
766```typescript
767const { maintenance } = await openstatus.maintenance.v1.MaintenanceService
768 .getMaintenance(
769 { id: "maint_123" },
770 { headers },
771 );
772
773console.log(`Title: ${maintenance?.title}`);
774console.log(`From: ${maintenance?.from}`);
775console.log(`To: ${maintenance?.to}`);
776```
777
778#### `listMaintenances(request, options)`
779
780List all maintenance windows with pagination and optional filtering.
781
782```typescript
783const { maintenances, totalSize } = await openstatus.maintenance.v1
784 .MaintenanceService.listMaintenances(
785 {
786 limit: 10,
787 offset: 0,
788 pageId: "page_123", // optional filter
789 },
790 { headers },
791 );
792
793console.log(`Found ${totalSize} maintenance windows`);
794```
795
796#### `updateMaintenance(request, options)`
797
798Update a maintenance window.
799
800```typescript
801const { maintenance } = await openstatus.maintenance.v1.MaintenanceService
802 .updateMaintenance(
803 {
804 id: "maint_123",
805 title: "Extended Database Upgrade",
806 to: "2024-01-20T06:00:00Z",
807 },
808 { headers },
809 );
810```
811
812#### `deleteMaintenance(request, options)`
813
814Delete a maintenance window.
815
816```typescript
817const { success } = await openstatus.maintenance.v1.MaintenanceService
818 .deleteMaintenance(
819 { id: "maint_123" },
820 { headers },
821 );
822```
823
824### Status Page Options
825
826| Option | Type | Required | Description |
827| ------------- | ------ | -------- | ---------------------------------------- |
828| `title` | string | Yes | Title of the status page (max 256 chars) |
829| `slug` | string | Yes | URL-friendly slug (lowercase, hyphens) |
830| `description` | string | No | Description (max 2048 chars) |
831| `homepageUrl` | string | No | Link to your homepage |
832| `contactUrl` | string | No | Link to your contact page |
833
834### Page Access Type
835
836| Enum Value | Description |
837| -------------------- | ----------------------- |
838| `UNSPECIFIED` | Default/unspecified |
839| `PUBLIC` | Publicly accessible |
840| `PASSWORD_PROTECTED` | Requires password |
841| `AUTHENTICATED` | Requires authentication |
842
843### Page Theme
844
845| Enum Value | Description |
846| ------------- | ------------------- |
847| `UNSPECIFIED` | Default/unspecified |
848| `SYSTEM` | Follow system theme |
849| `LIGHT` | Light theme |
850| `DARK` | Dark theme |
851
852### Overall Status
853
854| Enum Value | Description |
855| ---------------- | --------------------------- |
856| `UNSPECIFIED` | Default/unspecified |
857| `OPERATIONAL` | All systems operational |
858| `DEGRADED` | Performance is degraded |
859| `PARTIAL_OUTAGE` | Some systems are down |
860| `MAJOR_OUTAGE` | Major systems are down |
861| `MAINTENANCE` | Scheduled maintenance |
862| `UNKNOWN` | Status cannot be determined |
863
864### Page Component Type
865
866| Enum Value | Description |
867| ------------- | ------------------------- |
868| `UNSPECIFIED` | Default/unspecified |
869| `MONITOR` | Linked to a monitor |
870| `STATIC` | Static component (manual) |
871
872## Monitor Options
873
874### HTTP Monitor
875
876| Option | Type | Required | Description |
877| ---------------------- | ------------------- | -------- | --------------------------------------------------- |
878| `name` | string | Yes | Monitor name (max 256 chars) |
879| `url` | string | Yes | URL to monitor (max 2048 chars) |
880| `periodicity` | Periodicity | Yes | Check interval (see [Periodicity](#periodicity)) |
881| `method` | HTTPMethod | No | HTTP method (see [HTTP Methods](#http-methods)) |
882| `body` | string | No | Request body |
883| `headers` | Headers[] | No | Custom headers (`{ key: string, value: string }[]`) |
884| `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) |
885| `retry` | bigint | No | Retry attempts (default: 3, max: 10) |
886| `followRedirects` | boolean | No | Follow redirects (default: true) |
887| `regions` | Region[] | No | [Regions](#regions) for checks |
888| `active` | boolean | No | Enable monitoring (default: false) |
889| `public` | boolean | No | Public visibility (default: false) |
890| `degradedAt` | bigint | No | Latency threshold (ms) for degraded status |
891| `description` | string | No | Monitor description (max 1024 chars) |
892| `statusCodeAssertions` | array | No | [Status code assertions](#status-code-assertions) |
893| `bodyAssertions` | array | No | [Body assertions](#body-assertions) |
894| `headerAssertions` | array | No | [Header assertions](#header-assertions) |
895| `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration |
896
897### TCP Monitor
898
899| Option | Type | Required | Description |
900| --------------- | ------------------- | -------- | ------------------------------------------------ |
901| `name` | string | Yes | Monitor name (max 256 chars) |
902| `uri` | string | Yes | `host:port` to monitor (max 2048 chars) |
903| `periodicity` | Periodicity | Yes | Check interval (see [Periodicity](#periodicity)) |
904| `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) |
905| `retry` | bigint | No | Retry attempts (default: 3, max: 10) |
906| `regions` | Region[] | No | [Regions](#regions) for checks |
907| `active` | boolean | No | Enable monitoring (default: false) |
908| `public` | boolean | No | Public visibility (default: false) |
909| `degradedAt` | bigint | No | Latency threshold (ms) for degraded status |
910| `description` | string | No | Monitor description (max 1024 chars) |
911| `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration |
912
913### DNS Monitor
914
915| Option | Type | Required | Description |
916| ------------------ | ------------------- | -------- | ------------------------------------------------ |
917| `name` | string | Yes | Monitor name (max 256 chars) |
918| `uri` | string | Yes | Domain to resolve (max 2048 chars) |
919| `periodicity` | Periodicity | Yes | Check interval (see [Periodicity](#periodicity)) |
920| `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) |
921| `retry` | bigint | No | Retry attempts (default: 3, max: 10) |
922| `regions` | Region[] | No | [Regions](#regions) for checks |
923| `active` | boolean | No | Enable monitoring (default: false) |
924| `public` | boolean | No | Public visibility (default: false) |
925| `degradedAt` | bigint | No | Latency threshold (ms) for degraded status |
926| `description` | string | No | Monitor description (max 1024 chars) |
927| `recordAssertions` | array | No | [DNS record assertions](#dns-record-assertions) |
928| `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration |
929
930### Periodicity
931
932| Enum Value | Description |
933| ----------------- | ----------- |
934| `PERIODICITY_30S` | Every 30s |
935| `PERIODICITY_1M` | Every 1m |
936| `PERIODICITY_5M` | Every 5m |
937| `PERIODICITY_10M` | Every 10m |
938| `PERIODICITY_30M` | Every 30m |
939| `PERIODICITY_1H` | Every 1h |
940
941### HTTP Methods
942
943| Enum Value | Description |
944| --------------------- | ----------- |
945| `HTTP_METHOD_GET` | GET |
946| `HTTP_METHOD_POST` | POST |
947| `HTTP_METHOD_HEAD` | HEAD |
948| `HTTP_METHOD_PUT` | PUT |
949| `HTTP_METHOD_PATCH` | PATCH |
950| `HTTP_METHOD_DELETE` | DELETE |
951| `HTTP_METHOD_TRACE` | TRACE |
952| `HTTP_METHOD_CONNECT` | CONNECT |
953| `HTTP_METHOD_OPTIONS` | OPTIONS |
954
955## Assertions
956
957All assertion comparators are exported as enums from the SDK.
958
959### Status Code Assertions
960
961Validate HTTP response status codes using `NumberComparator`.
962
963```typescript
964import { NumberComparator } from "@openstatus/sdk-node";
965
966{
967 statusCodeAssertions: [
968 { comparator: NumberComparator.EQUAL, target: BigInt(200) },
969 { comparator: NumberComparator.LESS_THAN, target: BigInt(400) },
970 ];
971}
972```
973
974**NumberComparator values:**
975
976| Enum Value | Description |
977| ----------------------- | --------------------- |
978| `EQUAL` | Equal to target |
979| `NOT_EQUAL` | Not equal to target |
980| `GREATER_THAN` | Greater than target |
981| `GREATER_THAN_OR_EQUAL` | Greater than or equal |
982| `LESS_THAN` | Less than target |
983| `LESS_THAN_OR_EQUAL` | Less than or equal |
984
985### Body Assertions
986
987Validate response body content using `StringComparator`.
988
989```typescript
990import { StringComparator } from "@openstatus/sdk-node";
991
992{
993 bodyAssertions: [
994 { comparator: StringComparator.CONTAINS, target: '"status":"ok"' },
995 { comparator: StringComparator.NOT_EMPTY, target: "" },
996 ];
997}
998```
999
1000**StringComparator values:**
1001
1002| Enum Value | Description |
1003| ----------------------- | --------------------------- |
1004| `CONTAINS` | Contains target string |
1005| `NOT_CONTAINS` | Does not contain target |
1006| `EQUAL` | Equal to target |
1007| `NOT_EQUAL` | Not equal to target |
1008| `EMPTY` | Body is empty |
1009| `NOT_EMPTY` | Body is not empty |
1010| `GREATER_THAN` | Lexicographically greater |
1011| `GREATER_THAN_OR_EQUAL` | Lexicographically >= target |
1012| `LESS_THAN` | Lexicographically less |
1013| `LESS_THAN_OR_EQUAL` | Lexicographically <= target |
1014
1015### Header Assertions
1016
1017Validate response headers using `StringComparator`.
1018
1019```typescript
1020import { StringComparator } from "@openstatus/sdk-node";
1021
1022{
1023 headerAssertions: [
1024 {
1025 key: "content-type",
1026 comparator: StringComparator.CONTAINS,
1027 target: "application/json",
1028 },
1029 ];
1030}
1031```
1032
1033### DNS Record Assertions
1034
1035Validate DNS records using `RecordComparator`.
1036
1037```typescript
1038import { RecordComparator } from "@openstatus/sdk-node";
1039
1040{
1041 recordAssertions: [
1042 {
1043 record: "A",
1044 comparator: RecordComparator.EQUAL,
1045 target: "93.184.216.34",
1046 },
1047 { record: "CNAME", comparator: RecordComparator.CONTAINS, target: "cdn" },
1048 ];
1049}
1050```
1051
1052**RecordComparator values:**
1053
1054| Enum Value | Description |
1055| -------------- | ----------------------- |
1056| `EQUAL` | Equal to target |
1057| `NOT_EQUAL` | Not equal to target |
1058| `CONTAINS` | Contains target string |
1059| `NOT_CONTAINS` | Does not contain target |
1060
1061**Supported record types:** `A`, `AAAA`, `CNAME`, `MX`, `TXT`
1062
1063## Regions
1064
1065Monitor from 28 global locations across multiple providers. Use the `Region`
1066enum:
1067
1068```typescript
1069import { Region } from "@openstatus/sdk-node";
1070
1071// Example: Use specific regions
1072regions: [Region.FLY_AMS, Region.FLY_IAD, Region.KOYEB_FRA];
1073```
1074
1075### Fly.io Regions
1076
1077| Enum Value | Location |
1078| ---------- | --------------- |
1079| `FLY_AMS` | Amsterdam |
1080| `FLY_ARN` | Stockholm |
1081| `FLY_BOM` | Mumbai |
1082| `FLY_CDG` | Paris |
1083| `FLY_DFW` | Dallas |
1084| `FLY_EWR` | Newark |
1085| `FLY_FRA` | Frankfurt |
1086| `FLY_GRU` | São Paulo |
1087| `FLY_IAD` | Washington D.C. |
1088| `FLY_JNB` | Johannesburg |
1089| `FLY_LAX` | Los Angeles |
1090| `FLY_LHR` | London |
1091| `FLY_NRT` | Tokyo |
1092| `FLY_ORD` | Chicago |
1093| `FLY_SJC` | San Jose |
1094| `FLY_SIN` | Singapore |
1095| `FLY_SYD` | Sydney |
1096| `FLY_YYZ` | Toronto |
1097
1098### Koyeb Regions
1099
1100| Enum Value | Location |
1101| ----------- | ------------- |
1102| `KOYEB_FRA` | Frankfurt |
1103| `KOYEB_PAR` | Paris |
1104| `KOYEB_SFO` | San Francisco |
1105| `KOYEB_SIN` | Singapore |
1106| `KOYEB_TYO` | Tokyo |
1107| `KOYEB_WAS` | Washington |
1108
1109### Railway Regions
1110
1111| Enum Value | Location |
1112| ------------------------- | -------------- |
1113| `RAILWAY_US_WEST2` | US West |
1114| `RAILWAY_US_EAST4` | US East |
1115| `RAILWAY_EUROPE_WEST4` | Europe West |
1116| `RAILWAY_ASIA_SOUTHEAST1` | Asia Southeast |
1117
1118## Error Handling
1119
1120The SDK uses Connect RPC. Errors include a `code` and `message`:
1121
1122```typescript
1123import { ConnectError } from "@connectrpc/connect";
1124
1125try {
1126 await openstatus.monitor.v1.MonitorService.deleteMonitor(
1127 { id: "invalid" },
1128 { headers },
1129 );
1130} catch (error) {
1131 if (error instanceof ConnectError) {
1132 console.error(`Error ${error.code}: ${error.message}`);
1133 }
1134}
1135```
1136
1137## Related
1138
1139- [OpenStatus](https://openstatus.dev) - Open-source monitoring platform
1140- [Documentation](https://docs.openstatus.dev) - Full API documentation
1141- [Status Page](https://status.openstatus.dev) - OpenStatus service status
1142
1143## License
1144
1145MIT