Notifier SDK Usage Examples (rules, incidents, quiet hours)
Worked examples for driving the Notifier API from generated SDK clients — creating notification rules, acknowledging incidents, and configuring quiet hours. Each example is shown in cURL, TypeScript, and Python, and is kept air-gap friendly and deterministic.
Audience: SDK integrators and automation authors building against the Notifier API.
For the platform-wide conventions these examples assume (auth, tenancy, pagination, error envelope), see the API Overview.
Prerequisites
- Token with scopes:
notify.viewerfor reads,notify.operatorfor writes (tenant-scoped). These scopes exist in the canonical catalog (StellaOps.Auth.Abstractions/StellaOpsScopes.cs) and are enforced by the service (NotifierPolicies). - Tenant header:
X-StellaOps-TenantId: <tenant-id>. - Base URL:
https://api.stellaops.example.com. - OpenAPI document:
/.well-known/openapi(served by Notifier; see OpenAPI Discovery).
API version note. Rules, templates, incidents, channels, deliveries, and quiet-hours are served under
/api/v2/notify/*by the currentStellaOps.Notifier.WebService(see itsProgram.csroute registrations andNotifyApiEndpoints.MapNotifyApiV2). The legacy/api/v1/notify/*surface is deprecated (the service emitsDeprecation: trueandSunset: Tue, 31 Mar 2026 00:00:00 GMTfor any/api/v1request) and is retired for these resources. The remaining live/api/v1/notify/*routes are limited to event intake / approval flows (/pack-approvals,/pack-approvals/{packId}/ack,/attestation-events,/risk-events) plus/api/v1/ack/{token}. The legacyStellaOps.Notify.WebServicestill serves rules/channels/templates/deliveries under a configurable base path defaulting to/api/v1/notify, but new integrations should target/api/v2/notify/*. The examples below use v2.
Rules CRUD
cURL
# Create rule
curl -X POST "$BASE/api/v2/notify/rules" \
-H "Authorization: Bearer $TOKEN" \
-H "X-StellaOps-TenantId: acme-prod" \
-H "Content-Type: application/json" \
-d '{
"ruleId": "rule-attest-fail",
"tenantId": "acme-prod",
"name": "Attestation failures to SOC",
"match": { "eventKinds": ["attestor.verification.failed"] },
"actions": [{
"actionId": "act-soc",
"channel": "chn-soc-webhook",
"template": "tmpl-attest-verify-fail",
"digest": "instant"
}]
}'
# List rules (paginated)
curl -H "Authorization: Bearer $TOKEN" \
-H "X-StellaOps-TenantId: acme-prod" \
"$BASE/api/v2/notify/rules?pageSize=50"
TypeScript (OpenAPI-generated client)
import { RulesApi, Configuration } from "./generated/notify-client";
const api = new RulesApi(new Configuration({
basePath: process.env.BASE,
accessToken: process.env.TOKEN
}));
await api.createRule({
xStellaOpsTenant: "acme-prod",
notifyRule: {
ruleId: "rule-attest-fail",
tenantId: "acme-prod",
name: "Attestation failures to SOC",
match: { eventKinds: ["attestor.verification.failed"] },
actions: [{
actionId: "act-soc",
channel: "chn-soc-webhook",
template: "tmpl-attest-verify-fail",
digest: "instant"
}]
}
});
Python (OpenAPI-generated client)
from notify_client import RulesApi, Configuration, ApiClient
config = Configuration(host=BASE, access_token=TOKEN)
with ApiClient(config) as client:
api = RulesApi(client)
api.create_rule(
x_stella_ops_tenant="acme-prod",
notify_rule={
"ruleId": "rule-attest-fail",
"tenantId": "acme-prod",
"name": "Attestation failures to SOC",
"match": {"eventKinds": ["attestor.verification.failed"]},
"actions": [{
"actionId": "act-soc",
"channel": "chn-soc-webhook",
"template": "tmpl-attest-verify-fail",
"digest": "instant"
}]
}
)
Incident acknowledge
cURL
curl -X POST "$BASE/api/v2/notify/incidents/inc-telemetry/ack" \
-H "Authorization: Bearer $TOKEN" \
-H "X-StellaOps-TenantId: acme-prod" \
-H "Content-Type: application/json" \
-d '{"ackToken":"<dsse-token>"}' \
-i
TypeScript
import { IncidentsApi } from "./generated/notify-client";
await new IncidentsApi(config).ackIncident({
incidentId: "inc-telemetry",
xStellaOpsTenant: "acme-prod",
inlineObject: { ackToken: process.env.ACK_TOKEN }
});
Quiet hours
cURL
# Quiet-hours schedules are upserted by id with PUT /api/v2/notify/quiet-hours/{scheduleId}.
# List with GET /api/v2/notify/quiet-hours.
curl -X PUT "$BASE/api/v2/notify/quiet-hours/qh-default" \
-H "Authorization: Bearer $TOKEN" \
-H "X-StellaOps-TenantId: acme-prod" \
-H "Content-Type: application/json" \
-d '{
"quietHoursId": "qh-default",
"windows": [{
"timezone": "UTC",
"days": ["Mon","Tue","Wed","Thu","Fri"],
"start": "22:00",
"end": "06:00"
}],
"exemptions": [{
"eventKinds": ["attestor.verification.failed"],
"reason": "Always alert on attestation failures"
}]
}'
Smoke-test recipe (SDK CI)
- Generate client from
/.well-known/openapi(ts/python/go) with deterministic options. - Run:
- create rule → list rules → delete rule.
- set quiet hours → get quiet hours.
- ack incident with dummy token (expect 2xx or validation error envelope).
- Assert deterministic headers:
X-OpenAPI-Scope=notify,ETagstable for identical spec bytes.
