Skip to main content Skip to content

Notifications

Channel + subscription model for delivering ZopNight events to Slack, Teams, Google Chat, and email, with cost-anomaly, budget, and resource-event subscriptions.

9 min read Last updated: 

The notification system lets you receive alerts when resources are started, stopped, actions fail, overrides fire, retries are exhausted, or budget thresholds are crossed. Notifications can be delivered to Slack, Microsoft Teams, Google Chat, or email.

The system is built around two concepts: channels define where notifications go (a Slack channel, a Teams or Google Chat webhook, or a generic webhook), and subscriptions define which events trigger a notification on a given channel, optionally scoped to a specific resource, resource group, or cloud account.

Supported Channels

ChannelplatformConfiguration fields
SlackslackslackBotToken, slackChannelId, slackSigningSecret
Microsoft TeamsteamswebhookUrl (incoming webhook URL)
Google ChatgchatwebhookUrl (incoming webhook URL)
WebhookwebhookwebhookUrl (any HTTPS endpoint that accepts a POST)

Email is not a channel type. Transactional emails are controlled with Email Preferences.

Legacy Notifications (Deprecated)

List Legacy Notifications

GET /notifications

List all legacy notification configurations.

Create Legacy Notification

POST /notifications

Create a legacy notification configuration.

Slack example
curl -X POST https://api.zop.dev/notifications \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"channel": "slack",
"webhookUrl": "https://hooks.slack.com/services/T00/B00/xxxx",
"notifyOnStart": true,
"notifyOnStop": true,
"notifyOnFailure": true,
"notifyOnOverride": false
}'
Response
{
"data": {
"id": "ntf_abc123",
"channel": "slack",
"webhookUrl": "https://hooks.slack.com/services/T00/B00/xxxx",
"notifyOnStart": true,
"notifyOnStop": true,
"notifyOnFailure": true,
"notifyOnOverride": false,
"createdAt": "2025-01-15T10:30:00Z",
"updatedAt": "2025-01-15T10:30:00Z"
}
}

Update Legacy Notification

PUT /notifications/{notificationID}

Update a legacy notification configuration.

Request
curl -X PUT https://api.zop.dev/notifications/ntf_abc123 \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"notifyOnOverride": true
}'

Delete Legacy Notification

DELETE /notifications/{notificationID}

Remove a legacy notification configuration.

Notification Channels

Channels represent a delivery destination such as a Slack channel, a Teams channel, or a webhook. Create a channel first, then attach subscriptions to it.

List Channels

GET /notifications/channels

List all notification channels for the organization.

Request
curl https://api.zop.dev/notifications/channels \
-H "Authorization: Bearer <token>"

Returns {"data": [...]} with one entry per channel. Each entry carries the channel’s id, which you pass as channelId when creating subscriptions.

Create Channel

POST /notifications/channels

Create a new notification channel.

Slack example
curl -X POST https://api.zop.dev/notifications/channels \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Engineering Alerts",
"platform": "slack",
"slackBotToken": "xoxb-...",
"slackChannelId": "C0123456789",
"slackSigningSecret": "..."
}'
Teams example
curl -X POST https://api.zop.dev/notifications/channels \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Infra Alerts",
"platform": "teams",
"webhookUrl": "https://example.webhook.office.com/webhookb2/..."
}'

Update Channel

PUT /notifications/channels/{channelID}

Update an existing notification channel. Takes the same fields as create.

Request
curl -X PUT https://api.zop.dev/notifications/channels/<channelId> \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Infra Alerts",
"platform": "teams",
"webhookUrl": "https://example.webhook.office.com/webhookb2/new..."
}'

Delete Channel

DELETE /notifications/channels/{channelID}

Delete a notification channel and all its subscriptions.

Request
curl -X DELETE https://api.zop.dev/notifications/channels/<channelId> \
-H "Authorization: Bearer <token>"

Notification Subscriptions

Subscriptions bind a channel to one or more event types. You can scope a subscription to the entire organization, a specific cloud account, a resource group, or an individual resource.

Event Types

The table below lists common event keys. It is not the complete catalogue: more keys exist (for example remediation approvals, billing sync, and override expiry). GET /notifications/event-types returns the authoritative list.

Event KeyDisplay NameTriggered When
resource.startedResource StartedA resource is successfully started by the executor
resource.stoppedResource StoppedA resource is successfully stopped by the executor
resource.failedAction FailedA start or stop action fails during execution
resource.overrideOverride TriggeredAn override is created for a resource or group
resource.retry_exhaustedRetry ExhaustedAll retry attempts for an action have been exhausted
budget.warningBudget WarningSpending approaches a configured budget threshold
budget.exceededBudget ExceededSpending exceeds a configured budget threshold
cost.anomaly.warningCost Anomaly (Warning)Org-level cost exceeds 7-day baseline by 30%
cost.anomaly.criticalCost Anomaly (Critical)Org-level cost exceeds 7-day baseline by 100%
cost.anomaly.emergencyCost Anomaly (Emergency)Org-level cost exceeds 7-day baseline by 500%
cost.anomaly.cloud_account.*Cloud Account AnomalyA cloud account’s cost spikes beyond baseline, each * expands to warning, critical, emergency
cost.anomaly.resource_group.*Resource Group AnomalyA resource group’s cost spikes beyond baseline, each * expands to warning, critical, emergency
cost.anomaly.resource.*Resource AnomalyA single resource’s cost spikes beyond baseline, each * expands to warning, critical, emergency
cost.anomaly.team.*Team AnomalyA team’s attributed cost spikes beyond baseline, each * expands to warning, critical, emergency

