Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/openstatus. ๐ซ Status page with uptime monitoring & API monitoring as code ๐ซ openstatus.dev
bun drizzle-orm monitoring monitoring-as-code nextjs observability on-call open-source shadcn-ui status-page statuspage synthetic-monitoring tinybird turso uptime uptime-checker uptime-monitor
Something went wrong. Try again.
MDX
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429---category: SDKtitle: Monitor Servicedescription: "Create and manage HTTP, TCP, and DNS monitors with the openstatus Node.js SDK"---
Manage HTTP, TCP, and DNS monitors. The Monitor Service provides 14 RPC methods for creating, updating, listing, triggering, deleting, querying monitor status and metrics, and inspecting HTTP response logs.
All examples assume you have created a client:
```typescriptimport { createOpenStatusClient } from "@openstatus/sdk-node";
const client = createOpenStatusClient({ apiKey: process.env.OPENSTATUS_API_KEY,});```
## HTTP Monitors
### Create HTTP Monitor
```typescriptimport { createOpenStatusClient, HTTPMethod, NumberComparator, Periodicity, Region, StringComparator,} from "@openstatus/sdk-node";
const client = createOpenStatusClient({ apiKey: process.env.OPENSTATUS_API_KEY,});
const { monitor } = await client.monitor.v1.MonitorService.createHTTPMonitor({ monitor: { name: "My API", url: "https://api.example.com/health", periodicity: Periodicity.PERIODICITY_1M, method: HTTPMethod.HTTP_METHOD_GET, regions: [Region.FLY_AMS, Region.FLY_IAD, Region.FLY_SYD], active: true, timeout: BigInt(30000), retry: BigInt(3), followRedirects: true, degradedAt: BigInt(5000), headers: [ { key: "Authorization", value: "Bearer my-token" }, ], statusCodeAssertions: [ { comparator: NumberComparator.EQUAL, target: BigInt(200) }, ], bodyAssertions: [ { comparator: StringComparator.CONTAINS, target: '"status":"ok"' }, ], headerAssertions: [ { key: "content-type", comparator: StringComparator.CONTAINS, target: "application/json", }, ], description: "Health check for the production API", public: false, openTelemetry: { endpoint: "https://otel.example.com/v1/traces", headers: [{ key: "Authorization", value: "Bearer otel-token" }], }, },});
console.log(`Created monitor: ${monitor?.id}`);```
### Update HTTP Monitor
Updates are partial โ only include the fields you want to change.
```typescriptconst { monitor } = await client.monitor.v1.MonitorService.updateHTTPMonitor({ id: "123456", monitor: { name: "Updated API Monitor", active: false, },});```
### HTTP Monitor Options
| Option | Type | Required | Description ||--------|------|----------|-------------|| `name` | string | Yes | Monitor name (max 256 chars) || `url` | string | Yes | URL to monitor (max 2048 chars) || `periodicity` | Periodicity | Yes | Check interval || `method` | HTTPMethod | No | HTTP method (default: GET) || `body` | string | No | Request body || `headers` | Headers[] | No | Custom headers `{ key, value }[]` || `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) || `retry` | bigint | No | Retry attempts (default: 3, max: 10) || `followRedirects` | boolean | No | Follow redirects (default: true) || `regions` | Region[] | No | Regions for checks || `active` | boolean | No | Enable monitoring (default: false) || `public` | boolean | No | Public visibility (default: false) || `degradedAt` | bigint | No | Latency threshold (ms) for degraded status || `description` | string | No | Monitor description (max 1024 chars) || `statusCodeAssertions` | StatusCodeAssertion[] | No | Status code assertions || `bodyAssertions` | BodyAssertion[] | No | Body assertions || `headerAssertions` | HeaderAssertion[] | No | Header assertions || `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration |
## TCP Monitors
### Create TCP Monitor
```typescriptimport { createOpenStatusClient, Periodicity, Region,} from "@openstatus/sdk-node";
const client = createOpenStatusClient({ apiKey: process.env.OPENSTATUS_API_KEY,});
const { monitor } = await client.monitor.v1.MonitorService.createTCPMonitor({ monitor: { name: "Database", uri: "db.example.com:5432", periodicity: Periodicity.PERIODICITY_5M, regions: [Region.FLY_AMS, Region.FLY_IAD], active: true, },});```
### Update TCP Monitor
```typescriptconst { monitor } = await client.monitor.v1.MonitorService.updateTCPMonitor({ id: "123456", monitor: { name: "Updated Database Monitor", },});```
### TCP Monitor Options
| Option | Type | Required | Description ||--------|------|----------|-------------|| `name` | string | Yes | Monitor name (max 256 chars) || `uri` | string | Yes | `host:port` to monitor (max 2048 chars) || `periodicity` | Periodicity | Yes | Check interval || `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) || `retry` | bigint | No | Retry attempts (default: 3, max: 10) || `regions` | Region[] | No | Regions for checks || `active` | boolean | No | Enable monitoring (default: false) || `public` | boolean | No | Public visibility (default: false) || `degradedAt` | bigint | No | Latency threshold (ms) for degraded status || `description` | string | No | Monitor description (max 1024 chars) || `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration |
## DNS Monitors
### Create DNS Monitor
```typescriptimport { createOpenStatusClient, Periodicity, RecordComparator, Region,} from "@openstatus/sdk-node";
const client = createOpenStatusClient({ apiKey: process.env.OPENSTATUS_API_KEY,});
const { monitor } = await client.monitor.v1.MonitorService.createDNSMonitor({ monitor: { name: "DNS Check", uri: "example.com", periodicity: Periodicity.PERIODICITY_10M, regions: [Region.FLY_AMS], active: true, recordAssertions: [ { record: "A", comparator: RecordComparator.EQUAL, target: "93.184.216.34", }, { record: "CNAME", comparator: RecordComparator.CONTAINS, target: "cdn", }, ], },});```
### Update DNS Monitor
```typescriptconst { monitor } = await client.monitor.v1.MonitorService.updateDNSMonitor({ id: "123456", monitor: { name: "Updated DNS Check", },});```
### DNS Monitor Options
| Option | Type | Required | Description ||--------|------|----------|-------------|| `name` | string | Yes | Monitor name (max 256 chars) || `uri` | string | Yes | Domain to resolve (max 2048 chars) || `periodicity` | Periodicity | Yes | Check interval || `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) || `retry` | bigint | No | Retry attempts (default: 3, max: 10) || `regions` | Region[] | No | Regions for checks || `active` | boolean | No | Enable monitoring (default: false) || `public` | boolean | No | Public visibility (default: false) || `degradedAt` | bigint | No | Latency threshold (ms) for degraded status || `description` | string | No | Monitor description (max 1024 chars) || `recordAssertions` | RecordAssertion[] | No | DNS record assertions || `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration |
## List Monitors
List all monitors with offset-based pagination. Returns monitors grouped by type.
<Aside>The response also carries `icmpMonitors` and `grpcMonitors`, and `totalSize` counts every type.The SDK does not yet ship create/update methods for those two โ call the[ConnectRPC API](https://api.openstatus.dev/openapi) directly if you need them.</Aside>
```typescriptconst { httpMonitors, tcpMonitors, dnsMonitors, totalSize } = await client.monitor.v1.MonitorService.listMonitors({ limit: 10, offset: 0, });
console.log(`Total: ${totalSize}`);console.log(`HTTP: ${httpMonitors.length}`);console.log(`TCP: ${tcpMonitors.length}`);console.log(`DNS: ${dnsMonitors.length}`);```
Pagination parameters:
| Parameter | Type | Description ||-----------|------|-------------|| `limit` | number (optional) | Max results to return (1โ100, default 50) || `offset` | number (optional) | Number of results to skip (default 0) |
## Get Monitor
Get a single monitor by ID. The response uses a `MonitorConfig` oneof type that contains one of the HTTP, TCP, DNS, ICMP, or gRPC configurations.
```typescriptconst { monitor } = await client.monitor.v1.MonitorService.getMonitor({ id: "123456",});
if (monitor?.config.case === "http") { console.log(`HTTP Monitor: ${monitor.config.value.name} โ ${monitor.config.value.url}`);} else if (monitor?.config.case === "tcp") { console.log(`TCP Monitor: ${monitor.config.value.name} โ ${monitor.config.value.uri}`);} else if (monitor?.config.case === "dns") { console.log(`DNS Monitor: ${monitor.config.value.name} โ ${monitor.config.value.uri}`);}```
## Trigger Monitor
Trigger an immediate check for a monitor.
```typescriptconst { success } = await client.monitor.v1.MonitorService.triggerMonitor({ id: "123456",});
console.log(`Trigger successful: ${success}`);```
## Delete Monitor
```typescriptconst { success } = await client.monitor.v1.MonitorService.deleteMonitor({ id: "123456",});```
## Get Monitor Status
Get the current status of a monitor across all configured regions.
```typescriptimport { createOpenStatusClient, MonitorStatus, Region,} from "@openstatus/sdk-node";
const client = createOpenStatusClient({ apiKey: process.env.OPENSTATUS_API_KEY,});
const { id, regions } = await client.monitor.v1.MonitorService.getMonitorStatus( { id: "123456" },);
for (const { region, status } of regions) { console.log(`${Region[region]}: ${MonitorStatus[status]}`);}```
## Get Monitor Summary
Get aggregated metrics and latency percentiles for a monitor over a time range.
```typescriptimport { createOpenStatusClient, TimeRange } from "@openstatus/sdk-node";
const client = createOpenStatusClient({ apiKey: process.env.OPENSTATUS_API_KEY,});
const summary = await client.monitor.v1.MonitorService.getMonitorSummary({ id: "123456", timeRange: TimeRange.TIME_RANGE_7D, regions: [],});
console.log(`Last ping: ${summary.lastPingAt}`);console.log(`Successful: ${summary.totalSuccessful}`);console.log(`Degraded: ${summary.totalDegraded}`);console.log(`Failed: ${summary.totalFailed}`);console.log(`P50: ${summary.p50}ms`);console.log(`P75: ${summary.p75}ms`);console.log(`P90: ${summary.p90}ms`);console.log(`P95: ${summary.p95}ms`);console.log(`P99: ${summary.p99}ms`);```
The latency fields (`p50`, `p75`, `p90`, `p95`, `p99`) and count fields (`totalSuccessful`, `totalDegraded`, `totalFailed`) are `bigint` values. The `regions` parameter is optional โ pass an empty array to get metrics across all regions.
`getMonitorSummary` returns a single aggregate over the window and `TimeRange` caps at 14 days. For a per-day series to render status bars, use `getPageComponentDailySummary` on the [Status Page Service](/docs/sdk/nodejs/status-page-service) โ it returns per-component daily buckets merged with the incident and maintenance timeline (max 45 days), the single source of truth for the `status-bar` / `status-calendar` registry components. The REST endpoint `GET /v1/monitor/{id}/summary` also exposes a single-monitor daily series (`{ ok, count, day }`).
## List Monitor HTTP Response Logs
List HTTP response logs for a monitor within the 14-day retention window. Supports time-window filtering and offset-based pagination.
<Aside type="caution">Response logs are a paid feature. On the free plan these methods return `permission_denied` ("Upgrade for response logs").</Aside>
```typescriptimport { createOpenStatusClient, HTTPResponseLogRequestStatus, HTTPResponseLogTrigger, Region,} from "@openstatus/sdk-node";
const client = createOpenStatusClient({ apiKey: process.env.OPENSTATUS_API_KEY,});
const { logs, pagination } = await client.monitor.v1.MonitorService .listMonitorHTTPResponseLogs({ id: "123456", fromTimestamp: BigInt(Date.now() - 24 * 60 * 60 * 1000), toTimestamp: BigInt(Date.now()), limit: 25, offset: 0, });
for (const log of logs) { console.log( `[${Region[log.region]}] ${log.timestamp}: ` + `${log.statusCode ?? "n/a"} (${log.latency}ms) ` + `status=${HTTPResponseLogRequestStatus[log.requestStatus]} ` + `trigger=${HTTPResponseLogTrigger[log.trigger]}`, );}
if (pagination?.hasMore) { console.log(`Next offset: ${pagination.nextOffset}`);}```
Request parameters:
| Parameter | Type | Description || --------------- | ----------------- | ----------------------------------------------- || `id` | string | Monitor ID (required) || `fromTimestamp` | bigint (optional) | Window start, Unix milliseconds (14d retention) || `toTimestamp` | bigint (optional) | Window end, Unix milliseconds || `limit` | number (optional) | Max results to return (1โ100, default 25) || `offset` | number (optional) | Number of results to skip (default 0) |
Each `HTTPResponseLogListItem` includes `id`, `latency`, `statusCode`, `monitorId`, `requestStatus`, `region`, `cronTimestamp`, `trigger`, `timestamp`, and an optional `timing` breakdown (`dns`, `connect`, `tls`, `ttfb`, `transfer`).
## Get Monitor HTTP Response Log
Get full debugging details for a single response log: the requested URL, redacted response headers, error message, and serialized assertions. Same plan gating as above.
```typescriptconst { log } = await client.monitor.v1.MonitorService .getMonitorHTTPResponseLog({ id: "123456", logId: "log_456", });
console.log(`URL: ${log?.url}`);console.log(`Errored: ${log?.error}`);console.log(`Status code: ${log?.log?.statusCode}`);console.log(`Assertions: ${log?.assertions ?? "n/a"}`);```
The `log.log` field embeds the same `HTTPResponseLogListItem` returned by `listMonitorHTTPResponseLogs`, so timing and classification fields are available alongside the detail fields.