Openstatus sdk www.openstatus.dev
at getMonitor 1497 lines 38 kB view raw view rendered
1# OpenStatus Node.js SDK (Beta) 2 3[![JSR](https://jsr.io/badges/@openstatus/sdk-node)](https://jsr.io/@openstatus/sdk-node) 4[![npm](https://img.shields.io/npm/v/@openstatus/sdk-node)](https://www.npmjs.com/package/@openstatus/sdk-node) 5[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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