Scope Types

Scope TypeScope IDDescription
org(none)Matches all events across the organization
cloud_accountCloud account IDMatches events for resources in a specific cloud account
resource_groupResource group IDMatches events for resources in a specific group
resourceResource UIDMatches events for a single resource
teamTeam IDMatches events for resources attributed to a specific team

List Subscriptions

GET /notifications/subscriptions

List all notification subscriptions.

Request
curl https://api.zop.dev/notifications/subscriptions \
-H "Authorization: Bearer <token>"
Response
{
"data": [
{
"id": "sub_x1y2z3",
"channelId": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a",
"eventType": "resource.stopped",
"scopeType": "org",
"scopeId": "",
"enabled": true,
"createdAt": "2025-06-01T09:15:00Z",
"updatedAt": "2025-06-01T09:15:00Z"
}
]
}

Create Subscription

POST /notifications/subscriptions

Subscribe a channel to an event type.

Request
curl -X POST https://api.zop.dev/notifications/subscriptions \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"channelId": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a",
"eventType": "resource.failed",
"scopeType": "cloud_account",
"scopeId": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"enabled": true
}'
Response
{
"data": {
"id": "sub_f4g5h6",
"channelId": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a",
"eventType": "resource.failed",
"scopeType": "cloud_account",
"scopeId": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"enabled": true,
"createdAt": "2025-06-02T11:00:00Z",
"updatedAt": "2025-06-02T11:00:00Z"
}
}

Update Subscription

PUT /notifications/subscriptions/{subID}

Update an existing subscription.

Request
curl -X PUT https://api.zop.dev/notifications/subscriptions/sub_f4g5h6 \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"enabled": false
}'

Delete Subscription

DELETE /notifications/subscriptions/{subID}

Delete a notification subscription.

Request
curl -X DELETE https://api.zop.dev/notifications/subscriptions/sub_f4g5h6 \
-H "Authorization: Bearer <token>"

Bulk Create / Update Subscriptions

POST /notifications/subscriptions/bulk

Create or update multiple subscriptions in a single request. Existing subscriptions matched by channelId + eventType + scope are updated; otherwise new ones are created.

Request
curl -X POST https://api.zop.dev/notifications/subscriptions/bulk \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"subscriptions": [
{
"channelId": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a",
"eventType": "resource.started",
"scopeType": "org",
"scopeId": "",
"enabled": true
},
{
"channelId": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a",
"eventType": "resource.stopped",
"scopeType": "org",
"scopeId": "",
"enabled": true
},
{
"channelId": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a",
"eventType": "budget.exceeded",
"scopeType": "cloud_account",
"scopeId": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"enabled": true
}
]
}'
Response
{
"data": { "status": "ok" }
}

Event Types

GET /notifications/event-types

List all available event types that can be used in subscriptions. This is the authoritative catalogue.

Request
curl https://api.zop.dev/notifications/event-types \
-H "Authorization: Bearer <token>"
Response (truncated)
{
"data": [
{ "key": "resource.started", "label": "Resource Started", "category": "resource" },
{ "key": "resource.failed", "label": "Action Failed", "category": "resource" },
{ "key": "budget.exceeded", "label": "Budget Exceeded", "category": "budget" },
{ "key": "cost.anomaly.critical", "label": "Cost Anomaly (Critical)", "category": "cost_anomaly" }
]
}

Email Preferences

Email preferences are organization-level opt-outs for ZopNight’s transactional emails, one per event key. They are independent of channel subscriptions.

List Email Preferences

GET /notifications/email-preferences

List the email preferences for every event key.

Request
curl https://api.zop.dev/notifications/email-preferences \
-H "Authorization: Bearer <token>"

Update Email Preference

PUT /notifications/email-preferences/{eventKey}

Enable or disable emails for a specific event key.

Request
curl -X PUT https://api.zop.dev/notifications/email-preferences/resource.failed \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"enabled": false
}'
Response
{
"data": {
"orgId": "3f6c2a9e-8b1d-4c7e-9f2a-1d5e6b7c8a90",
"eventKey": "resource.failed",
"enabled": false
}
}

Share Recommendation

Send a cost-saving recommendation to one or more notification channels so that team members who may not use the dashboard directly can act on it.

POST /notifications/share/recommendation/{recID}

Share a recommendation by email or through a notification channel.

Request
curl -X POST https://api.zop.dev/notifications/share/recommendation/<recId> \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"channel": "slack",
"targets": ["6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a"],
"message": "This EC2 instance has been idle for 14 days. Consider stopping or downsizing."
}'

channel is email, slack, teams, gchat or webhook. targets holds email addresses for email, or channel IDs otherwise. message is optional.

Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·