diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 8ebd951..7ad1e5f 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -47,3 +47,4 @@ jobs:
run: npm publish --access public --provenance
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ NPM_CONFIG_PROVENANCE: true
diff --git a/README.md b/README.md
index a7972a6..fc6c81c 100644
--- a/README.md
+++ b/README.md
@@ -7,8 +7,36 @@
Official Node.js SDK for [OpenStatus](https://openstatus.dev) - The open-source
status page with uptime monitoring.
+## Table of Contents
+
+- [Features](#features)
+- [Installation](#installation)
+- [Quick Start](#quick-start)
+- [Authentication](#authentication)
+- [SDK Reference](#sdk-reference)
+ - [Monitor Service](#monitor-service)
+ - [Health Service](#health-service)
+ - [Status Report Service](#status-report-service)
+ - [Status Page Service](#status-page-service)
+ - [Maintenance Service](#maintenance-service)
+ - [Notification Service](#notification-service)
+- [Reference](#reference)
+ - [Monitor Options](#monitor-options)
+ - [Assertions](#assertions)
+ - [Regions](#regions)
+ - [Enums](#enums)
+- [Error Handling](#error-handling)
+- [Related](#related)
+
## Features
+### Monitoring
+
+- **HTTP Monitoring** - Monitor websites and APIs with customizable assertions
+- **TCP Monitoring** - Check database connections and other TCP services
+- **DNS Monitoring** - Verify DNS records and resolution
+- **Global Regions** - Monitor from 28 locations worldwide
+
### Status Page
- **Status Pages** - Create and manage public status pages with custom domains
@@ -17,27 +45,30 @@ status page with uptime monitoring.
- **Status Reports** - Manage incident reports with update timelines
- **Maintenance Windows** - Schedule and manage planned maintenance periods
-### Monitoring
+### Notifications
-- **HTTP Monitoring** - Monitor websites and APIs with customizable assertions
-- **TCP Monitoring** - Check database connections and other TCP services
-- **DNS Monitoring** - Verify DNS records and resolution
+- **12 Providers** - Slack, Discord, Email, PagerDuty, Opsgenie, Telegram, and
+ more
+- **Webhook Support** - Custom webhooks with headers for any integration
+- **Monitor Alerts** - Get notified when monitors go down or recover
+
+### Developer Experience
-- **Global Regions** - Monitor from 28 locations worldwide
- **Type-safe** - Full TypeScript support with generated types from protobuf
+- **Multiple Runtimes** - Works with Node.js, Deno, and Bun
## Installation
-### JSR
+### npm
```bash
-npx jsr add @openstatus/sdk-node
+npm install @openstatus/sdk-node
```
-### npm
+### JSR
```bash
-npm install @openstatus/sdk-node
+npx jsr add @openstatus/sdk-node
```
### Deno
@@ -58,33 +89,32 @@ import {
} from "@openstatus/sdk-node";
const headers = {
- "x-openstatus-key": `${process.env.OPENSTATUS_API_KEY}`,
+ "x-openstatus-key": process.env.OPENSTATUS_API_KEY,
};
// Create a monitor
-const { monitor } = await openstatus.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,
- statusCodeAssertions: [
- { comparator: NumberComparator.EQUAL, target: BigInt(200) },
- ],
- },
+const { monitor } = await openstatus.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,
+ statusCodeAssertions: [
+ { comparator: NumberComparator.EQUAL, target: BigInt(200) },
+ ],
},
- { headers },
- );
+ },
+ { headers },
+);
console.log(`Monitor created: ${monitor?.id}`);
// List all monitors
-const { httpMonitors, tcpMonitors, dnsMonitors, totalSize } = await openstatus
- .monitor.v1.MonitorService.listMonitors({}, { headers });
+const { httpMonitors, tcpMonitors, dnsMonitors, totalSize } =
+ await openstatus.monitor.v1.MonitorService.listMonitors({}, { headers });
console.log(`Found ${totalSize} monitors`);
```
@@ -96,24 +126,26 @@ All API requests require an API key. Get yours from the
```typescript
const headers = {
- "x-openstatus-key": `${process.env.OPENSTATUS_API_KEY}`,
+ "x-openstatus-key": process.env.OPENSTATUS_API_KEY,
};
// Pass headers to any service method
await openstatus.monitor.v1.MonitorService.listMonitors({}, { headers });
```
-## Environment Variables
+### Environment Variables
| Variable | Description | Default |
| -------------------- | ----------------------- | -------------------------------- |
-| `OPENSTATUS_API_KEY` | Your OpenStatus API key | - |
+| `OPENSTATUS_API_KEY` | Your OpenStatus API key | Required |
| `OPENSTATUS_API_URL` | Custom API endpoint | `https://api.openstatus.dev/rpc` |
-## API Reference
+## SDK Reference
### Monitor Service
+Manage HTTP, TCP, and DNS monitors.
+
#### `createHTTPMonitor(request, options)`
Create an HTTP/HTTPS monitor.
@@ -121,20 +153,19 @@ Create an HTTP/HTTPS monitor.
```typescript
import { HTTPMethod, Periodicity, Region } from "@openstatus/sdk-node";
-const { monitor } = await openstatus.monitor.v1.MonitorService
- .createHTTPMonitor(
- {
- monitor: {
- name: "My Website",
- url: "https://example.com",
- periodicity: Periodicity.PERIODICITY_1M,
- method: HTTPMethod.HTTP_METHOD_GET,
- regions: [Region.FLY_AMS, Region.FLY_IAD, Region.FLY_SYD],
- active: true,
- },
+const { monitor } = await openstatus.monitor.v1.MonitorService.createHTTPMonitor(
+ {
+ monitor: {
+ name: "My Website",
+ url: "https://example.com",
+ periodicity: Periodicity.PERIODICITY_1M,
+ method: HTTPMethod.HTTP_METHOD_GET,
+ regions: [Region.FLY_AMS, Region.FLY_IAD, Region.FLY_SYD],
+ active: true,
},
- { headers },
- );
+ },
+ { headers },
+);
```
#### `updateHTTPMonitor(request, options)`
@@ -142,17 +173,16 @@ const { monitor } = await openstatus.monitor.v1.MonitorService
Update an existing HTTP monitor.
```typescript
-const { monitor } = await openstatus.monitor.v1.MonitorService
- .updateHTTPMonitor(
- {
- id: "mon_123",
- monitor: {
- name: "Updated Name",
- active: false,
- },
+const { monitor } = await openstatus.monitor.v1.MonitorService.updateHTTPMonitor(
+ {
+ id: "mon_123",
+ monitor: {
+ name: "Updated Name",
+ active: false,
},
- { headers },
- );
+ },
+ { headers },
+);
```
#### `createTCPMonitor(request, options)`
@@ -195,7 +225,7 @@ const { monitor } = await openstatus.monitor.v1.MonitorService.updateTCPMonitor(
Create a DNS resolution monitor.
```typescript
-import { RecordComparator } from "@openstatus/sdk-node";
+import { Periodicity, RecordComparator, Region } from "@openstatus/sdk-node";
const { monitor } = await openstatus.monitor.v1.MonitorService.createDNSMonitor(
{
@@ -275,15 +305,11 @@ Get the current status of a monitor across all configured regions.
```typescript
import { MonitorStatus, Region } from "@openstatus/sdk-node";
-const { id, regions } = await openstatus.monitor.v1.MonitorService
- .getMonitorStatus(
- { id: "mon_123" },
- { headers },
- );
+const { id, regions } = await openstatus.monitor.v1.MonitorService.getMonitorStatus(
+ { id: "mon_123" },
+ { headers },
+);
-// regions is an array of { region, status }
-// region: Region enum value (e.g., Region.FLY_AMS)
-// status: MonitorStatus.ACTIVE, MonitorStatus.DEGRADED, or MonitorStatus.ERROR
for (const { region, status } of regions) {
console.log(`${Region[region]}: ${MonitorStatus[status]}`);
}
@@ -299,7 +325,7 @@ import { TimeRange } from "@openstatus/sdk-node";
const summary = await openstatus.monitor.v1.MonitorService.getMonitorSummary(
{
id: "mon_123",
- timeRange: TimeRange.TIME_RANGE_7D, // TIME_RANGE_1D, TIME_RANGE_7D, or TIME_RANGE_14D
+ timeRange: TimeRange.TIME_RANGE_7D,
regions: [], // optional: filter by specific regions
},
{ headers },
@@ -307,15 +333,14 @@ const summary = await openstatus.monitor.v1.MonitorService.getMonitorSummary(
console.log(`Last ping: ${summary.lastPingAt}`);
console.log(`Success: ${summary.totalSuccessful}`);
-console.log(`Degraded: ${summary.totalDegraded}`);
console.log(`Failed: ${summary.totalFailed}`);
console.log(`P50 latency: ${summary.p50}ms`);
-console.log(`P75 latency: ${summary.p75}ms`);
-console.log(`P90 latency: ${summary.p90}ms`);
console.log(`P95 latency: ${summary.p95}ms`);
console.log(`P99 latency: ${summary.p99}ms`);
```
+---
+
### Health Service
Check API health status (no authentication required).
@@ -327,9 +352,11 @@ const { status } = await openstatus.health.v1.HealthService.check({});
console.log(ServingStatus[status]); // "SERVING"
```
+---
+
### Status Report Service
-Manage incident and maintenance reports with update timelines.
+Manage incident reports with update timelines.
#### `createStatusReport(request, options)`
@@ -338,19 +365,18 @@ Create a new status report.
```typescript
import { StatusReportStatus } from "@openstatus/sdk-node";
-const { statusReport } = await openstatus.statusReport.v1.StatusReportService
- .createStatusReport(
- {
- title: "API Degradation",
- status: StatusReportStatus.INVESTIGATING,
- message: "We are investigating reports of increased latency.",
- date: "2024-01-15T10:30:00",
- pageId: "page_123",
- pageComponentIds: ["comp_456"],
- notify: true,
- },
- { headers },
- );
+const { statusReport } = await openstatus.statusReport.v1.StatusReportService.createStatusReport(
+ {
+ title: "API Degradation",
+ status: StatusReportStatus.INVESTIGATING,
+ message: "We are investigating reports of increased latency.",
+ date: "2024-01-15T10:30:00Z",
+ pageId: "page_123",
+ pageComponentIds: ["comp_456"],
+ notify: true,
+ },
+ { headers },
+);
console.log(`Status report created: ${statusReport?.id}`);
```
@@ -360,16 +386,16 @@ console.log(`Status report created: ${statusReport?.id}`);
Get a status report by ID (includes full update timeline).
```typescript
-const { statusReport } = await openstatus.statusReport.v1.StatusReportService
- .getStatusReport(
- { id: "sr_123" },
- { headers },
- );
+import { StatusReportStatus } from "@openstatus/sdk-node";
+
+const { statusReport } = await openstatus.statusReport.v1.StatusReportService.getStatusReport(
+ { id: "sr_123" },
+ { headers },
+);
console.log(`Title: ${statusReport?.title}`);
console.log(`Status: ${StatusReportStatus[statusReport?.status ?? 0]}`);
-// Access update timeline
for (const update of statusReport?.updates ?? []) {
console.log(`${update.date}: ${update.message}`);
}
@@ -382,15 +408,12 @@ List all status reports with pagination and optional filtering.
```typescript
import { StatusReportStatus } from "@openstatus/sdk-node";
-const { statusReports, totalSize } = await openstatus.statusReport.v1
- .StatusReportService.listStatusReports(
+const { statusReports, totalSize } =
+ await openstatus.statusReport.v1.StatusReportService.listStatusReports(
{
limit: 10,
offset: 0,
- statuses: [
- StatusReportStatus.INVESTIGATING,
- StatusReportStatus.IDENTIFIED,
- ],
+ statuses: [StatusReportStatus.INVESTIGATING, StatusReportStatus.IDENTIFIED],
},
{ headers },
);
@@ -400,18 +423,17 @@ console.log(`Found ${totalSize} status reports`);
#### `updateStatusReport(request, options)`
-Update status report metadata (title, page components).
+Update status report metadata.
```typescript
-const { statusReport } = await openstatus.statusReport.v1.StatusReportService
- .updateStatusReport(
- {
- id: "sr_123",
- title: "Updated Title",
- pageComponentIds: ["comp_456", "comp_789"],
- },
- { headers },
- );
+const { statusReport } = await openstatus.statusReport.v1.StatusReportService.updateStatusReport(
+ {
+ id: "sr_123",
+ title: "Updated Title",
+ pageComponentIds: ["comp_456", "comp_789"],
+ },
+ { headers },
+);
```
#### `deleteStatusReport(request, options)`
@@ -419,11 +441,10 @@ const { statusReport } = await openstatus.statusReport.v1.StatusReportService
Delete a status report and all its updates.
```typescript
-const { success } = await openstatus.statusReport.v1.StatusReportService
- .deleteStatusReport(
- { id: "sr_123" },
- { headers },
- );
+const { success } = await openstatus.statusReport.v1.StatusReportService.deleteStatusReport(
+ { id: "sr_123" },
+ { headers },
+);
```
#### `addStatusReportUpdate(request, options)`
@@ -433,29 +454,19 @@ Add a new update to an existing status report timeline.
```typescript
import { StatusReportStatus } from "@openstatus/sdk-node";
-const { statusReport } = await openstatus.statusReport.v1.StatusReportService
- .addStatusReportUpdate(
- {
- statusReportId: "sr_123",
- status: StatusReportStatus.IDENTIFIED,
- message:
- "The issue has been identified as a database connection problem.",
- date: "2024-01-15T11:00:00", // optional, defaults to current time
- notify: true,
- },
- { headers },
- );
+const { statusReport } = await openstatus.statusReport.v1.StatusReportService.addStatusReportUpdate(
+ {
+ statusReportId: "sr_123",
+ status: StatusReportStatus.IDENTIFIED,
+ message: "The issue has been identified as a database connection problem.",
+ date: "2024-01-15T11:00:00Z", // optional, defaults to current time
+ notify: true,
+ },
+ { headers },
+);
```
-### Status Report Status
-
-| Enum Value | Description |
-| --------------- | -------------------------------- |
-| `UNSPECIFIED` | Default/unspecified status |
-| `INVESTIGATING` | Actively investigating the issue |
-| `IDENTIFIED` | Root cause has been identified |
-| `MONITORING` | Fix deployed, monitoring |
-| `RESOLVED` | Issue fully resolved |
+---
### Status Page Service
@@ -466,17 +477,16 @@ Manage status pages, components, and subscribers.
Create a new status page.
```typescript
-const { statusPage } = await openstatus.statusPage.v1.StatusPageService
- .createStatusPage(
- {
- title: "My Service Status",
- slug: "my-service",
- description: "Status page for My Service",
- homepageUrl: "https://example.com",
- contactUrl: "https://example.com/contact",
- },
- { headers },
- );
+const { statusPage } = await openstatus.statusPage.v1.StatusPageService.createStatusPage(
+ {
+ title: "My Service Status",
+ slug: "my-service",
+ description: "Status page for My Service",
+ homepageUrl: "https://example.com",
+ contactUrl: "https://example.com/contact",
+ },
+ { headers },
+);
console.log(`Status page created: ${statusPage?.id}`);
```
@@ -486,11 +496,10 @@ console.log(`Status page created: ${statusPage?.id}`);
Get a status page by ID.
```typescript
-const { statusPage } = await openstatus.statusPage.v1.StatusPageService
- .getStatusPage(
- { id: "page_123" },
- { headers },
- );
+const { statusPage } = await openstatus.statusPage.v1.StatusPageService.getStatusPage(
+ { id: "page_123" },
+ { headers },
+);
```
#### `listStatusPages(request, options)`
@@ -498,8 +507,8 @@ const { statusPage } = await openstatus.statusPage.v1.StatusPageService
List all status pages with pagination.
```typescript
-const { statusPages, totalSize } = await openstatus.statusPage.v1
- .StatusPageService.listStatusPages(
+const { statusPages, totalSize } =
+ await openstatus.statusPage.v1.StatusPageService.listStatusPages(
{ limit: 10, offset: 0 },
{ headers },
);
@@ -512,15 +521,14 @@ console.log(`Found ${totalSize} status pages`);
Update a status page.
```typescript
-const { statusPage } = await openstatus.statusPage.v1.StatusPageService
- .updateStatusPage(
- {
- id: "page_123",
- title: "Updated Title",
- description: "Updated description",
- },
- { headers },
- );
+const { statusPage } = await openstatus.statusPage.v1.StatusPageService.updateStatusPage(
+ {
+ id: "page_123",
+ title: "Updated Title",
+ description: "Updated description",
+ },
+ { headers },
+);
```
#### `deleteStatusPage(request, options)`
@@ -528,11 +536,10 @@ const { statusPage } = await openstatus.statusPage.v1.StatusPageService
Delete a status page.
```typescript
-const { success } = await openstatus.statusPage.v1.StatusPageService
- .deleteStatusPage(
- { id: "page_123" },
- { headers },
- );
+const { success } = await openstatus.statusPage.v1.StatusPageService.deleteStatusPage(
+ { id: "page_123" },
+ { headers },
+);
```
#### `addMonitorComponent(request, options)`
@@ -540,17 +547,16 @@ const { success } = await openstatus.statusPage.v1.StatusPageService
Add a monitor-based component to a status page.
```typescript
-const { component } = await openstatus.statusPage.v1.StatusPageService
- .addMonitorComponent(
- {
- pageId: "page_123",
- monitorId: "mon_456",
- name: "API Server",
- description: "Main API endpoint",
- order: 1,
- },
- { headers },
- );
+const { component } = await openstatus.statusPage.v1.StatusPageService.addMonitorComponent(
+ {
+ pageId: "page_123",
+ monitorId: "mon_456",
+ name: "API Server",
+ description: "Main API endpoint",
+ order: 1,
+ },
+ { headers },
+);
```
#### `addStaticComponent(request, options)`
@@ -558,16 +564,15 @@ const { component } = await openstatus.statusPage.v1.StatusPageService
Add a static component (not linked to a monitor).
```typescript
-const { component } = await openstatus.statusPage.v1.StatusPageService
- .addStaticComponent(
- {
- pageId: "page_123",
- name: "Third-party Service",
- description: "External dependency",
- order: 2,
- },
- { headers },
- );
+const { component } = await openstatus.statusPage.v1.StatusPageService.addStaticComponent(
+ {
+ pageId: "page_123",
+ name: "Third-party Service",
+ description: "External dependency",
+ order: 2,
+ },
+ { headers },
+);
```
#### `updateComponent(request, options)`
@@ -575,15 +580,14 @@ const { component } = await openstatus.statusPage.v1.StatusPageService
Update a component.
```typescript
-const { component } = await openstatus.statusPage.v1.StatusPageService
- .updateComponent(
- {
- id: "comp_123",
- name: "Updated Component Name",
- order: 3,
- },
- { headers },
- );
+const { component } = await openstatus.statusPage.v1.StatusPageService.updateComponent(
+ {
+ id: "comp_123",
+ name: "Updated Component Name",
+ order: 3,
+ },
+ { headers },
+);
```
#### `removeComponent(request, options)`
@@ -591,11 +595,10 @@ const { component } = await openstatus.statusPage.v1.StatusPageService
Remove a component from a status page.
```typescript
-const { success } = await openstatus.statusPage.v1.StatusPageService
- .removeComponent(
- { id: "comp_123" },
- { headers },
- );
+const { success } = await openstatus.statusPage.v1.StatusPageService.removeComponent(
+ { id: "comp_123" },
+ { headers },
+);
```
#### `createComponentGroup(request, options)`
@@ -603,14 +606,13 @@ const { success } = await openstatus.statusPage.v1.StatusPageService
Create a component group.
```typescript
-const { group } = await openstatus.statusPage.v1.StatusPageService
- .createComponentGroup(
- {
- pageId: "page_123",
- name: "Core Services",
- },
- { headers },
- );
+const { group } = await openstatus.statusPage.v1.StatusPageService.createComponentGroup(
+ {
+ pageId: "page_123",
+ name: "Core Services",
+ },
+ { headers },
+);
```
#### `updateComponentGroup(request, options)`
@@ -618,14 +620,13 @@ const { group } = await openstatus.statusPage.v1.StatusPageService
Update a component group.
```typescript
-const { group } = await openstatus.statusPage.v1.StatusPageService
- .updateComponentGroup(
- {
- id: "group_123",
- name: "Updated Group Name",
- },
- { headers },
- );
+const { group } = await openstatus.statusPage.v1.StatusPageService.updateComponentGroup(
+ {
+ id: "group_123",
+ name: "Updated Group Name",
+ },
+ { headers },
+);
```
#### `deleteComponentGroup(request, options)`
@@ -633,11 +634,10 @@ const { group } = await openstatus.statusPage.v1.StatusPageService
Delete a component group.
```typescript
-const { success } = await openstatus.statusPage.v1.StatusPageService
- .deleteComponentGroup(
- { id: "group_123" },
- { headers },
- );
+const { success } = await openstatus.statusPage.v1.StatusPageService.deleteComponentGroup(
+ { id: "group_123" },
+ { headers },
+);
```
#### `subscribeToPage(request, options)`
@@ -645,14 +645,13 @@ const { success } = await openstatus.statusPage.v1.StatusPageService
Subscribe an email to status page updates.
```typescript
-const { subscriber } = await openstatus.statusPage.v1.StatusPageService
- .subscribeToPage(
- {
- pageId: "page_123",
- email: "user@example.com",
- },
- { headers },
- );
+const { subscriber } = await openstatus.statusPage.v1.StatusPageService.subscribeToPage(
+ {
+ pageId: "page_123",
+ email: "user@example.com",
+ },
+ { headers },
+);
```
#### `unsubscribeFromPage(request, options)`
@@ -661,24 +660,22 @@ Unsubscribe from a status page.
```typescript
// By email
-const { success } = await openstatus.statusPage.v1.StatusPageService
- .unsubscribeFromPage(
- {
- pageId: "page_123",
- identifier: { case: "email", value: "user@example.com" },
- },
- { headers },
- );
+const { success } = await openstatus.statusPage.v1.StatusPageService.unsubscribeFromPage(
+ {
+ pageId: "page_123",
+ identifier: { case: "email", value: "user@example.com" },
+ },
+ { headers },
+);
// Or by subscriber ID
-const { success: success2 } = await openstatus.statusPage.v1.StatusPageService
- .unsubscribeFromPage(
- {
- pageId: "page_123",
- identifier: { case: "id", value: "sub_456" },
- },
- { headers },
- );
+const { success: success2 } = await openstatus.statusPage.v1.StatusPageService.unsubscribeFromPage(
+ {
+ pageId: "page_123",
+ identifier: { case: "id", value: "sub_456" },
+ },
+ { headers },
+);
```
#### `listSubscribers(request, options)`
@@ -686,8 +683,8 @@ const { success: success2 } = await openstatus.statusPage.v1.StatusPageService
List all subscribers for a status page.
```typescript
-const { subscribers, totalSize } = await openstatus.statusPage.v1
- .StatusPageService.listSubscribers(
+const { subscribers, totalSize } =
+ await openstatus.statusPage.v1.StatusPageService.listSubscribers(
{
pageId: "page_123",
limit: 50,
@@ -703,11 +700,10 @@ const { subscribers, totalSize } = await openstatus.statusPage.v1
Get full status page content including components, groups, and active reports.
```typescript
-const content = await openstatus.statusPage.v1.StatusPageService
- .getStatusPageContent(
- { identifier: { case: "slug", value: "my-service" } },
- { headers },
- );
+const content = await openstatus.statusPage.v1.StatusPageService.getStatusPageContent(
+ { identifier: { case: "slug", value: "my-service" } },
+ { headers },
+);
console.log(`Page: ${content.statusPage?.title}`);
console.log(`Components: ${content.components.length}`);
@@ -721,8 +717,8 @@ Get the aggregated status of a status page.
```typescript
import { OverallStatus } from "@openstatus/sdk-node";
-const { overallStatus, componentStatuses } = await openstatus.statusPage.v1
- .StatusPageService.getOverallStatus(
+const { overallStatus, componentStatuses } =
+ await openstatus.statusPage.v1.StatusPageService.getOverallStatus(
{ identifier: { case: "id", value: "page_123" } },
{ headers },
);
@@ -733,6 +729,8 @@ for (const { componentId, status } of componentStatuses) {
}
```
+---
+
### Maintenance Service
Manage scheduled maintenance windows.
@@ -742,19 +740,18 @@ Manage scheduled maintenance windows.
Create a new maintenance window.
```typescript
-const { maintenance } = await openstatus.maintenance.v1.MaintenanceService
- .createMaintenance(
- {
- title: "Database Upgrade",
- message: "We will be upgrading our database infrastructure.",
- from: "2024-01-20T02:00:00Z",
- to: "2024-01-20T04:00:00Z",
- pageId: "page_123",
- pageComponentIds: ["comp_456"],
- notify: true,
- },
- { headers },
- );
+const { maintenance } = await openstatus.maintenance.v1.MaintenanceService.createMaintenance(
+ {
+ title: "Database Upgrade",
+ message: "We will be upgrading our database infrastructure.",
+ from: "2024-01-20T02:00:00Z",
+ to: "2024-01-20T04:00:00Z",
+ pageId: "page_123",
+ pageComponentIds: ["comp_456"],
+ notify: true,
+ },
+ { headers },
+);
console.log(`Maintenance created: ${maintenance?.id}`);
```
@@ -764,11 +761,10 @@ console.log(`Maintenance created: ${maintenance?.id}`);
Get a maintenance window by ID.
```typescript
-const { maintenance } = await openstatus.maintenance.v1.MaintenanceService
- .getMaintenance(
- { id: "maint_123" },
- { headers },
- );
+const { maintenance } = await openstatus.maintenance.v1.MaintenanceService.getMaintenance(
+ { id: "maint_123" },
+ { headers },
+);
console.log(`Title: ${maintenance?.title}`);
console.log(`From: ${maintenance?.from}`);
@@ -780,8 +776,8 @@ console.log(`To: ${maintenance?.to}`);
List all maintenance windows with pagination and optional filtering.
```typescript
-const { maintenances, totalSize } = await openstatus.maintenance.v1
- .MaintenanceService.listMaintenances(
+const { maintenances, totalSize } =
+ await openstatus.maintenance.v1.MaintenanceService.listMaintenances(
{
limit: 10,
offset: 0,
@@ -798,15 +794,14 @@ console.log(`Found ${totalSize} maintenance windows`);
Update a maintenance window.
```typescript
-const { maintenance } = await openstatus.maintenance.v1.MaintenanceService
- .updateMaintenance(
- {
- id: "maint_123",
- title: "Extended Database Upgrade",
- to: "2024-01-20T06:00:00Z",
- },
- { headers },
- );
+const { maintenance } = await openstatus.maintenance.v1.MaintenanceService.updateMaintenance(
+ {
+ id: "maint_123",
+ title: "Extended Database Upgrade",
+ to: "2024-01-20T06:00:00Z",
+ },
+ { headers },
+);
```
#### `deleteMaintenance(request, options)`
@@ -814,149 +809,424 @@ const { maintenance } = await openstatus.maintenance.v1.MaintenanceService
Delete a maintenance window.
```typescript
-const { success } = await openstatus.maintenance.v1.MaintenanceService
- .deleteMaintenance(
- { id: "maint_123" },
- { headers },
- );
+const { success } = await openstatus.maintenance.v1.MaintenanceService.deleteMaintenance(
+ { id: "maint_123" },
+ { headers },
+);
```
-### Status Page Options
+---
-| Option | Type | Required | Description |
-| ------------- | ------ | -------- | ---------------------------------------- |
-| `title` | string | Yes | Title of the status page (max 256 chars) |
-| `slug` | string | Yes | URL-friendly slug (lowercase, hyphens) |
-| `description` | string | No | Description (max 2048 chars) |
-| `homepageUrl` | string | No | Link to your homepage |
-| `contactUrl` | string | No | Link to your contact page |
+### Notification Service
-### Page Access Type
+Manage notification channels for monitor alerts. Supports 12 providers including
+Slack, Discord, Email, PagerDuty, and custom webhooks.
-| Enum Value | Description |
-| -------------------- | ----------------------- |
-| `UNSPECIFIED` | Default/unspecified |
-| `PUBLIC` | Publicly accessible |
-| `PASSWORD_PROTECTED` | Requires password |
-| `AUTHENTICATED` | Requires authentication |
+#### `createNotification(request, options)`
-### Page Theme
+Create a new notification channel.
-| Enum Value | Description |
-| ------------- | ------------------- |
-| `UNSPECIFIED` | Default/unspecified |
-| `SYSTEM` | Follow system theme |
-| `LIGHT` | Light theme |
-| `DARK` | Dark theme |
+```typescript
+import { NotificationProvider } from "@openstatus/sdk-node";
-### Overall Status
+const { notification } = await openstatus.notification.v1.NotificationService.createNotification(
+ {
+ name: "Slack Alerts",
+ provider: NotificationProvider.SLACK,
+ data: {
+ data: {
+ case: "slack",
+ value: { webhookUrl: "https://hooks.slack.com/services/..." },
+ },
+ },
+ monitorIds: ["mon_123", "mon_456"],
+ },
+ { headers },
+);
-| Enum Value | Description |
-| ---------------- | --------------------------- |
-| `UNSPECIFIED` | Default/unspecified |
-| `OPERATIONAL` | All systems operational |
-| `DEGRADED` | Performance is degraded |
-| `PARTIAL_OUTAGE` | Some systems are down |
-| `MAJOR_OUTAGE` | Major systems are down |
-| `MAINTENANCE` | Scheduled maintenance |
-| `UNKNOWN` | Status cannot be determined |
+console.log(`Notification created: ${notification?.id}`);
+```
-### Page Component Type
-
-| Enum Value | Description |
-| ------------- | ------------------------- |
-| `UNSPECIFIED` | Default/unspecified |
-| `MONITOR` | Linked to a monitor |
-| `STATIC` | Static component (manual) |
-
-## Monitor Options
-
-### HTTP Monitor
-
-| 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 (see [Periodicity](#periodicity)) |
-| `method` | HTTPMethod | No | HTTP method (see [HTTP Methods](#http-methods)) |
-| `body` | string | No | Request body |
-| `headers` | Headers[] | No | Custom headers (`{ key: string, value: string }[]`) |
-| `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](#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` | array | No | [Status code assertions](#status-code-assertions) |
-| `bodyAssertions` | array | No | [Body assertions](#body-assertions) |
-| `headerAssertions` | array | No | [Header assertions](#header-assertions) |
-| `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration |
-
-### TCP Monitor
-
-| 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 (see [Periodicity](#periodicity)) |
-| `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) |
-| `retry` | bigint | No | Retry attempts (default: 3, max: 10) |
-| `regions` | Region[] | No | [Regions](#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 Monitor
-
-| 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 (see [Periodicity](#periodicity)) |
-| `timeout` | bigint | No | Timeout in ms (default: 45000, max: 120000) |
-| `retry` | bigint | No | Retry attempts (default: 3, max: 10) |
-| `regions` | Region[] | No | [Regions](#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` | array | No | [DNS record assertions](#dns-record-assertions) |
-| `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration |
-
-### Periodicity
-
-| Enum Value | Description |
-| ----------------- | ----------- |
-| `PERIODICITY_30S` | Every 30s |
-| `PERIODICITY_1M` | Every 1m |
-| `PERIODICITY_5M` | Every 5m |
-| `PERIODICITY_10M` | Every 10m |
-| `PERIODICITY_30M` | Every 30m |
-| `PERIODICITY_1H` | Every 1h |
+#### `getNotification(request, options)`
-### HTTP Methods
+Get a notification channel by ID.
-| Enum Value | Description |
-| --------------------- | ----------- |
-| `HTTP_METHOD_GET` | GET |
-| `HTTP_METHOD_POST` | POST |
-| `HTTP_METHOD_HEAD` | HEAD |
-| `HTTP_METHOD_PUT` | PUT |
-| `HTTP_METHOD_PATCH` | PATCH |
-| `HTTP_METHOD_DELETE` | DELETE |
-| `HTTP_METHOD_TRACE` | TRACE |
-| `HTTP_METHOD_CONNECT` | CONNECT |
-| `HTTP_METHOD_OPTIONS` | OPTIONS |
+```typescript
+import { NotificationProvider } from "@openstatus/sdk-node";
+
+const { notification } = await openstatus.notification.v1.NotificationService.getNotification(
+ { id: "notif_123" },
+ { headers },
+);
+
+console.log(`Name: ${notification?.name}`);
+console.log(`Provider: ${NotificationProvider[notification?.provider ?? 0]}`);
+```
+
+#### `listNotifications(request, options)`
+
+List all notification channels with pagination.
+
+```typescript
+const { notifications, totalSize } =
+ await openstatus.notification.v1.NotificationService.listNotifications(
+ { limit: 10, offset: 0 },
+ { headers },
+ );
+
+console.log(`Found ${totalSize} notification channels`);
+```
+
+#### `updateNotification(request, options)`
+
+Update a notification channel.
+
+```typescript
+const { notification } = await openstatus.notification.v1.NotificationService.updateNotification(
+ {
+ id: "notif_123",
+ name: "Updated Slack Alerts",
+ monitorIds: ["mon_123", "mon_456", "mon_789"],
+ },
+ { headers },
+);
+```
+
+#### `deleteNotification(request, options)`
+
+Delete a notification channel.
+
+```typescript
+const { success } = await openstatus.notification.v1.NotificationService.deleteNotification(
+ { id: "notif_123" },
+ { headers },
+);
+```
+
+#### `sendTestNotification(request, options)`
+
+Send a test notification to verify configuration.
+
+```typescript
+import { NotificationProvider } from "@openstatus/sdk-node";
+
+const { success, errorMessage } =
+ await openstatus.notification.v1.NotificationService.sendTestNotification(
+ {
+ provider: NotificationProvider.SLACK,
+ data: {
+ data: {
+ case: "slack",
+ value: { webhookUrl: "https://hooks.slack.com/services/..." },
+ },
+ },
+ },
+ { headers },
+ );
+
+if (success) {
+ console.log("Test notification sent successfully");
+} else {
+ console.log(`Test failed: ${errorMessage}`);
+}
+```
+
+#### `checkNotificationLimit(request, options)`
+
+Check if the workspace has reached its notification limit.
+
+```typescript
+const { limitReached, currentCount, maxCount } =
+ await openstatus.notification.v1.NotificationService.checkNotificationLimit({}, { headers });
+
+console.log(`${currentCount}/${maxCount} notification channels used`);
+```
+
+#### Provider Configuration Examples
-## Assertions
+
+Slack
-All assertion comparators are exported as enums from the SDK.
+```typescript
+{
+ provider: NotificationProvider.SLACK,
+ data: {
+ data: {
+ case: "slack",
+ value: { webhookUrl: "https://hooks.slack.com/services/..." }
+ }
+ }
+}
+```
+
+
+
+
+Discord
+
+```typescript
+{
+ provider: NotificationProvider.DISCORD,
+ data: {
+ data: {
+ case: "discord",
+ value: { webhookUrl: "https://discord.com/api/webhooks/..." }
+ }
+ }
+}
+```
+
+
+
+
+Email
+
+```typescript
+{
+ provider: NotificationProvider.EMAIL,
+ data: {
+ data: {
+ case: "email",
+ value: { email: "alerts@example.com" }
+ }
+ }
+}
+```
+
+
+
+
+PagerDuty
+
+```typescript
+{
+ provider: NotificationProvider.PAGERDUTY,
+ data: {
+ data: {
+ case: "pagerduty",
+ value: { integrationKey: "your-integration-key" }
+ }
+ }
+}
+```
+
+
+
+
+Opsgenie
+
+```typescript
+import { OpsgenieRegion } from "@openstatus/sdk-node";
+
+{
+ provider: NotificationProvider.OPSGENIE,
+ data: {
+ data: {
+ case: "opsgenie",
+ value: { apiKey: "your-api-key", region: OpsgenieRegion.US }
+ }
+ }
+}
+```
+
+
+
+
+Telegram
+
+```typescript
+{
+ provider: NotificationProvider.TELEGRAM,
+ data: {
+ data: {
+ case: "telegram",
+ value: { chatId: "123456789" }
+ }
+ }
+}
+```
+
+
+
+
+Google Chat
+
+```typescript
+{
+ provider: NotificationProvider.GOOGLE_CHAT,
+ data: {
+ data: {
+ case: "googleChat",
+ value: { webhookUrl: "https://chat.googleapis.com/v1/spaces/..." }
+ }
+ }
+}
+```
-### Status Code Assertions
+
+
+
+Grafana OnCall
+
+```typescript
+{
+ provider: NotificationProvider.GRAFANA_ONCALL,
+ data: {
+ data: {
+ case: "grafanaOncall",
+ value: { webhookUrl: "https://oncall.example.com/..." }
+ }
+ }
+}
+```
+
+
+
+
+Ntfy
+
+```typescript
+{
+ provider: NotificationProvider.NTFY,
+ data: {
+ data: {
+ case: "ntfy",
+ value: {
+ topic: "my-alerts",
+ serverUrl: "https://ntfy.sh", // optional, defaults to ntfy.sh
+ token: "tk_..." // optional auth token
+ }
+ }
+ }
+}
+```
+
+
+
+
+SMS
+
+```typescript
+{
+ provider: NotificationProvider.SMS,
+ data: {
+ data: {
+ case: "sms",
+ value: { phoneNumber: "+1234567890" }
+ }
+ }
+}
+```
+
+
+
+
+WhatsApp
+
+```typescript
+{
+ provider: NotificationProvider.WHATSAPP,
+ data: {
+ data: {
+ case: "whatsapp",
+ value: { phoneNumber: "+1234567890" }
+ }
+ }
+}
+```
+
+
+
+
+Custom Webhook
+
+```typescript
+{
+ provider: NotificationProvider.WEBHOOK,
+ data: {
+ data: {
+ case: "webhook",
+ value: {
+ endpoint: "https://api.example.com/webhook",
+ headers: [
+ { key: "Authorization", value: "Bearer token" },
+ { key: "X-Custom-Header", value: "value" }
+ ]
+ }
+ }
+ }
+}
+```
+
+
+
+---
+
+## Reference
+
+### Monitor Options
+
+#### HTTP Monitor
+
+| 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` | array | No | Status code assertions |
+| `bodyAssertions` | array | No | Body assertions |
+| `headerAssertions` | array | No | Header assertions |
+| `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration |
+
+#### TCP Monitor
+
+| 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 Monitor
+
+| 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` | array | No | DNS record assertions |
+| `openTelemetry` | OpenTelemetryConfig | No | OpenTelemetry export configuration |
+
+---
+
+### Assertions
+
+#### Status Code Assertions
Validate HTTP response status codes using `NumberComparator`.
@@ -971,18 +1241,7 @@ import { NumberComparator } from "@openstatus/sdk-node";
}
```
-**NumberComparator values:**
-
-| Enum Value | Description |
-| ----------------------- | --------------------- |
-| `EQUAL` | Equal to target |
-| `NOT_EQUAL` | Not equal to target |
-| `GREATER_THAN` | Greater than target |
-| `GREATER_THAN_OR_EQUAL` | Greater than or equal |
-| `LESS_THAN` | Less than target |
-| `LESS_THAN_OR_EQUAL` | Less than or equal |
-
-### Body Assertions
+#### Body Assertions
Validate response body content using `StringComparator`.
@@ -997,22 +1256,7 @@ import { StringComparator } from "@openstatus/sdk-node";
}
```
-**StringComparator values:**
-
-| Enum Value | Description |
-| ----------------------- | --------------------------- |
-| `CONTAINS` | Contains target string |
-| `NOT_CONTAINS` | Does not contain target |
-| `EQUAL` | Equal to target |
-| `NOT_EQUAL` | Not equal to target |
-| `EMPTY` | Body is empty |
-| `NOT_EMPTY` | Body is not empty |
-| `GREATER_THAN` | Lexicographically greater |
-| `GREATER_THAN_OR_EQUAL` | Lexicographically >= target |
-| `LESS_THAN` | Lexicographically less |
-| `LESS_THAN_OR_EQUAL` | Lexicographically <= target |
-
-### Header Assertions
+#### Header Assertions
Validate response headers using `StringComparator`.
@@ -1030,7 +1274,7 @@ import { StringComparator } from "@openstatus/sdk-node";
}
```
-### DNS Record Assertions
+#### DNS Record Assertions
Validate DNS records using `RecordComparator`.
@@ -1049,30 +1293,21 @@ import { RecordComparator } from "@openstatus/sdk-node";
}
```
-**RecordComparator values:**
-
-| Enum Value | Description |
-| -------------- | ----------------------- |
-| `EQUAL` | Equal to target |
-| `NOT_EQUAL` | Not equal to target |
-| `CONTAINS` | Contains target string |
-| `NOT_CONTAINS` | Does not contain target |
-
**Supported record types:** `A`, `AAAA`, `CNAME`, `MX`, `TXT`
-## Regions
+---
+
+### Regions
-Monitor from 28 global locations across multiple providers. Use the `Region`
-enum:
+Monitor from 28 global locations across multiple providers.
```typescript
import { Region } from "@openstatus/sdk-node";
-// Example: Use specific regions
regions: [Region.FLY_AMS, Region.FLY_IAD, Region.KOYEB_FRA];
```
-### Fly.io Regions
+#### Fly.io Regions (18)
| Enum Value | Location |
| ---------- | --------------- |
@@ -1095,7 +1330,7 @@ regions: [Region.FLY_AMS, Region.FLY_IAD, Region.KOYEB_FRA];
| `FLY_SYD` | Sydney |
| `FLY_YYZ` | Toronto |
-### Koyeb Regions
+#### Koyeb Regions (6)
| Enum Value | Location |
| ----------- | ------------- |
@@ -1106,7 +1341,7 @@ regions: [Region.FLY_AMS, Region.FLY_IAD, Region.KOYEB_FRA];
| `KOYEB_TYO` | Tokyo |
| `KOYEB_WAS` | Washington |
-### Railway Regions
+#### Railway Regions (4)
| Enum Value | Location |
| ------------------------- | -------------- |
@@ -1115,6 +1350,155 @@ regions: [Region.FLY_AMS, Region.FLY_IAD, Region.KOYEB_FRA];
| `RAILWAY_EUROPE_WEST4` | Europe West |
| `RAILWAY_ASIA_SOUTHEAST1` | Asia Southeast |
+---
+
+### Enums
+
+#### Periodicity
+
+| Value | Description |
+| ----------------- | ----------- |
+| `PERIODICITY_30S` | Every 30s |
+| `PERIODICITY_1M` | Every 1m |
+| `PERIODICITY_5M` | Every 5m |
+| `PERIODICITY_10M` | Every 10m |
+| `PERIODICITY_30M` | Every 30m |
+| `PERIODICITY_1H` | Every 1h |
+
+#### HTTPMethod
+
+| Value | Description |
+| --------------------- | ----------- |
+| `HTTP_METHOD_GET` | GET |
+| `HTTP_METHOD_POST` | POST |
+| `HTTP_METHOD_HEAD` | HEAD |
+| `HTTP_METHOD_PUT` | PUT |
+| `HTTP_METHOD_PATCH` | PATCH |
+| `HTTP_METHOD_DELETE` | DELETE |
+| `HTTP_METHOD_TRACE` | TRACE |
+| `HTTP_METHOD_CONNECT` | CONNECT |
+| `HTTP_METHOD_OPTIONS` | OPTIONS |
+
+#### MonitorStatus
+
+| Value | Description |
+| ---------- | ------------------------ |
+| `ACTIVE` | Monitor is healthy |
+| `DEGRADED` | Latency threshold exceeded |
+| `ERROR` | Monitor is failing |
+
+#### TimeRange
+
+| Value | Description |
+| ----------------- | ----------- |
+| `TIME_RANGE_1D` | Last 1 day |
+| `TIME_RANGE_7D` | Last 7 days |
+| `TIME_RANGE_14D` | Last 14 days|
+
+#### StatusReportStatus
+
+| Value | Description |
+| --------------- | -------------------------------- |
+| `INVESTIGATING` | Actively investigating the issue |
+| `IDENTIFIED` | Root cause has been identified |
+| `MONITORING` | Fix deployed, monitoring |
+| `RESOLVED` | Issue fully resolved |
+
+#### OverallStatus
+
+| Value | Description |
+| ---------------- | --------------------------- |
+| `OPERATIONAL` | All systems operational |
+| `DEGRADED` | Performance is degraded |
+| `PARTIAL_OUTAGE` | Some systems are down |
+| `MAJOR_OUTAGE` | Major systems are down |
+| `MAINTENANCE` | Scheduled maintenance |
+| `UNKNOWN` | Status cannot be determined |
+
+#### NotificationProvider
+
+| Value | Description |
+| ---------------- | ------------------- |
+| `DISCORD` | Discord webhook |
+| `EMAIL` | Email notification |
+| `GOOGLE_CHAT` | Google Chat webhook |
+| `GRAFANA_ONCALL` | Grafana OnCall |
+| `NTFY` | Ntfy push service |
+| `PAGERDUTY` | PagerDuty |
+| `OPSGENIE` | Opsgenie |
+| `SLACK` | Slack webhook |
+| `SMS` | SMS notification |
+| `TELEGRAM` | Telegram bot |
+| `WEBHOOK` | Custom webhook |
+| `WHATSAPP` | WhatsApp |
+
+#### OpsgenieRegion
+
+| Value | Description |
+| ----- | ----------- |
+| `US` | US region |
+| `EU` | EU region |
+
+#### PageAccessType
+
+| Value | Description |
+| -------------------- | ----------------------- |
+| `PUBLIC` | Publicly accessible |
+| `PASSWORD_PROTECTED` | Requires password |
+| `AUTHENTICATED` | Requires authentication |
+
+#### PageTheme
+
+| Value | Description |
+| -------- | ------------------- |
+| `SYSTEM` | Follow system theme |
+| `LIGHT` | Light theme |
+| `DARK` | Dark theme |
+
+#### PageComponentType
+
+| Value | Description |
+| --------- | ------------------------- |
+| `MONITOR` | Linked to a monitor |
+| `STATIC` | Static component (manual) |
+
+#### NumberComparator
+
+| Value | Description |
+| ----------------------- | --------------------- |
+| `EQUAL` | Equal to target |
+| `NOT_EQUAL` | Not equal to target |
+| `GREATER_THAN` | Greater than target |
+| `GREATER_THAN_OR_EQUAL` | Greater than or equal |
+| `LESS_THAN` | Less than target |
+| `LESS_THAN_OR_EQUAL` | Less than or equal |
+
+#### StringComparator
+
+| Value | Description |
+| ----------------------- | --------------------------- |
+| `CONTAINS` | Contains target string |
+| `NOT_CONTAINS` | Does not contain target |
+| `EQUAL` | Equal to target |
+| `NOT_EQUAL` | Not equal to target |
+| `EMPTY` | Value is empty |
+| `NOT_EMPTY` | Value is not empty |
+| `GREATER_THAN` | Lexicographically greater |
+| `GREATER_THAN_OR_EQUAL` | Lexicographically >= target |
+| `LESS_THAN` | Lexicographically less |
+| `LESS_THAN_OR_EQUAL` | Lexicographically <= target |
+
+#### RecordComparator
+
+| Value | Description |
+| -------------- | ----------------------- |
+| `EQUAL` | Equal to target |
+| `NOT_EQUAL` | Not equal to target |
+| `CONTAINS` | Contains target string |
+| `NOT_CONTAINS` | Does not contain target |
+
+---
+
## Error Handling
The SDK uses Connect RPC. Errors include a `code` and `message`:
diff --git a/scripts/build_npm.ts b/scripts/build_npm.ts
index bb65051..61cae38 100644
--- a/scripts/build_npm.ts
+++ b/scripts/build_npm.ts
@@ -22,6 +22,10 @@ await build({
bugs: {
url: "https://github.com/openstatushq/sdk-node/issues",
},
+ publishConfig: {
+ access: "public",
+ provenance: true,
+ },
},
postBuild() {
// steps to run after building and before running the tests
diff --git a/src/gen/openstatus/notification/v1/notification_pb.ts b/src/gen/openstatus/notification/v1/notification_pb.ts
new file mode 100644
index 0000000..3ddfac5
--- /dev/null
+++ b/src/gen/openstatus/notification/v1/notification_pb.ts
@@ -0,0 +1,144 @@
+// @generated by protoc-gen-es v2.11.0 with parameter "target=ts,import_extension=ts"
+// @generated from file openstatus/notification/v1/notification.proto (package openstatus.notification.v1, syntax proto3)
+/* eslint-disable */
+
+import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
+import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
+import type { NotificationData, NotificationProvider } from "./providers_pb.ts";
+import { file_openstatus_notification_v1_providers } from "./providers_pb.ts";
+import type { Message } from "@bufbuild/protobuf";
+
+/**
+ * Describes the file openstatus/notification/v1/notification.proto.
+ */
+export const file_openstatus_notification_v1_notification:
+ GenFile = /*@__PURE__*/
+ fileDesc(
+ "Ci1vcGVuc3RhdHVzL25vdGlmaWNhdGlvbi92MS9ub3RpZmljYXRpb24ucHJvdG8SGm9wZW5zdGF0dXMubm90aWZpY2F0aW9uLnYxIuUBCgxOb3RpZmljYXRpb24SCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRJCCghwcm92aWRlchgDIAEoDjIwLm9wZW5zdGF0dXMubm90aWZpY2F0aW9uLnYxLk5vdGlmaWNhdGlvblByb3ZpZGVyEjoKBGRhdGEYBCABKAsyLC5vcGVuc3RhdHVzLm5vdGlmaWNhdGlvbi52MS5Ob3RpZmljYXRpb25EYXRhEhMKC21vbml0b3JfaWRzGAUgAygJEhIKCmNyZWF0ZWRfYXQYBiABKAkSEgoKdXBkYXRlZF9hdBgHIAEoCSKyAQoTTm90aWZpY2F0aW9uU3VtbWFyeRIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJEkIKCHByb3ZpZGVyGAMgASgOMjAub3BlbnN0YXR1cy5ub3RpZmljYXRpb24udjEuTm90aWZpY2F0aW9uUHJvdmlkZXISFQoNbW9uaXRvcl9jb3VudBgEIAEoBRISCgpjcmVhdGVkX2F0GAUgASgJEhIKCnVwZGF0ZWRfYXQYBiABKAlCXVpbZ2l0aHViLmNvbS9vcGVuc3RhdHVzaHEvb3BlbnN0YXR1cy9wYWNrYWdlcy9wcm90by9vcGVuc3RhdHVzL25vdGlmaWNhdGlvbi92MTtub3RpZmljYXRpb252MWIGcHJvdG8z",
+ [file_openstatus_notification_v1_providers],
+ );
+
+/**
+ * Notification represents a notification channel with full details.
+ *
+ * @generated from message openstatus.notification.v1.Notification
+ */
+export type Notification =
+ & Message<"openstatus.notification.v1.Notification">
+ & {
+ /**
+ * Unique identifier for the notification.
+ *
+ * @generated from field: string id = 1;
+ */
+ id: string;
+
+ /**
+ * Display name for the notification channel.
+ *
+ * @generated from field: string name = 2;
+ */
+ name: string;
+
+ /**
+ * Provider type.
+ *
+ * @generated from field: openstatus.notification.v1.NotificationProvider provider = 3;
+ */
+ provider: NotificationProvider;
+
+ /**
+ * Provider-specific configuration.
+ *
+ * @generated from field: openstatus.notification.v1.NotificationData data = 4;
+ */
+ data?: NotificationData;
+
+ /**
+ * IDs of monitors associated with this notification.
+ *
+ * @generated from field: repeated string monitor_ids = 5;
+ */
+ monitorIds: string[];
+
+ /**
+ * Timestamp when the notification was created (RFC 3339).
+ *
+ * @generated from field: string created_at = 6;
+ */
+ createdAt: string;
+
+ /**
+ * Timestamp when the notification was last updated (RFC 3339).
+ *
+ * @generated from field: string updated_at = 7;
+ */
+ updatedAt: string;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.Notification.
+ * Use `create(NotificationSchema)` to create a new message.
+ */
+export const NotificationSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_notification, 0);
+
+/**
+ * NotificationSummary represents a notification channel summary for list responses.
+ *
+ * @generated from message openstatus.notification.v1.NotificationSummary
+ */
+export type NotificationSummary =
+ & Message<"openstatus.notification.v1.NotificationSummary">
+ & {
+ /**
+ * Unique identifier for the notification.
+ *
+ * @generated from field: string id = 1;
+ */
+ id: string;
+
+ /**
+ * Display name for the notification channel.
+ *
+ * @generated from field: string name = 2;
+ */
+ name: string;
+
+ /**
+ * Provider type.
+ *
+ * @generated from field: openstatus.notification.v1.NotificationProvider provider = 3;
+ */
+ provider: NotificationProvider;
+
+ /**
+ * Number of monitors associated with this notification.
+ *
+ * @generated from field: int32 monitor_count = 4;
+ */
+ monitorCount: number;
+
+ /**
+ * Timestamp when the notification was created (RFC 3339).
+ *
+ * @generated from field: string created_at = 5;
+ */
+ createdAt: string;
+
+ /**
+ * Timestamp when the notification was last updated (RFC 3339).
+ *
+ * @generated from field: string updated_at = 6;
+ */
+ updatedAt: string;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.NotificationSummary.
+ * Use `create(NotificationSummarySchema)` to create a new message.
+ */
+export const NotificationSummarySchema: GenMessage<
+ NotificationSummary
+> = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_notification, 1);
diff --git a/src/gen/openstatus/notification/v1/providers_pb.ts b/src/gen/openstatus/notification/v1/providers_pb.ts
new file mode 100644
index 0000000..66e6440
--- /dev/null
+++ b/src/gen/openstatus/notification/v1/providers_pb.ts
@@ -0,0 +1,604 @@
+// @generated by protoc-gen-es v2.11.0 with parameter "target=ts,import_extension=ts"
+// @generated from file openstatus/notification/v1/providers.proto (package openstatus.notification.v1, syntax proto3)
+/* eslint-disable */
+
+import type {
+ GenEnum,
+ GenFile,
+ GenMessage,
+} from "@bufbuild/protobuf/codegenv2";
+import { enumDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
+import { file_buf_validate_validate } from "../../../buf/validate/validate_pb.ts";
+import type { Message } from "@bufbuild/protobuf";
+
+/**
+ * Describes the file openstatus/notification/v1/providers.proto.
+ */
+export const file_openstatus_notification_v1_providers: GenFile = /*@__PURE__*/
+ fileDesc(
+ "CipvcGVuc3RhdHVzL25vdGlmaWNhdGlvbi92MS9wcm92aWRlcnMucHJvdG8SGm9wZW5zdGF0dXMubm90aWZpY2F0aW9uLnYxIiwKC0Rpc2NvcmREYXRhEh0KC3dlYmhvb2tfdXJsGAEgASgJQgi6SAVyA4gBASIjCglFbWFpbERhdGESFgoFZW1haWwYASABKAlCB7pIBHICYAEiLwoOR29vZ2xlQ2hhdERhdGESHQoLd2ViaG9va191cmwYASABKAlCCLpIBXIDiAEBIjIKEUdyYWZhbmFPbmNhbGxEYXRhEh0KC3dlYmhvb2tfdXJsGAEgASgJQgi6SAVyA4gBASJUCghOdGZ5RGF0YRIWCgV0b3BpYxgBIAEoCUIHukgEcgIQARISCgpzZXJ2ZXJfdXJsGAIgASgJEhIKBXRva2VuGAMgASgJSACIAQFCCAoGX3Rva2VuIjEKDVBhZ2VyRHV0eURhdGESIAoPaW50ZWdyYXRpb25fa2V5GAEgASgJQge6SARyAhABIm4KDE9wc2dlbmllRGF0YRIYCgdhcGlfa2V5GAEgASgJQge6SARyAhABEkQKBnJlZ2lvbhgCIAEoDjIqLm9wZW5zdGF0dXMubm90aWZpY2F0aW9uLnYxLk9wc2dlbmllUmVnaW9uQgi6SAWCAQIQASIqCglTbGFja0RhdGESHQoLd2ViaG9va191cmwYASABKAlCCLpIBXIDiAEBIigKB1Ntc0RhdGESHQoMcGhvbmVfbnVtYmVyGAEgASgJQge6SARyAhABIigKDFRlbGVncmFtRGF0YRIYCgdjaGF0X2lkGAEgASgJQge6SARyAhABIjQKDVdlYmhvb2tIZWFkZXISFAoDa2V5GAEgASgJQge6SARyAhABEg0KBXZhbHVlGAIgASgJImUKC1dlYmhvb2tEYXRhEhoKCGVuZHBvaW50GAEgASgJQgi6SAVyA4gBARI6CgdoZWFkZXJzGAIgAygLMikub3BlbnN0YXR1cy5ub3RpZmljYXRpb24udjEuV2ViaG9va0hlYWRlciItCgxXaGF0c2FwcERhdGESHQoMcGhvbmVfbnVtYmVyGAEgASgJQge6SARyAhABIvIFChBOb3RpZmljYXRpb25EYXRhEjoKB2Rpc2NvcmQYASABKAsyJy5vcGVuc3RhdHVzLm5vdGlmaWNhdGlvbi52MS5EaXNjb3JkRGF0YUgAEjYKBWVtYWlsGAIgASgLMiUub3BlbnN0YXR1cy5ub3RpZmljYXRpb24udjEuRW1haWxEYXRhSAASQQoLZ29vZ2xlX2NoYXQYAyABKAsyKi5vcGVuc3RhdHVzLm5vdGlmaWNhdGlvbi52MS5Hb29nbGVDaGF0RGF0YUgAEkcKDmdyYWZhbmFfb25jYWxsGAQgASgLMi0ub3BlbnN0YXR1cy5ub3RpZmljYXRpb24udjEuR3JhZmFuYU9uY2FsbERhdGFIABI0CgRudGZ5GAUgASgLMiQub3BlbnN0YXR1cy5ub3RpZmljYXRpb24udjEuTnRmeURhdGFIABI+CglwYWdlcmR1dHkYBiABKAsyKS5vcGVuc3RhdHVzLm5vdGlmaWNhdGlvbi52MS5QYWdlckR1dHlEYXRhSAASPAoIb3BzZ2VuaWUYByABKAsyKC5vcGVuc3RhdHVzLm5vdGlmaWNhdGlvbi52MS5PcHNnZW5pZURhdGFIABI2CgVzbGFjaxgIIAEoCzIlLm9wZW5zdGF0dXMubm90aWZpY2F0aW9uLnYxLlNsYWNrRGF0YUgAEjIKA3NtcxgJIAEoCzIjLm9wZW5zdGF0dXMubm90aWZpY2F0aW9uLnYxLlNtc0RhdGFIABI8Cgh0ZWxlZ3JhbRgKIAEoCzIoLm9wZW5zdGF0dXMubm90aWZpY2F0aW9uLnYxLlRlbGVncmFtRGF0YUgAEjoKB3dlYmhvb2sYCyABKAsyJy5vcGVuc3RhdHVzLm5vdGlmaWNhdGlvbi52MS5XZWJob29rRGF0YUgAEjwKCHdoYXRzYXBwGAwgASgLMigub3BlbnN0YXR1cy5ub3RpZmljYXRpb24udjEuV2hhdHNhcHBEYXRhSABCBgoEZGF0YSrmAwoUTm90aWZpY2F0aW9uUHJvdmlkZXISJQohTk9USUZJQ0FUSU9OX1BST1ZJREVSX1VOU1BFQ0lGSUVEEAASIQodTk9USUZJQ0FUSU9OX1BST1ZJREVSX0RJU0NPUkQQARIfChtOT1RJRklDQVRJT05fUFJPVklERVJfRU1BSUwQAhIlCiFOT1RJRklDQVRJT05fUFJPVklERVJfR09PR0xFX0NIQVQQAxIoCiROT1RJRklDQVRJT05fUFJPVklERVJfR1JBRkFOQV9PTkNBTEwQBBIeChpOT1RJRklDQVRJT05fUFJPVklERVJfTlRGWRAFEiMKH05PVElGSUNBVElPTl9QUk9WSURFUl9QQUdFUkRVVFkQBhIiCh5OT1RJRklDQVRJT05fUFJPVklERVJfT1BTR0VOSUUQBxIfChtOT1RJRklDQVRJT05fUFJPVklERVJfU0xBQ0sQCBIdChlOT1RJRklDQVRJT05fUFJPVklERVJfU01TEAkSIgoeTk9USUZJQ0FUSU9OX1BST1ZJREVSX1RFTEVHUkFNEAoSIQodTk9USUZJQ0FUSU9OX1BST1ZJREVSX1dFQkhPT0sQCxIiCh5OT1RJRklDQVRJT05fUFJPVklERVJfV0hBVFNBUFAQDCphCg5PcHNnZW5pZVJlZ2lvbhIfChtPUFNHRU5JRV9SRUdJT05fVU5TUEVDSUZJRUQQABIWChJPUFNHRU5JRV9SRUdJT05fVVMQARIWChJPUFNHRU5JRV9SRUdJT05fRVUQAkJdWltnaXRodWIuY29tL29wZW5zdGF0dXNocS9vcGVuc3RhdHVzL3BhY2thZ2VzL3Byb3RvL29wZW5zdGF0dXMvbm90aWZpY2F0aW9uL3YxO25vdGlmaWNhdGlvbnYxYgZwcm90bzM",
+ [file_buf_validate_validate],
+ );
+
+/**
+ * DiscordData contains configuration for Discord notifications.
+ *
+ * @generated from message openstatus.notification.v1.DiscordData
+ */
+export type DiscordData = Message<"openstatus.notification.v1.DiscordData"> & {
+ /**
+ * Discord webhook URL.
+ *
+ * @generated from field: string webhook_url = 1;
+ */
+ webhookUrl: string;
+};
+
+/**
+ * Describes the message openstatus.notification.v1.DiscordData.
+ * Use `create(DiscordDataSchema)` to create a new message.
+ */
+export const DiscordDataSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_providers, 0);
+
+/**
+ * EmailData contains configuration for email notifications.
+ *
+ * @generated from message openstatus.notification.v1.EmailData
+ */
+export type EmailData = Message<"openstatus.notification.v1.EmailData"> & {
+ /**
+ * Email address to send notifications to.
+ *
+ * @generated from field: string email = 1;
+ */
+ email: string;
+};
+
+/**
+ * Describes the message openstatus.notification.v1.EmailData.
+ * Use `create(EmailDataSchema)` to create a new message.
+ */
+export const EmailDataSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_providers, 1);
+
+/**
+ * GoogleChatData contains configuration for Google Chat notifications.
+ *
+ * @generated from message openstatus.notification.v1.GoogleChatData
+ */
+export type GoogleChatData =
+ & Message<"openstatus.notification.v1.GoogleChatData">
+ & {
+ /**
+ * Google Chat webhook URL.
+ *
+ * @generated from field: string webhook_url = 1;
+ */
+ webhookUrl: string;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.GoogleChatData.
+ * Use `create(GoogleChatDataSchema)` to create a new message.
+ */
+export const GoogleChatDataSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_providers, 2);
+
+/**
+ * GrafanaOncallData contains configuration for Grafana OnCall notifications.
+ *
+ * @generated from message openstatus.notification.v1.GrafanaOncallData
+ */
+export type GrafanaOncallData =
+ & Message<"openstatus.notification.v1.GrafanaOncallData">
+ & {
+ /**
+ * Grafana OnCall webhook URL.
+ *
+ * @generated from field: string webhook_url = 1;
+ */
+ webhookUrl: string;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.GrafanaOncallData.
+ * Use `create(GrafanaOncallDataSchema)` to create a new message.
+ */
+export const GrafanaOncallDataSchema: GenMessage<
+ GrafanaOncallData
+> = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_providers, 3);
+
+/**
+ * NtfyData contains configuration for Ntfy notifications.
+ *
+ * @generated from message openstatus.notification.v1.NtfyData
+ */
+export type NtfyData = Message<"openstatus.notification.v1.NtfyData"> & {
+ /**
+ * Ntfy topic to publish to.
+ *
+ * @generated from field: string topic = 1;
+ */
+ topic: string;
+
+ /**
+ * Ntfy server URL (defaults to https://ntfy.sh).
+ *
+ * @generated from field: string server_url = 2;
+ */
+ serverUrl: string;
+
+ /**
+ * Optional authentication token.
+ *
+ * @generated from field: optional string token = 3;
+ */
+ token?: string;
+};
+
+/**
+ * Describes the message openstatus.notification.v1.NtfyData.
+ * Use `create(NtfyDataSchema)` to create a new message.
+ */
+export const NtfyDataSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_providers, 4);
+
+/**
+ * PagerDutyData contains configuration for PagerDuty notifications.
+ *
+ * @generated from message openstatus.notification.v1.PagerDutyData
+ */
+export type PagerDutyData =
+ & Message<"openstatus.notification.v1.PagerDutyData">
+ & {
+ /**
+ * PagerDuty integration key.
+ *
+ * @generated from field: string integration_key = 1;
+ */
+ integrationKey: string;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.PagerDutyData.
+ * Use `create(PagerDutyDataSchema)` to create a new message.
+ */
+export const PagerDutyDataSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_providers, 5);
+
+/**
+ * OpsgenieData contains configuration for Opsgenie notifications.
+ *
+ * @generated from message openstatus.notification.v1.OpsgenieData
+ */
+export type OpsgenieData =
+ & Message<"openstatus.notification.v1.OpsgenieData">
+ & {
+ /**
+ * Opsgenie API key.
+ *
+ * @generated from field: string api_key = 1;
+ */
+ apiKey: string;
+
+ /**
+ * Opsgenie region.
+ *
+ * @generated from field: openstatus.notification.v1.OpsgenieRegion region = 2;
+ */
+ region: OpsgenieRegion;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.OpsgenieData.
+ * Use `create(OpsgenieDataSchema)` to create a new message.
+ */
+export const OpsgenieDataSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_providers, 6);
+
+/**
+ * SlackData contains configuration for Slack notifications.
+ *
+ * @generated from message openstatus.notification.v1.SlackData
+ */
+export type SlackData = Message<"openstatus.notification.v1.SlackData"> & {
+ /**
+ * Slack webhook URL.
+ *
+ * @generated from field: string webhook_url = 1;
+ */
+ webhookUrl: string;
+};
+
+/**
+ * Describes the message openstatus.notification.v1.SlackData.
+ * Use `create(SlackDataSchema)` to create a new message.
+ */
+export const SlackDataSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_providers, 7);
+
+/**
+ * SmsData contains configuration for SMS notifications.
+ *
+ * @generated from message openstatus.notification.v1.SmsData
+ */
+export type SmsData = Message<"openstatus.notification.v1.SmsData"> & {
+ /**
+ * Phone number to send SMS to.
+ *
+ * @generated from field: string phone_number = 1;
+ */
+ phoneNumber: string;
+};
+
+/**
+ * Describes the message openstatus.notification.v1.SmsData.
+ * Use `create(SmsDataSchema)` to create a new message.
+ */
+export const SmsDataSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_providers, 8);
+
+/**
+ * TelegramData contains configuration for Telegram notifications.
+ *
+ * @generated from message openstatus.notification.v1.TelegramData
+ */
+export type TelegramData =
+ & Message<"openstatus.notification.v1.TelegramData">
+ & {
+ /**
+ * Telegram chat ID.
+ *
+ * @generated from field: string chat_id = 1;
+ */
+ chatId: string;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.TelegramData.
+ * Use `create(TelegramDataSchema)` to create a new message.
+ */
+export const TelegramDataSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_providers, 9);
+
+/**
+ * WebhookHeader represents a custom header for webhook requests.
+ *
+ * @generated from message openstatus.notification.v1.WebhookHeader
+ */
+export type WebhookHeader =
+ & Message<"openstatus.notification.v1.WebhookHeader">
+ & {
+ /**
+ * Header name.
+ *
+ * @generated from field: string key = 1;
+ */
+ key: string;
+
+ /**
+ * Header value.
+ *
+ * @generated from field: string value = 2;
+ */
+ value: string;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.WebhookHeader.
+ * Use `create(WebhookHeaderSchema)` to create a new message.
+ */
+export const WebhookHeaderSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_providers, 10);
+
+/**
+ * WebhookData contains configuration for custom webhook notifications.
+ *
+ * @generated from message openstatus.notification.v1.WebhookData
+ */
+export type WebhookData = Message<"openstatus.notification.v1.WebhookData"> & {
+ /**
+ * Webhook endpoint URL.
+ *
+ * @generated from field: string endpoint = 1;
+ */
+ endpoint: string;
+
+ /**
+ * Optional custom headers.
+ *
+ * @generated from field: repeated openstatus.notification.v1.WebhookHeader headers = 2;
+ */
+ headers: WebhookHeader[];
+};
+
+/**
+ * Describes the message openstatus.notification.v1.WebhookData.
+ * Use `create(WebhookDataSchema)` to create a new message.
+ */
+export const WebhookDataSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_providers, 11);
+
+/**
+ * WhatsappData contains configuration for WhatsApp notifications.
+ *
+ * @generated from message openstatus.notification.v1.WhatsappData
+ */
+export type WhatsappData =
+ & Message<"openstatus.notification.v1.WhatsappData">
+ & {
+ /**
+ * Phone number to send WhatsApp messages to.
+ *
+ * @generated from field: string phone_number = 1;
+ */
+ phoneNumber: string;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.WhatsappData.
+ * Use `create(WhatsappDataSchema)` to create a new message.
+ */
+export const WhatsappDataSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_providers, 12);
+
+/**
+ * NotificationData is a union of provider-specific configuration.
+ *
+ * @generated from message openstatus.notification.v1.NotificationData
+ */
+export type NotificationData =
+ & Message<"openstatus.notification.v1.NotificationData">
+ & {
+ /**
+ * @generated from oneof openstatus.notification.v1.NotificationData.data
+ */
+ data: {
+ /**
+ * Discord configuration.
+ *
+ * @generated from field: openstatus.notification.v1.DiscordData discord = 1;
+ */
+ value: DiscordData;
+ case: "discord";
+ } | {
+ /**
+ * Email configuration.
+ *
+ * @generated from field: openstatus.notification.v1.EmailData email = 2;
+ */
+ value: EmailData;
+ case: "email";
+ } | {
+ /**
+ * Google Chat configuration.
+ *
+ * @generated from field: openstatus.notification.v1.GoogleChatData google_chat = 3;
+ */
+ value: GoogleChatData;
+ case: "googleChat";
+ } | {
+ /**
+ * Grafana OnCall configuration.
+ *
+ * @generated from field: openstatus.notification.v1.GrafanaOncallData grafana_oncall = 4;
+ */
+ value: GrafanaOncallData;
+ case: "grafanaOncall";
+ } | {
+ /**
+ * Ntfy configuration.
+ *
+ * @generated from field: openstatus.notification.v1.NtfyData ntfy = 5;
+ */
+ value: NtfyData;
+ case: "ntfy";
+ } | {
+ /**
+ * PagerDuty configuration.
+ *
+ * @generated from field: openstatus.notification.v1.PagerDutyData pagerduty = 6;
+ */
+ value: PagerDutyData;
+ case: "pagerduty";
+ } | {
+ /**
+ * Opsgenie configuration.
+ *
+ * @generated from field: openstatus.notification.v1.OpsgenieData opsgenie = 7;
+ */
+ value: OpsgenieData;
+ case: "opsgenie";
+ } | {
+ /**
+ * Slack configuration.
+ *
+ * @generated from field: openstatus.notification.v1.SlackData slack = 8;
+ */
+ value: SlackData;
+ case: "slack";
+ } | {
+ /**
+ * SMS configuration.
+ *
+ * @generated from field: openstatus.notification.v1.SmsData sms = 9;
+ */
+ value: SmsData;
+ case: "sms";
+ } | {
+ /**
+ * Telegram configuration.
+ *
+ * @generated from field: openstatus.notification.v1.TelegramData telegram = 10;
+ */
+ value: TelegramData;
+ case: "telegram";
+ } | {
+ /**
+ * Webhook configuration.
+ *
+ * @generated from field: openstatus.notification.v1.WebhookData webhook = 11;
+ */
+ value: WebhookData;
+ case: "webhook";
+ } | {
+ /**
+ * WhatsApp configuration.
+ *
+ * @generated from field: openstatus.notification.v1.WhatsappData whatsapp = 12;
+ */
+ value: WhatsappData;
+ case: "whatsapp";
+ } | { case: undefined; value?: undefined };
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.NotificationData.
+ * Use `create(NotificationDataSchema)` to create a new message.
+ */
+export const NotificationDataSchema: GenMessage<
+ NotificationData
+> = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_providers, 13);
+
+/**
+ * NotificationProvider represents the supported notification channel types.
+ *
+ * @generated from enum openstatus.notification.v1.NotificationProvider
+ */
+export enum NotificationProvider {
+ /**
+ * Unspecified provider.
+ *
+ * @generated from enum value: NOTIFICATION_PROVIDER_UNSPECIFIED = 0;
+ */
+ UNSPECIFIED = 0,
+
+ /**
+ * Discord webhook.
+ *
+ * @generated from enum value: NOTIFICATION_PROVIDER_DISCORD = 1;
+ */
+ DISCORD = 1,
+
+ /**
+ * Email notification.
+ *
+ * @generated from enum value: NOTIFICATION_PROVIDER_EMAIL = 2;
+ */
+ EMAIL = 2,
+
+ /**
+ * Google Chat webhook.
+ *
+ * @generated from enum value: NOTIFICATION_PROVIDER_GOOGLE_CHAT = 3;
+ */
+ GOOGLE_CHAT = 3,
+
+ /**
+ * Grafana OnCall webhook.
+ *
+ * @generated from enum value: NOTIFICATION_PROVIDER_GRAFANA_ONCALL = 4;
+ */
+ GRAFANA_ONCALL = 4,
+
+ /**
+ * Ntfy notification service.
+ *
+ * @generated from enum value: NOTIFICATION_PROVIDER_NTFY = 5;
+ */
+ NTFY = 5,
+
+ /**
+ * PagerDuty integration.
+ *
+ * @generated from enum value: NOTIFICATION_PROVIDER_PAGERDUTY = 6;
+ */
+ PAGERDUTY = 6,
+
+ /**
+ * Opsgenie integration.
+ *
+ * @generated from enum value: NOTIFICATION_PROVIDER_OPSGENIE = 7;
+ */
+ OPSGENIE = 7,
+
+ /**
+ * Slack webhook.
+ *
+ * @generated from enum value: NOTIFICATION_PROVIDER_SLACK = 8;
+ */
+ SLACK = 8,
+
+ /**
+ * SMS notification.
+ *
+ * @generated from enum value: NOTIFICATION_PROVIDER_SMS = 9;
+ */
+ SMS = 9,
+
+ /**
+ * Telegram bot.
+ *
+ * @generated from enum value: NOTIFICATION_PROVIDER_TELEGRAM = 10;
+ */
+ TELEGRAM = 10,
+
+ /**
+ * Custom webhook.
+ *
+ * @generated from enum value: NOTIFICATION_PROVIDER_WEBHOOK = 11;
+ */
+ WEBHOOK = 11,
+
+ /**
+ * WhatsApp notification.
+ *
+ * @generated from enum value: NOTIFICATION_PROVIDER_WHATSAPP = 12;
+ */
+ WHATSAPP = 12,
+}
+
+/**
+ * Describes the enum openstatus.notification.v1.NotificationProvider.
+ */
+export const NotificationProviderSchema: GenEnum<
+ NotificationProvider
+> = /*@__PURE__*/
+ enumDesc(file_openstatus_notification_v1_providers, 0);
+
+/**
+ * OpsgenieRegion represents the Opsgenie API region.
+ *
+ * @generated from enum openstatus.notification.v1.OpsgenieRegion
+ */
+export enum OpsgenieRegion {
+ /**
+ * Unspecified region.
+ *
+ * @generated from enum value: OPSGENIE_REGION_UNSPECIFIED = 0;
+ */
+ UNSPECIFIED = 0,
+
+ /**
+ * US region.
+ *
+ * @generated from enum value: OPSGENIE_REGION_US = 1;
+ */
+ US = 1,
+
+ /**
+ * EU region.
+ *
+ * @generated from enum value: OPSGENIE_REGION_EU = 2;
+ */
+ EU = 2,
+}
+
+/**
+ * Describes the enum openstatus.notification.v1.OpsgenieRegion.
+ */
+export const OpsgenieRegionSchema: GenEnum = /*@__PURE__*/
+ enumDesc(file_openstatus_notification_v1_providers, 1);
diff --git a/src/gen/openstatus/notification/v1/service_pb.ts b/src/gen/openstatus/notification/v1/service_pb.ts
new file mode 100644
index 0000000..a9b4bc9
--- /dev/null
+++ b/src/gen/openstatus/notification/v1/service_pb.ts
@@ -0,0 +1,539 @@
+// @generated by protoc-gen-es v2.11.0 with parameter "target=ts,import_extension=ts"
+// @generated from file openstatus/notification/v1/service.proto (package openstatus.notification.v1, syntax proto3)
+/* eslint-disable */
+
+import type {
+ GenFile,
+ GenMessage,
+ GenService,
+} from "@bufbuild/protobuf/codegenv2";
+import {
+ fileDesc,
+ messageDesc,
+ serviceDesc,
+} from "@bufbuild/protobuf/codegenv2";
+import { file_buf_validate_validate } from "../../../buf/validate/validate_pb.ts";
+import type { Notification, NotificationSummary } from "./notification_pb.ts";
+import { file_openstatus_notification_v1_notification } from "./notification_pb.ts";
+import type { NotificationData, NotificationProvider } from "./providers_pb.ts";
+import { file_openstatus_notification_v1_providers } from "./providers_pb.ts";
+import type { Message } from "@bufbuild/protobuf";
+
+/**
+ * Describes the file openstatus/notification/v1/service.proto.
+ */
+export const file_openstatus_notification_v1_service: GenFile = /*@__PURE__*/
+ fileDesc(
+ "CihvcGVuc3RhdHVzL25vdGlmaWNhdGlvbi92MS9zZXJ2aWNlLnByb3RvEhpvcGVuc3RhdHVzLm5vdGlmaWNhdGlvbi52MSLbAQoZQ3JlYXRlTm90aWZpY2F0aW9uUmVxdWVzdBIVCgRuYW1lGAEgASgJQge6SARyAhABEk4KCHByb3ZpZGVyGAIgASgOMjAub3BlbnN0YXR1cy5ub3RpZmljYXRpb24udjEuTm90aWZpY2F0aW9uUHJvdmlkZXJCCrpIB4IBBBABIAASQgoEZGF0YRgDIAEoCzIsLm9wZW5zdGF0dXMubm90aWZpY2F0aW9uLnYxLk5vdGlmaWNhdGlvbkRhdGFCBrpIA8gBARITCgttb25pdG9yX2lkcxgEIAMoCSJcChpDcmVhdGVOb3RpZmljYXRpb25SZXNwb25zZRI+Cgxub3RpZmljYXRpb24YASABKAsyKC5vcGVuc3RhdHVzLm5vdGlmaWNhdGlvbi52MS5Ob3RpZmljYXRpb24iLQoWR2V0Tm90aWZpY2F0aW9uUmVxdWVzdBITCgJpZBgBIAEoCUIHukgEcgIQASJZChdHZXROb3RpZmljYXRpb25SZXNwb25zZRI+Cgxub3RpZmljYXRpb24YASABKAsyKC5vcGVuc3RhdHVzLm5vdGlmaWNhdGlvbi52MS5Ob3RpZmljYXRpb24ibAoYTGlzdE5vdGlmaWNhdGlvbnNSZXF1ZXN0Eh0KBWxpbWl0GAEgASgFQgm6SAYaBBhkKAFIAIgBARIcCgZvZmZzZXQYAiABKAVCB7pIBBoCKABIAYgBAUIICgZfbGltaXRCCQoHX29mZnNldCJ3ChlMaXN0Tm90aWZpY2F0aW9uc1Jlc3BvbnNlEkYKDW5vdGlmaWNhdGlvbnMYASADKAsyLy5vcGVuc3RhdHVzLm5vdGlmaWNhdGlvbi52MS5Ob3RpZmljYXRpb25TdW1tYXJ5EhIKCnRvdGFsX3NpemUYAiABKAUiqwEKGVVwZGF0ZU5vdGlmaWNhdGlvblJlcXVlc3QSEwoCaWQYASABKAlCB7pIBHICEAESEQoEbmFtZRgCIAEoCUgAiAEBEj8KBGRhdGEYAyABKAsyLC5vcGVuc3RhdHVzLm5vdGlmaWNhdGlvbi52MS5Ob3RpZmljYXRpb25EYXRhSAGIAQESEwoLbW9uaXRvcl9pZHMYBCADKAlCBwoFX25hbWVCBwoFX2RhdGEiXAoaVXBkYXRlTm90aWZpY2F0aW9uUmVzcG9uc2USPgoMbm90aWZpY2F0aW9uGAEgASgLMigub3BlbnN0YXR1cy5ub3RpZmljYXRpb24udjEuTm90aWZpY2F0aW9uIjAKGURlbGV0ZU5vdGlmaWNhdGlvblJlcXVlc3QSEwoCaWQYASABKAlCB7pIBHICEAEiLQoaRGVsZXRlTm90aWZpY2F0aW9uUmVzcG9uc2USDwoHc3VjY2VzcxgBIAEoCCKxAQobU2VuZFRlc3ROb3RpZmljYXRpb25SZXF1ZXN0Ek4KCHByb3ZpZGVyGAEgASgOMjAub3BlbnN0YXR1cy5ub3RpZmljYXRpb24udjEuTm90aWZpY2F0aW9uUHJvdmlkZXJCCrpIB4IBBBABIAASQgoEZGF0YRgCIAEoCzIsLm9wZW5zdGF0dXMubm90aWZpY2F0aW9uLnYxLk5vdGlmaWNhdGlvbkRhdGFCBrpIA8gBASJdChxTZW5kVGVzdE5vdGlmaWNhdGlvblJlc3BvbnNlEg8KB3N1Y2Nlc3MYASABKAgSGgoNZXJyb3JfbWVzc2FnZRgCIAEoCUgAiAEBQhAKDl9lcnJvcl9tZXNzYWdlIh8KHUNoZWNrTm90aWZpY2F0aW9uTGltaXRSZXF1ZXN0ImEKHkNoZWNrTm90aWZpY2F0aW9uTGltaXRSZXNwb25zZRIVCg1saW1pdF9yZWFjaGVkGAEgASgIEhUKDWN1cnJlbnRfY291bnQYAiABKAUSEQoJbWF4X2NvdW50GAMgASgFMsQHChNOb3RpZmljYXRpb25TZXJ2aWNlEoMBChJDcmVhdGVOb3RpZmljYXRpb24SNS5vcGVuc3RhdHVzLm5vdGlmaWNhdGlvbi52MS5DcmVhdGVOb3RpZmljYXRpb25SZXF1ZXN0GjYub3BlbnN0YXR1cy5ub3RpZmljYXRpb24udjEuQ3JlYXRlTm90aWZpY2F0aW9uUmVzcG9uc2USegoPR2V0Tm90aWZpY2F0aW9uEjIub3BlbnN0YXR1cy5ub3RpZmljYXRpb24udjEuR2V0Tm90aWZpY2F0aW9uUmVxdWVzdBozLm9wZW5zdGF0dXMubm90aWZpY2F0aW9uLnYxLkdldE5vdGlmaWNhdGlvblJlc3BvbnNlEoABChFMaXN0Tm90aWZpY2F0aW9ucxI0Lm9wZW5zdGF0dXMubm90aWZpY2F0aW9uLnYxLkxpc3ROb3RpZmljYXRpb25zUmVxdWVzdBo1Lm9wZW5zdGF0dXMubm90aWZpY2F0aW9uLnYxLkxpc3ROb3RpZmljYXRpb25zUmVzcG9uc2USgwEKElVwZGF0ZU5vdGlmaWNhdGlvbhI1Lm9wZW5zdGF0dXMubm90aWZpY2F0aW9uLnYxLlVwZGF0ZU5vdGlmaWNhdGlvblJlcXVlc3QaNi5vcGVuc3RhdHVzLm5vdGlmaWNhdGlvbi52MS5VcGRhdGVOb3RpZmljYXRpb25SZXNwb25zZRKDAQoSRGVsZXRlTm90aWZpY2F0aW9uEjUub3BlbnN0YXR1cy5ub3RpZmljYXRpb24udjEuRGVsZXRlTm90aWZpY2F0aW9uUmVxdWVzdBo2Lm9wZW5zdGF0dXMubm90aWZpY2F0aW9uLnYxLkRlbGV0ZU5vdGlmaWNhdGlvblJlc3BvbnNlEokBChRTZW5kVGVzdE5vdGlmaWNhdGlvbhI3Lm9wZW5zdGF0dXMubm90aWZpY2F0aW9uLnYxLlNlbmRUZXN0Tm90aWZpY2F0aW9uUmVxdWVzdBo4Lm9wZW5zdGF0dXMubm90aWZpY2F0aW9uLnYxLlNlbmRUZXN0Tm90aWZpY2F0aW9uUmVzcG9uc2USjwEKFkNoZWNrTm90aWZpY2F0aW9uTGltaXQSOS5vcGVuc3RhdHVzLm5vdGlmaWNhdGlvbi52MS5DaGVja05vdGlmaWNhdGlvbkxpbWl0UmVxdWVzdBo6Lm9wZW5zdGF0dXMubm90aWZpY2F0aW9uLnYxLkNoZWNrTm90aWZpY2F0aW9uTGltaXRSZXNwb25zZUJdWltnaXRodWIuY29tL29wZW5zdGF0dXNocS9vcGVuc3RhdHVzL3BhY2thZ2VzL3Byb3RvL29wZW5zdGF0dXMvbm90aWZpY2F0aW9uL3YxO25vdGlmaWNhdGlvbnYxYgZwcm90bzM",
+ [
+ file_buf_validate_validate,
+ file_openstatus_notification_v1_notification,
+ file_openstatus_notification_v1_providers,
+ ],
+ );
+
+/**
+ * CreateNotificationRequest is the request to create a new notification channel.
+ *
+ * @generated from message openstatus.notification.v1.CreateNotificationRequest
+ */
+export type CreateNotificationRequest =
+ & Message<"openstatus.notification.v1.CreateNotificationRequest">
+ & {
+ /**
+ * Display name for the notification channel.
+ *
+ * @generated from field: string name = 1;
+ */
+ name: string;
+
+ /**
+ * Provider type.
+ *
+ * @generated from field: openstatus.notification.v1.NotificationProvider provider = 2;
+ */
+ provider: NotificationProvider;
+
+ /**
+ * Provider-specific configuration.
+ *
+ * @generated from field: openstatus.notification.v1.NotificationData data = 3;
+ */
+ data?: NotificationData;
+
+ /**
+ * IDs of monitors to associate with this notification.
+ *
+ * @generated from field: repeated string monitor_ids = 4;
+ */
+ monitorIds: string[];
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.CreateNotificationRequest.
+ * Use `create(CreateNotificationRequestSchema)` to create a new message.
+ */
+export const CreateNotificationRequestSchema: GenMessage<
+ CreateNotificationRequest
+> = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_service, 0);
+
+/**
+ * CreateNotificationResponse is the response after creating a notification channel.
+ *
+ * @generated from message openstatus.notification.v1.CreateNotificationResponse
+ */
+export type CreateNotificationResponse =
+ & Message<"openstatus.notification.v1.CreateNotificationResponse">
+ & {
+ /**
+ * The created notification channel.
+ *
+ * @generated from field: openstatus.notification.v1.Notification notification = 1;
+ */
+ notification?: Notification;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.CreateNotificationResponse.
+ * Use `create(CreateNotificationResponseSchema)` to create a new message.
+ */
+export const CreateNotificationResponseSchema: GenMessage<
+ CreateNotificationResponse
+> = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_service, 1);
+
+/**
+ * GetNotificationRequest is the request to get a notification channel.
+ *
+ * @generated from message openstatus.notification.v1.GetNotificationRequest
+ */
+export type GetNotificationRequest =
+ & Message<"openstatus.notification.v1.GetNotificationRequest">
+ & {
+ /**
+ * Notification ID to retrieve (required).
+ *
+ * @generated from field: string id = 1;
+ */
+ id: string;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.GetNotificationRequest.
+ * Use `create(GetNotificationRequestSchema)` to create a new message.
+ */
+export const GetNotificationRequestSchema: GenMessage<
+ GetNotificationRequest
+> = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_service, 2);
+
+/**
+ * GetNotificationResponse is the response containing the notification channel.
+ *
+ * @generated from message openstatus.notification.v1.GetNotificationResponse
+ */
+export type GetNotificationResponse =
+ & Message<"openstatus.notification.v1.GetNotificationResponse">
+ & {
+ /**
+ * The notification channel.
+ *
+ * @generated from field: openstatus.notification.v1.Notification notification = 1;
+ */
+ notification?: Notification;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.GetNotificationResponse.
+ * Use `create(GetNotificationResponseSchema)` to create a new message.
+ */
+export const GetNotificationResponseSchema: GenMessage<
+ GetNotificationResponse
+> = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_service, 3);
+
+/**
+ * ListNotificationsRequest is the request to list notification channels.
+ *
+ * @generated from message openstatus.notification.v1.ListNotificationsRequest
+ */
+export type ListNotificationsRequest =
+ & Message<"openstatus.notification.v1.ListNotificationsRequest">
+ & {
+ /**
+ * Maximum number of notifications to return (1-100, defaults to 50).
+ *
+ * @generated from field: optional int32 limit = 1;
+ */
+ limit?: number;
+
+ /**
+ * Number of notifications to skip for pagination (defaults to 0).
+ *
+ * @generated from field: optional int32 offset = 2;
+ */
+ offset?: number;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.ListNotificationsRequest.
+ * Use `create(ListNotificationsRequestSchema)` to create a new message.
+ */
+export const ListNotificationsRequestSchema: GenMessage<
+ ListNotificationsRequest
+> = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_service, 4);
+
+/**
+ * ListNotificationsResponse is the response containing notification channels.
+ *
+ * @generated from message openstatus.notification.v1.ListNotificationsResponse
+ */
+export type ListNotificationsResponse =
+ & Message<"openstatus.notification.v1.ListNotificationsResponse">
+ & {
+ /**
+ * Notification channel summaries.
+ *
+ * @generated from field: repeated openstatus.notification.v1.NotificationSummary notifications = 1;
+ */
+ notifications: NotificationSummary[];
+
+ /**
+ * Total number of notification channels.
+ *
+ * @generated from field: int32 total_size = 2;
+ */
+ totalSize: number;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.ListNotificationsResponse.
+ * Use `create(ListNotificationsResponseSchema)` to create a new message.
+ */
+export const ListNotificationsResponseSchema: GenMessage<
+ ListNotificationsResponse
+> = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_service, 5);
+
+/**
+ * UpdateNotificationRequest is the request to update a notification channel.
+ *
+ * @generated from message openstatus.notification.v1.UpdateNotificationRequest
+ */
+export type UpdateNotificationRequest =
+ & Message<"openstatus.notification.v1.UpdateNotificationRequest">
+ & {
+ /**
+ * Notification ID to update (required).
+ *
+ * @generated from field: string id = 1;
+ */
+ id: string;
+
+ /**
+ * Updated display name.
+ *
+ * @generated from field: optional string name = 2;
+ */
+ name?: string;
+
+ /**
+ * Updated provider-specific configuration.
+ *
+ * @generated from field: optional openstatus.notification.v1.NotificationData data = 3;
+ */
+ data?: NotificationData;
+
+ /**
+ * Updated monitor IDs to associate.
+ *
+ * @generated from field: repeated string monitor_ids = 4;
+ */
+ monitorIds: string[];
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.UpdateNotificationRequest.
+ * Use `create(UpdateNotificationRequestSchema)` to create a new message.
+ */
+export const UpdateNotificationRequestSchema: GenMessage<
+ UpdateNotificationRequest
+> = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_service, 6);
+
+/**
+ * UpdateNotificationResponse is the response after updating a notification channel.
+ *
+ * @generated from message openstatus.notification.v1.UpdateNotificationResponse
+ */
+export type UpdateNotificationResponse =
+ & Message<"openstatus.notification.v1.UpdateNotificationResponse">
+ & {
+ /**
+ * The updated notification channel.
+ *
+ * @generated from field: openstatus.notification.v1.Notification notification = 1;
+ */
+ notification?: Notification;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.UpdateNotificationResponse.
+ * Use `create(UpdateNotificationResponseSchema)` to create a new message.
+ */
+export const UpdateNotificationResponseSchema: GenMessage<
+ UpdateNotificationResponse
+> = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_service, 7);
+
+/**
+ * DeleteNotificationRequest is the request to delete a notification channel.
+ *
+ * @generated from message openstatus.notification.v1.DeleteNotificationRequest
+ */
+export type DeleteNotificationRequest =
+ & Message<"openstatus.notification.v1.DeleteNotificationRequest">
+ & {
+ /**
+ * Notification ID to delete (required).
+ *
+ * @generated from field: string id = 1;
+ */
+ id: string;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.DeleteNotificationRequest.
+ * Use `create(DeleteNotificationRequestSchema)` to create a new message.
+ */
+export const DeleteNotificationRequestSchema: GenMessage<
+ DeleteNotificationRequest
+> = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_service, 8);
+
+/**
+ * DeleteNotificationResponse is the response after deleting a notification channel.
+ *
+ * @generated from message openstatus.notification.v1.DeleteNotificationResponse
+ */
+export type DeleteNotificationResponse =
+ & Message<"openstatus.notification.v1.DeleteNotificationResponse">
+ & {
+ /**
+ * Whether the deletion was successful.
+ *
+ * @generated from field: bool success = 1;
+ */
+ success: boolean;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.DeleteNotificationResponse.
+ * Use `create(DeleteNotificationResponseSchema)` to create a new message.
+ */
+export const DeleteNotificationResponseSchema: GenMessage<
+ DeleteNotificationResponse
+> = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_service, 9);
+
+/**
+ * SendTestNotificationRequest is the request to send a test notification.
+ *
+ * @generated from message openstatus.notification.v1.SendTestNotificationRequest
+ */
+export type SendTestNotificationRequest =
+ & Message<"openstatus.notification.v1.SendTestNotificationRequest">
+ & {
+ /**
+ * Provider type.
+ *
+ * @generated from field: openstatus.notification.v1.NotificationProvider provider = 1;
+ */
+ provider: NotificationProvider;
+
+ /**
+ * Provider-specific configuration.
+ *
+ * @generated from field: openstatus.notification.v1.NotificationData data = 2;
+ */
+ data?: NotificationData;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.SendTestNotificationRequest.
+ * Use `create(SendTestNotificationRequestSchema)` to create a new message.
+ */
+export const SendTestNotificationRequestSchema: GenMessage<
+ SendTestNotificationRequest
+> = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_service, 10);
+
+/**
+ * SendTestNotificationResponse is the response after sending a test notification.
+ *
+ * @generated from message openstatus.notification.v1.SendTestNotificationResponse
+ */
+export type SendTestNotificationResponse =
+ & Message<"openstatus.notification.v1.SendTestNotificationResponse">
+ & {
+ /**
+ * Whether the test was successful.
+ *
+ * @generated from field: bool success = 1;
+ */
+ success: boolean;
+
+ /**
+ * Optional error message if the test failed.
+ *
+ * @generated from field: optional string error_message = 2;
+ */
+ errorMessage?: string;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.SendTestNotificationResponse.
+ * Use `create(SendTestNotificationResponseSchema)` to create a new message.
+ */
+export const SendTestNotificationResponseSchema: GenMessage<
+ SendTestNotificationResponse
+> = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_service, 11);
+
+/**
+ * CheckNotificationLimitRequest is the request to check notification limits.
+ *
+ * @generated from message openstatus.notification.v1.CheckNotificationLimitRequest
+ */
+export type CheckNotificationLimitRequest =
+ & Message<"openstatus.notification.v1.CheckNotificationLimitRequest">
+ & {};
+
+/**
+ * Describes the message openstatus.notification.v1.CheckNotificationLimitRequest.
+ * Use `create(CheckNotificationLimitRequestSchema)` to create a new message.
+ */
+export const CheckNotificationLimitRequestSchema: GenMessage<
+ CheckNotificationLimitRequest
+> = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_service, 12);
+
+/**
+ * CheckNotificationLimitResponse is the response containing limit information.
+ *
+ * @generated from message openstatus.notification.v1.CheckNotificationLimitResponse
+ */
+export type CheckNotificationLimitResponse =
+ & Message<"openstatus.notification.v1.CheckNotificationLimitResponse">
+ & {
+ /**
+ * Whether the workspace has reached its notification limit.
+ *
+ * @generated from field: bool limit_reached = 1;
+ */
+ limitReached: boolean;
+
+ /**
+ * Current number of notification channels.
+ *
+ * @generated from field: int32 current_count = 2;
+ */
+ currentCount: number;
+
+ /**
+ * Maximum allowed notification channels.
+ *
+ * @generated from field: int32 max_count = 3;
+ */
+ maxCount: number;
+ };
+
+/**
+ * Describes the message openstatus.notification.v1.CheckNotificationLimitResponse.
+ * Use `create(CheckNotificationLimitResponseSchema)` to create a new message.
+ */
+export const CheckNotificationLimitResponseSchema: GenMessage<
+ CheckNotificationLimitResponse
+> = /*@__PURE__*/
+ messageDesc(file_openstatus_notification_v1_service, 13);
+
+/**
+ * NotificationService provides CRUD operations for notification channels.
+ *
+ * @generated from service openstatus.notification.v1.NotificationService
+ */
+export const NotificationService: GenService<{
+ /**
+ * CreateNotification creates a new notification channel.
+ *
+ * @generated from rpc openstatus.notification.v1.NotificationService.CreateNotification
+ */
+ createNotification: {
+ methodKind: "unary";
+ input: typeof CreateNotificationRequestSchema;
+ output: typeof CreateNotificationResponseSchema;
+ };
+ /**
+ * GetNotification retrieves a notification channel by ID.
+ *
+ * @generated from rpc openstatus.notification.v1.NotificationService.GetNotification
+ */
+ getNotification: {
+ methodKind: "unary";
+ input: typeof GetNotificationRequestSchema;
+ output: typeof GetNotificationResponseSchema;
+ };
+ /**
+ * ListNotifications returns a list of notification channels.
+ *
+ * @generated from rpc openstatus.notification.v1.NotificationService.ListNotifications
+ */
+ listNotifications: {
+ methodKind: "unary";
+ input: typeof ListNotificationsRequestSchema;
+ output: typeof ListNotificationsResponseSchema;
+ };
+ /**
+ * UpdateNotification updates an existing notification channel.
+ *
+ * @generated from rpc openstatus.notification.v1.NotificationService.UpdateNotification
+ */
+ updateNotification: {
+ methodKind: "unary";
+ input: typeof UpdateNotificationRequestSchema;
+ output: typeof UpdateNotificationResponseSchema;
+ };
+ /**
+ * DeleteNotification removes a notification channel.
+ *
+ * @generated from rpc openstatus.notification.v1.NotificationService.DeleteNotification
+ */
+ deleteNotification: {
+ methodKind: "unary";
+ input: typeof DeleteNotificationRequestSchema;
+ output: typeof DeleteNotificationResponseSchema;
+ };
+ /**
+ * SendTestNotification sends a test notification to verify configuration.
+ *
+ * @generated from rpc openstatus.notification.v1.NotificationService.SendTestNotification
+ */
+ sendTestNotification: {
+ methodKind: "unary";
+ input: typeof SendTestNotificationRequestSchema;
+ output: typeof SendTestNotificationResponseSchema;
+ };
+ /**
+ * CheckNotificationLimit checks if the workspace has reached its notification limit.
+ *
+ * @generated from rpc openstatus.notification.v1.NotificationService.CheckNotificationLimit
+ */
+ checkNotificationLimit: {
+ methodKind: "unary";
+ input: typeof CheckNotificationLimitRequestSchema;
+ output: typeof CheckNotificationLimitResponseSchema;
+ };
+}> = /*@__PURE__*/
+ serviceDesc(file_openstatus_notification_v1_service, 0);
diff --git a/src/mod.ts b/src/mod.ts
index 2f589b8..e7093a7 100644
--- a/src/mod.ts
+++ b/src/mod.ts
@@ -36,6 +36,7 @@ import { HealthService } from "./gen/openstatus/health/v1/health_pb.ts";
import { StatusReportService } from "./gen/openstatus/status_report/v1/service_pb.ts";
import { StatusPageService } from "./gen/openstatus/status_page/v1/service_pb.ts";
import { MaintenanceService } from "./gen/openstatus/maintenance/v1/service_pb.ts";
+import { NotificationService } from "./gen/openstatus/notification/v1/service_pb.ts";
// Re-export monitor types
export type {
@@ -214,6 +215,53 @@ export type {
UpdateMaintenanceResponse,
} from "./gen/openstatus/maintenance/v1/service_pb.ts";
+// Re-export notification types
+export type {
+ Notification,
+ NotificationSummary,
+} from "./gen/openstatus/notification/v1/notification_pb.ts";
+
+// Re-export notification provider types and data
+export type {
+ DiscordData,
+ EmailData,
+ GoogleChatData,
+ GrafanaOncallData,
+ NotificationData,
+ NtfyData,
+ OpsgenieData,
+ PagerDutyData,
+ SlackData,
+ SmsData,
+ TelegramData,
+ WebhookData,
+ WebhookHeader,
+ WhatsappData,
+} from "./gen/openstatus/notification/v1/providers_pb.ts";
+
+export {
+ NotificationProvider,
+ OpsgenieRegion,
+} from "./gen/openstatus/notification/v1/providers_pb.ts";
+
+// Re-export notification request/response types
+export type {
+ CheckNotificationLimitRequest,
+ CheckNotificationLimitResponse,
+ CreateNotificationRequest,
+ CreateNotificationResponse,
+ DeleteNotificationRequest,
+ DeleteNotificationResponse,
+ GetNotificationRequest,
+ GetNotificationResponse,
+ ListNotificationsRequest,
+ ListNotificationsResponse,
+ SendTestNotificationRequest,
+ SendTestNotificationResponse,
+ UpdateNotificationRequest,
+ UpdateNotificationResponse,
+} from "./gen/openstatus/notification/v1/service_pb.ts";
+
/**
* Default OpenStatus API URL.
*/
@@ -338,6 +386,26 @@ export interface OpenStatusClient {
MaintenanceService: Client;
};
};
+ /**
+ * Notification service namespace (v1).
+ */
+ notification: {
+ v1: {
+ /**
+ * NotificationService provides CRUD operations for notification channels.
+ *
+ * Methods:
+ * - `createNotification` - Create a new notification channel
+ * - `getNotification` - Get a notification channel by ID
+ * - `listNotifications` - List all notification channels
+ * - `updateNotification` - Update a notification channel
+ * - `deleteNotification` - Delete a notification channel
+ * - `sendTestNotification` - Send a test notification
+ * - `checkNotificationLimit` - Check notification limits
+ */
+ NotificationService: Client;
+ };
+ };
}
/**
@@ -390,4 +458,9 @@ export const openstatus: OpenStatusClient = {
MaintenanceService: createClient(MaintenanceService, transport),
},
},
+ notification: {
+ v1: {
+ NotificationService: createClient(NotificationService, transport),
+ },
+ },
};