Openstatus sdk www.openstatus.dev
at status-page 1057 lines 30 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## 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 and maintenance reports with update 18 timelines 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### Status Page Options 737 738| Option | Type | Required | Description | 739| ------------- | ------ | -------- | ---------------------------------------- | 740| `title` | string | Yes | Title of the status page (max 256 chars) | 741| `slug` | string | Yes | URL-friendly slug (lowercase, hyphens) | 742| `description` | string | No | Description (max 2048 chars) | 743| `homepageUrl` | string | No | Link to your homepage | 744| `contactUrl` | string | No | Link to your contact page | 745 746### Page Access Type 747 748| Enum Value | Description | 749| -------------------- | ----------------------- | 750| `UNSPECIFIED` | Default/unspecified | 751| `PUBLIC` | Publicly accessible | 752| `PASSWORD_PROTECTED` | Requires password | 753| `AUTHENTICATED` | Requires authentication | 754 755### Page Theme 756 757| Enum Value | Description | 758| ------------- | ------------------- | 759| `UNSPECIFIED` | Default/unspecified | 760| `SYSTEM` | Follow system theme | 761| `LIGHT` | Light theme | 762| `DARK` | Dark theme | 763 764### Overall Status 765 766| Enum Value | Description | 767| ---------------- | --------------------------- | 768| `UNSPECIFIED` | Default/unspecified | 769| `OPERATIONAL` | All systems operational | 770| `DEGRADED` | Performance is degraded | 771| `PARTIAL_OUTAGE` | Some systems are down | 772| `MAJOR_OUTAGE` | Major systems are down | 773| `MAINTENANCE` | Scheduled maintenance | 774| `UNKNOWN` | Status cannot be determined | 775 776### Page Component Type 777 778| Enum Value | Description | 779| ------------- | ------------------------- | 780| `UNSPECIFIED` | Default/unspecified | 781| `MONITOR` | Linked to a monitor | 782| `STATIC` | Static component (manual) | 783 784## Monitor Options 785 786### HTTP Monitor 787 788| Option | Type | Required | Description | 789| ---------------------- | ------------------- | -------- | --------------------------------------------------- | 790| `name` | string | Yes | Monitor name (max 256 chars) | 791| `url` | string | Yes | URL to monitor (max 2048 chars) | 792| `periodicity` | Periodicity | Yes | Check interval (see [Periodicity](#periodicity)) | 793| `method` | HTTPMethod | No | HTTP method (see [HTTP Methods](#http-methods)) | 794| `body` | string | No | Request body | 795| `headers` | Headers[] | No | Custom headers (`{ key: string, value: string }[]`) | 796| `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) | 797| `retry` | bigint | No | Retry attempts (default: 3, max: 10) | 798| `followRedirects` | boolean | No | Follow redirects (default: true) | 799| `regions` | Region[] | No | [Regions](#regions) for checks | 800| `active` | boolean | No | Enable monitoring (default: false) | 801| `public` | boolean | No | Public visibility (default: false) | 802| `degradedAt` | bigint | No | Latency threshold (ms) for degraded status | 803| `description` | string | No | Monitor description (max 1024 chars) | 804| `statusCodeAssertions` | array | No | [Status code assertions](#status-code-assertions) | 805| `bodyAssertions` | array | No | [Body assertions](#body-assertions) | 806| `headerAssertions` | array | No | [Header assertions](#header-assertions) | 807| `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration | 808 809### TCP Monitor 810 811| Option | Type | Required | Description | 812| --------------- | ------------------- | -------- | ------------------------------------------------ | 813| `name` | string | Yes | Monitor name (max 256 chars) | 814| `uri` | string | Yes | `host:port` to monitor (max 2048 chars) | 815| `periodicity` | Periodicity | Yes | Check interval (see [Periodicity](#periodicity)) | 816| `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) | 817| `retry` | bigint | No | Retry attempts (default: 3, max: 10) | 818| `regions` | Region[] | No | [Regions](#regions) for checks | 819| `active` | boolean | No | Enable monitoring (default: false) | 820| `public` | boolean | No | Public visibility (default: false) | 821| `degradedAt` | bigint | No | Latency threshold (ms) for degraded status | 822| `description` | string | No | Monitor description (max 1024 chars) | 823| `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration | 824 825### DNS Monitor 826 827| Option | Type | Required | Description | 828| ------------------ | ------------------- | -------- | ------------------------------------------------ | 829| `name` | string | Yes | Monitor name (max 256 chars) | 830| `uri` | string | Yes | Domain to resolve (max 2048 chars) | 831| `periodicity` | Periodicity | Yes | Check interval (see [Periodicity](#periodicity)) | 832| `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) | 833| `retry` | bigint | No | Retry attempts (default: 3, max: 10) | 834| `regions` | Region[] | No | [Regions](#regions) for checks | 835| `active` | boolean | No | Enable monitoring (default: false) | 836| `public` | boolean | No | Public visibility (default: false) | 837| `degradedAt` | bigint | No | Latency threshold (ms) for degraded status | 838| `description` | string | No | Monitor description (max 1024 chars) | 839| `recordAssertions` | array | No | [DNS record assertions](#dns-record-assertions) | 840| `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration | 841 842### Periodicity 843 844| Enum Value | Description | 845| ----------------- | ----------- | 846| `PERIODICITY_30S` | Every 30s | 847| `PERIODICITY_1M` | Every 1m | 848| `PERIODICITY_5M` | Every 5m | 849| `PERIODICITY_10M` | Every 10m | 850| `PERIODICITY_30M` | Every 30m | 851| `PERIODICITY_1H` | Every 1h | 852 853### HTTP Methods 854 855| Enum Value | Description | 856| --------------------- | ----------- | 857| `HTTP_METHOD_GET` | GET | 858| `HTTP_METHOD_POST` | POST | 859| `HTTP_METHOD_HEAD` | HEAD | 860| `HTTP_METHOD_PUT` | PUT | 861| `HTTP_METHOD_PATCH` | PATCH | 862| `HTTP_METHOD_DELETE` | DELETE | 863| `HTTP_METHOD_TRACE` | TRACE | 864| `HTTP_METHOD_CONNECT` | CONNECT | 865| `HTTP_METHOD_OPTIONS` | OPTIONS | 866 867## Assertions 868 869All assertion comparators are exported as enums from the SDK. 870 871### Status Code Assertions 872 873Validate HTTP response status codes using `NumberComparator`. 874 875```typescript 876import { NumberComparator } from "@openstatus/sdk-node"; 877 878{ 879 statusCodeAssertions: [ 880 { comparator: NumberComparator.EQUAL, target: BigInt(200) }, 881 { comparator: NumberComparator.LESS_THAN, target: BigInt(400) }, 882 ]; 883} 884``` 885 886**NumberComparator values:** 887 888| Enum Value | Description | 889| ----------------------- | --------------------- | 890| `EQUAL` | Equal to target | 891| `NOT_EQUAL` | Not equal to target | 892| `GREATER_THAN` | Greater than target | 893| `GREATER_THAN_OR_EQUAL` | Greater than or equal | 894| `LESS_THAN` | Less than target | 895| `LESS_THAN_OR_EQUAL` | Less than or equal | 896 897### Body Assertions 898 899Validate response body content using `StringComparator`. 900 901```typescript 902import { StringComparator } from "@openstatus/sdk-node"; 903 904{ 905 bodyAssertions: [ 906 { comparator: StringComparator.CONTAINS, target: '"status":"ok"' }, 907 { comparator: StringComparator.NOT_EMPTY, target: "" }, 908 ]; 909} 910``` 911 912**StringComparator values:** 913 914| Enum Value | Description | 915| ----------------------- | --------------------------- | 916| `CONTAINS` | Contains target string | 917| `NOT_CONTAINS` | Does not contain target | 918| `EQUAL` | Equal to target | 919| `NOT_EQUAL` | Not equal to target | 920| `EMPTY` | Body is empty | 921| `NOT_EMPTY` | Body is not empty | 922| `GREATER_THAN` | Lexicographically greater | 923| `GREATER_THAN_OR_EQUAL` | Lexicographically >= target | 924| `LESS_THAN` | Lexicographically less | 925| `LESS_THAN_OR_EQUAL` | Lexicographically <= target | 926 927### Header Assertions 928 929Validate response headers using `StringComparator`. 930 931```typescript 932import { StringComparator } from "@openstatus/sdk-node"; 933 934{ 935 headerAssertions: [ 936 { 937 key: "content-type", 938 comparator: StringComparator.CONTAINS, 939 target: "application/json", 940 }, 941 ]; 942} 943``` 944 945### DNS Record Assertions 946 947Validate DNS records using `RecordComparator`. 948 949```typescript 950import { RecordComparator } from "@openstatus/sdk-node"; 951 952{ 953 recordAssertions: [ 954 { 955 record: "A", 956 comparator: RecordComparator.EQUAL, 957 target: "93.184.216.34", 958 }, 959 { record: "CNAME", comparator: RecordComparator.CONTAINS, target: "cdn" }, 960 ]; 961} 962``` 963 964**RecordComparator values:** 965 966| Enum Value | Description | 967| -------------- | ----------------------- | 968| `EQUAL` | Equal to target | 969| `NOT_EQUAL` | Not equal to target | 970| `CONTAINS` | Contains target string | 971| `NOT_CONTAINS` | Does not contain target | 972 973**Supported record types:** `A`, `AAAA`, `CNAME`, `MX`, `TXT` 974 975## Regions 976 977Monitor from 28 global locations across multiple providers. Use the `Region` 978enum: 979 980```typescript 981import { Region } from "@openstatus/sdk-node"; 982 983// Example: Use specific regions 984regions: [Region.FLY_AMS, Region.FLY_IAD, Region.KOYEB_FRA]; 985``` 986 987### Fly.io Regions 988 989| Enum Value | Location | 990| ---------- | --------------- | 991| `FLY_AMS` | Amsterdam | 992| `FLY_ARN` | Stockholm | 993| `FLY_BOM` | Mumbai | 994| `FLY_CDG` | Paris | 995| `FLY_DFW` | Dallas | 996| `FLY_EWR` | Newark | 997| `FLY_FRA` | Frankfurt | 998| `FLY_GRU` | São Paulo | 999| `FLY_IAD` | Washington D.C. | 1000| `FLY_JNB` | Johannesburg | 1001| `FLY_LAX` | Los Angeles | 1002| `FLY_LHR` | London | 1003| `FLY_NRT` | Tokyo | 1004| `FLY_ORD` | Chicago | 1005| `FLY_SJC` | San Jose | 1006| `FLY_SIN` | Singapore | 1007| `FLY_SYD` | Sydney | 1008| `FLY_YYZ` | Toronto | 1009 1010### Koyeb Regions 1011 1012| Enum Value | Location | 1013| ----------- | ------------- | 1014| `KOYEB_FRA` | Frankfurt | 1015| `KOYEB_PAR` | Paris | 1016| `KOYEB_SFO` | San Francisco | 1017| `KOYEB_SIN` | Singapore | 1018| `KOYEB_TYO` | Tokyo | 1019| `KOYEB_WAS` | Washington | 1020 1021### Railway Regions 1022 1023| Enum Value | Location | 1024| ------------------------- | -------------- | 1025| `RAILWAY_US_WEST2` | US West | 1026| `RAILWAY_US_EAST4` | US East | 1027| `RAILWAY_EUROPE_WEST4` | Europe West | 1028| `RAILWAY_ASIA_SOUTHEAST1` | Asia Southeast | 1029 1030## Error Handling 1031 1032The SDK uses Connect RPC. Errors include a `code` and `message`: 1033 1034```typescript 1035import { ConnectError } from "@connectrpc/connect"; 1036 1037try { 1038 await openstatus.monitor.v1.MonitorService.deleteMonitor( 1039 { id: "invalid" }, 1040 { headers }, 1041 ); 1042} catch (error) { 1043 if (error instanceof ConnectError) { 1044 console.error(`Error ${error.code}: ${error.message}`); 1045 } 1046} 1047``` 1048 1049## Related 1050 1051- [OpenStatus](https://openstatus.dev) - Open-source monitoring platform 1052- [Documentation](https://docs.openstatus.dev) - Full API documentation 1053- [Status Page](https://status.openstatus.dev) - OpenStatus service status 1054 1055## License 1056 1057MIT