Openstatus sdk www.openstatus.dev
at main 583 lines 19 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 8monitoring platform. 9 10## Features 11 12- **HTTP Monitoring** - Monitor websites and APIs with customizable assertions 13- **TCP Monitoring** - Check database connections and other TCP services 14- **DNS Monitoring** - Verify DNS records and resolution 15- **Global Regions** - Monitor from 28 locations worldwide 16- **Type-safe** - Full TypeScript support with generated types from protobuf 17 18## Installation 19 20### JSR 21 22```bash 23npx jsr add @openstatus/sdk-node 24``` 25 26### npm 27 28```bash 29npm install @openstatus/sdk-node 30``` 31 32### Deno 33 34```typescript 35import { openstatus } from "jsr:@openstatus/sdk-node"; 36``` 37 38## Quick Start 39 40```typescript 41import { 42 openstatus, 43 Periodicity, 44 Region, 45 HTTPMethod, 46 NumberComparator, 47} from "@openstatus/sdk-node"; 48 49const headers = { 50 "x-openstatus-key": `${process.env.OPENSTATUS_API_KEY}`, 51}; 52 53// Create a monitor 54const { monitor } = await openstatus.monitor.v1.MonitorService.createHTTPMonitor( 55 { 56 monitor: { 57 name: "My API", 58 url: "https://api.example.com/health", 59 periodicity: Periodicity.PERIODICITY_1M, 60 method: HTTPMethod.HTTP_METHOD_GET, 61 regions: [Region.FLY_AMS, Region.FLY_IAD, Region.FLY_SYD], 62 active: true, 63 statusCodeAssertions: [ 64 { comparator: NumberComparator.EQUAL, target: BigInt(200) }, 65 ], 66 }, 67 }, 68 { headers }, 69); 70 71console.log(`Monitor created: ${monitor?.id}`); 72 73// List all monitors 74const { httpMonitors, tcpMonitors, dnsMonitors, totalSize } = 75 await openstatus.monitor.v1.MonitorService.listMonitors({}, { headers }); 76 77console.log(`Found ${totalSize} monitors`); 78``` 79 80## Authentication 81 82All API requests require an API key. Get yours from the 83[OpenStatus dashboard](https://www.openstatus.dev/app). 84 85```typescript 86const headers = { 87 "x-openstatus-key": `${process.env.OPENSTATUS_API_KEY}`, 88}; 89 90// Pass headers to any service method 91await openstatus.monitor.v1.MonitorService.listMonitors({}, { headers }); 92``` 93 94## Environment Variables 95 96| Variable | Description | Default | 97| -------------------- | ----------------------- | -------------------------------- | 98| `OPENSTATUS_API_KEY` | Your OpenStatus API key | - | 99| `OPENSTATUS_API_URL` | Custom API endpoint | `https://api.openstatus.dev/rpc` | 100 101## API Reference 102 103### Monitor Service 104 105#### `createHTTPMonitor(request, options)` 106 107Create an HTTP/HTTPS monitor. 108 109```typescript 110import { Periodicity, Region, HTTPMethod } from "@openstatus/sdk-node"; 111 112const { monitor } = await openstatus.monitor.v1.MonitorService.createHTTPMonitor( 113 { 114 monitor: { 115 name: "My Website", 116 url: "https://example.com", 117 periodicity: Periodicity.PERIODICITY_1M, 118 method: HTTPMethod.HTTP_METHOD_GET, 119 regions: [Region.FLY_AMS, Region.FLY_IAD, Region.FLY_SYD], 120 active: true, 121 }, 122 }, 123 { headers }, 124); 125``` 126 127#### `updateHTTPMonitor(request, options)` 128 129Update an existing HTTP monitor. 130 131```typescript 132const { monitor } = await openstatus.monitor.v1.MonitorService.updateHTTPMonitor( 133 { 134 id: "mon_123", 135 monitor: { 136 name: "Updated Name", 137 active: false, 138 }, 139 }, 140 { headers }, 141); 142``` 143 144#### `createTCPMonitor(request, options)` 145 146Create a TCP connection monitor. 147 148```typescript 149const { monitor } = await openstatus.monitor.v1.MonitorService.createTCPMonitor( 150 { 151 monitor: { 152 name: "Database", 153 uri: "db.example.com:5432", 154 periodicity: Periodicity.PERIODICITY_5M, 155 regions: [Region.FLY_AMS, Region.FLY_IAD], 156 active: true, 157 }, 158 }, 159 { headers }, 160); 161``` 162 163#### `updateTCPMonitor(request, options)` 164 165Update an existing TCP monitor. 166 167```typescript 168const { monitor } = await openstatus.monitor.v1.MonitorService.updateTCPMonitor( 169 { 170 id: "mon_123", 171 monitor: { 172 name: "Updated Database Monitor", 173 }, 174 }, 175 { headers }, 176); 177``` 178 179#### `createDNSMonitor(request, options)` 180 181Create a DNS resolution monitor. 182 183```typescript 184import { RecordComparator } from "@openstatus/sdk-node"; 185 186const { monitor } = await openstatus.monitor.v1.MonitorService.createDNSMonitor( 187 { 188 monitor: { 189 name: "DNS Check", 190 uri: "example.com", 191 periodicity: Periodicity.PERIODICITY_10M, 192 regions: [Region.FLY_AMS], 193 active: true, 194 recordAssertions: [ 195 { 196 record: "A", 197 comparator: RecordComparator.EQUAL, 198 target: "93.184.216.34", 199 }, 200 ], 201 }, 202 }, 203 { headers }, 204); 205``` 206 207#### `updateDNSMonitor(request, options)` 208 209Update an existing DNS monitor. 210 211```typescript 212const { monitor } = await openstatus.monitor.v1.MonitorService.updateDNSMonitor( 213 { 214 id: "mon_123", 215 monitor: { 216 name: "Updated DNS Check", 217 }, 218 }, 219 { headers }, 220); 221``` 222 223#### `listMonitors(request, options)` 224 225List all monitors with pagination. Returns monitors grouped by type. 226 227```typescript 228const { httpMonitors, tcpMonitors, dnsMonitors, nextPageToken, totalSize } = 229 await openstatus.monitor.v1.MonitorService.listMonitors( 230 { pageSize: 10, pageToken: "" }, 231 { headers }, 232 ); 233``` 234 235#### `triggerMonitor(request, options)` 236 237Trigger an immediate check. 238 239```typescript 240const { success } = await openstatus.monitor.v1.MonitorService.triggerMonitor( 241 { id: "mon_123" }, 242 { headers }, 243); 244``` 245 246#### `deleteMonitor(request, options)` 247 248Delete a monitor. 249 250```typescript 251const { success } = await openstatus.monitor.v1.MonitorService.deleteMonitor( 252 { id: "mon_123" }, 253 { headers }, 254); 255``` 256 257#### `getMonitorStatus(request, options)` 258 259Get the current status of a monitor across all configured regions. 260 261```typescript 262import { MonitorStatus, Region } from "@openstatus/sdk-node"; 263 264const { id, regions } = await openstatus.monitor.v1.MonitorService.getMonitorStatus( 265 { id: "mon_123" }, 266 { headers }, 267); 268 269// regions is an array of { region, status } 270// region: Region enum value (e.g., Region.FLY_AMS) 271// status: MonitorStatus.ACTIVE, MonitorStatus.DEGRADED, or MonitorStatus.ERROR 272for (const { region, status } of regions) { 273 console.log(`${Region[region]}: ${MonitorStatus[status]}`); 274} 275``` 276 277#### `getMonitorSummary(request, options)` 278 279Get aggregated metrics and latency percentiles for a monitor. 280 281```typescript 282import { TimeRange } from "@openstatus/sdk-node"; 283 284const summary = await openstatus.monitor.v1.MonitorService.getMonitorSummary( 285 { 286 id: "mon_123", 287 timeRange: TimeRange.TIME_RANGE_7D, // TIME_RANGE_1D, TIME_RANGE_7D, or TIME_RANGE_14D 288 regions: [], // optional: filter by specific regions 289 }, 290 { headers }, 291); 292 293console.log(`Last ping: ${summary.lastPingAt}`); 294console.log(`Success: ${summary.totalSuccessful}`); 295console.log(`Degraded: ${summary.totalDegraded}`); 296console.log(`Failed: ${summary.totalFailed}`); 297console.log(`P50 latency: ${summary.p50}ms`); 298console.log(`P75 latency: ${summary.p75}ms`); 299console.log(`P90 latency: ${summary.p90}ms`); 300console.log(`P95 latency: ${summary.p95}ms`); 301console.log(`P99 latency: ${summary.p99}ms`); 302``` 303 304### Health Service 305 306Check API health status (no authentication required). 307 308```typescript 309import { ServingStatus } from "@openstatus/sdk-node"; 310 311const { status } = await openstatus.health.v1.HealthService.check({}); 312console.log(ServingStatus[status]); // "SERVING" 313``` 314 315## Monitor Options 316 317### HTTP Monitor 318 319| Option | Type | Required | Description | 320| ---------------------- | ------------------ | -------- | -------------------------------------------------------- | 321| `name` | string | Yes | Monitor name (max 256 chars) | 322| `url` | string | Yes | URL to monitor (max 2048 chars) | 323| `periodicity` | Periodicity | Yes | Check interval (see [Periodicity](#periodicity)) | 324| `method` | HTTPMethod | No | HTTP method (see [HTTP Methods](#http-methods)) | 325| `body` | string | No | Request body | 326| `headers` | Headers[] | No | Custom headers (`{ key: string, value: string }[]`) | 327| `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) | 328| `retry` | bigint | No | Retry attempts (default: 3, max: 10) | 329| `followRedirects` | boolean | No | Follow redirects (default: true) | 330| `regions` | Region[] | No | [Regions](#regions) for checks | 331| `active` | boolean | No | Enable monitoring (default: false) | 332| `public` | boolean | No | Public visibility (default: false) | 333| `degradedAt` | bigint | No | Latency threshold (ms) for degraded status | 334| `description` | string | No | Monitor description (max 1024 chars) | 335| `statusCodeAssertions` | array | No | [Status code assertions](#status-code-assertions) | 336| `bodyAssertions` | array | No | [Body assertions](#body-assertions) | 337| `headerAssertions` | array | No | [Header assertions](#header-assertions) | 338| `openTelemetry` | OpenTelemetryConfig| No | OpenTelemetry export configuration | 339 340### TCP Monitor 341 342| Option | Type | Required | Description | 343| --------------- | ------------------ | -------- | ------------------------------------------------ | 344| `name` | string | Yes | Monitor name (max 256 chars) | 345| `uri` | string | Yes | `host:port` to monitor (max 2048 chars) | 346| `periodicity` | Periodicity | Yes | Check interval (see [Periodicity](#periodicity)) | 347| `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) | 348| `retry` | bigint | No | Retry attempts (default: 3, max: 10) | 349| `regions` | Region[] | No | [Regions](#regions) for checks | 350| `active` | boolean | No | Enable monitoring (default: false) | 351| `public` | boolean | No | Public visibility (default: false) | 352| `degradedAt` | bigint | No | Latency threshold (ms) for degraded status | 353| `description` | string | No | Monitor description (max 1024 chars) | 354| `openTelemetry` | OpenTelemetryConfig| No | OpenTelemetry export configuration | 355 356### DNS Monitor 357 358| Option | Type | Required | Description | 359| ------------------ | ------------------ | -------- | -------------------------------------------------- | 360| `name` | string | Yes | Monitor name (max 256 chars) | 361| `uri` | string | Yes | Domain to resolve (max 2048 chars) | 362| `periodicity` | Periodicity | Yes | Check interval (see [Periodicity](#periodicity)) | 363| `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) | 364| `retry` | bigint | No | Retry attempts (default: 3, max: 10) | 365| `regions` | Region[] | No | [Regions](#regions) for checks | 366| `active` | boolean | No | Enable monitoring (default: false) | 367| `public` | boolean | No | Public visibility (default: false) | 368| `degradedAt` | bigint | No | Latency threshold (ms) for degraded status | 369| `description` | string | No | Monitor description (max 1024 chars) | 370| `recordAssertions` | array | No | [DNS record assertions](#dns-record-assertions) | 371| `openTelemetry` | OpenTelemetryConfig| No | OpenTelemetry export configuration | 372 373### Periodicity 374 375| Enum Value | Description | 376| ----------------------- | ------------ | 377| `PERIODICITY_30S` | Every 30s | 378| `PERIODICITY_1M` | Every 1m | 379| `PERIODICITY_5M` | Every 5m | 380| `PERIODICITY_10M` | Every 10m | 381| `PERIODICITY_30M` | Every 30m | 382| `PERIODICITY_1H` | Every 1h | 383 384### HTTP Methods 385 386| Enum Value | Description | 387| ------------------------- | ----------- | 388| `HTTP_METHOD_GET` | GET | 389| `HTTP_METHOD_POST` | POST | 390| `HTTP_METHOD_HEAD` | HEAD | 391| `HTTP_METHOD_PUT` | PUT | 392| `HTTP_METHOD_PATCH` | PATCH | 393| `HTTP_METHOD_DELETE` | DELETE | 394| `HTTP_METHOD_TRACE` | TRACE | 395| `HTTP_METHOD_CONNECT` | CONNECT | 396| `HTTP_METHOD_OPTIONS` | OPTIONS | 397 398## Assertions 399 400All assertion comparators are exported as enums from the SDK. 401 402### Status Code Assertions 403 404Validate HTTP response status codes using `NumberComparator`. 405 406```typescript 407import { NumberComparator } from "@openstatus/sdk-node"; 408 409{ 410 statusCodeAssertions: [ 411 { comparator: NumberComparator.EQUAL, target: BigInt(200) }, 412 { comparator: NumberComparator.LESS_THAN, target: BigInt(400) }, 413 ]; 414} 415``` 416 417**NumberComparator values:** 418 419| Enum Value | Description | 420| ----------------------- | ------------------------ | 421| `EQUAL` | Equal to target | 422| `NOT_EQUAL` | Not equal to target | 423| `GREATER_THAN` | Greater than target | 424| `GREATER_THAN_OR_EQUAL` | Greater than or equal | 425| `LESS_THAN` | Less than target | 426| `LESS_THAN_OR_EQUAL` | Less than or equal | 427 428### Body Assertions 429 430Validate response body content using `StringComparator`. 431 432```typescript 433import { StringComparator } from "@openstatus/sdk-node"; 434 435{ 436 bodyAssertions: [ 437 { comparator: StringComparator.CONTAINS, target: '"status":"ok"' }, 438 { comparator: StringComparator.NOT_EMPTY, target: "" }, 439 ]; 440} 441``` 442 443**StringComparator values:** 444 445| Enum Value | Description | 446| ----------------------- | ---------------------------- | 447| `CONTAINS` | Contains target string | 448| `NOT_CONTAINS` | Does not contain target | 449| `EQUAL` | Equal to target | 450| `NOT_EQUAL` | Not equal to target | 451| `EMPTY` | Body is empty | 452| `NOT_EMPTY` | Body is not empty | 453| `GREATER_THAN` | Lexicographically greater | 454| `GREATER_THAN_OR_EQUAL` | Lexicographically >= target | 455| `LESS_THAN` | Lexicographically less | 456| `LESS_THAN_OR_EQUAL` | Lexicographically <= target | 457 458### Header Assertions 459 460Validate response headers using `StringComparator`. 461 462```typescript 463import { StringComparator } from "@openstatus/sdk-node"; 464 465{ 466 headerAssertions: [ 467 { 468 key: "content-type", 469 comparator: StringComparator.CONTAINS, 470 target: "application/json", 471 }, 472 ]; 473} 474``` 475 476### DNS Record Assertions 477 478Validate DNS records using `RecordComparator`. 479 480```typescript 481import { RecordComparator } from "@openstatus/sdk-node"; 482 483{ 484 recordAssertions: [ 485 { record: "A", comparator: RecordComparator.EQUAL, target: "93.184.216.34" }, 486 { record: "CNAME", comparator: RecordComparator.CONTAINS, target: "cdn" }, 487 ]; 488} 489``` 490 491**RecordComparator values:** 492 493| Enum Value | Description | 494| -------------- | ----------------------- | 495| `EQUAL` | Equal to target | 496| `NOT_EQUAL` | Not equal to target | 497| `CONTAINS` | Contains target string | 498| `NOT_CONTAINS` | Does not contain target | 499 500**Supported record types:** `A`, `AAAA`, `CNAME`, `MX`, `TXT` 501 502## Regions 503 504Monitor from 28 global locations across multiple providers. Use the `Region` enum: 505 506```typescript 507import { Region } from "@openstatus/sdk-node"; 508 509// Example: Use specific regions 510regions: [Region.FLY_AMS, Region.FLY_IAD, Region.KOYEB_FRA]; 511``` 512 513### Fly.io Regions 514 515| Enum Value | Location | 516| ---------- | --------------- | 517| `FLY_AMS` | Amsterdam | 518| `FLY_ARN` | Stockholm | 519| `FLY_BOM` | Mumbai | 520| `FLY_CDG` | Paris | 521| `FLY_DFW` | Dallas | 522| `FLY_EWR` | Newark | 523| `FLY_FRA` | Frankfurt | 524| `FLY_GRU` | São Paulo | 525| `FLY_IAD` | Washington D.C. | 526| `FLY_JNB` | Johannesburg | 527| `FLY_LAX` | Los Angeles | 528| `FLY_LHR` | London | 529| `FLY_NRT` | Tokyo | 530| `FLY_ORD` | Chicago | 531| `FLY_SJC` | San Jose | 532| `FLY_SIN` | Singapore | 533| `FLY_SYD` | Sydney | 534| `FLY_YYZ` | Toronto | 535 536### Koyeb Regions 537 538| Enum Value | Location | 539| ----------- | ------------- | 540| `KOYEB_FRA` | Frankfurt | 541| `KOYEB_PAR` | Paris | 542| `KOYEB_SFO` | San Francisco | 543| `KOYEB_SIN` | Singapore | 544| `KOYEB_TYO` | Tokyo | 545| `KOYEB_WAS` | Washington | 546 547### Railway Regions 548 549| Enum Value | Location | 550| ------------------------ | -------------- | 551| `RAILWAY_US_WEST2` | US West | 552| `RAILWAY_US_EAST4` | US East | 553| `RAILWAY_EUROPE_WEST4` | Europe West | 554| `RAILWAY_ASIA_SOUTHEAST1`| Asia Southeast | 555 556## Error Handling 557 558The SDK uses Connect RPC. Errors include a `code` and `message`: 559 560```typescript 561import { ConnectError } from "@connectrpc/connect"; 562 563try { 564 await openstatus.monitor.v1.MonitorService.deleteMonitor( 565 { id: "invalid" }, 566 { headers }, 567 ); 568} catch (error) { 569 if (error instanceof ConnectError) { 570 console.error(`Error ${error.code}: ${error.message}`); 571 } 572} 573``` 574 575## Related 576 577- [OpenStatus](https://openstatus.dev) - Open-source monitoring platform 578- [Documentation](https://docs.openstatus.dev) - Full API documentation 579- [Status Page](https://status.openstatus.dev) - OpenStatus service status 580 581## License 582 583MIT