Notifications
Channel + subscription model for delivering ZopNight events to Slack, Teams, Google Chat, and email — with cost-anomaly, budget, and resource-event subscriptions.
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 webhook, an email address, etc.), 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
| Channel | Type ID | Configuration |
|---|---|---|
| Slack | slack | Incoming webhook URL |
| Microsoft Teams | teams | Incoming webhook URL |
| Google Chat | gchat | Incoming webhook URL |
email | Recipient email address |
Legacy Notifications (Deprecated)
List Legacy Notifications
/notificationsList all legacy notification configurations.
Create Legacy Notification
/notificationsCreate a legacy notification configuration.
curl -X POST https://zopnight.com/api/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
}'{
"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
/notifications/{notificationID}Update a legacy notification configuration.
curl -X PUT https://zopnight.com/api/notifications/ntf_abc123 \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"notifyOnOverride": true
}'Delete Legacy Notification
/notifications/{notificationID}Remove a legacy notification configuration.
Notification Channels
Channels represent a delivery destination such as a Slack workspace, a Teams channel, or an email address. Create a channel first, then attach subscriptions to it.
List Channels
/notifications/channelsList all notification channels for the organization.
curl https://zopnight.com/api/notifications/channels \
-H "Authorization: Bearer <token>"{
"data": [
{
"id": "ch_s1a2b3",
"type": "slack",
"name": "Engineering Alerts",
"config": {
"webhookURL": "https://hooks.slack.com/services/T00/B00/xxxx"
},
"createdAt": "2025-06-01T09:00:00Z",
"updatedAt": "2025-06-01T09:00:00Z"
}
]
}Create Channel
/notifications/channelsCreate a new notification channel.
curl -X POST https://zopnight.com/api/notifications/channels \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"type": "slack",
"name": "Engineering Alerts",
"config": {
"webhookURL": "https://hooks.slack.com/services/T00/B00/xxxx"
}
}'{
"data": {
"id": "ch_s1a2b3",
"type": "slack",
"name": "Engineering Alerts",
"config": {
"webhookURL": "https://hooks.slack.com/services/T00/B00/xxxx"
},
"createdAt": "2025-06-01T09:00:00Z",
"updatedAt": "2025-06-01T09:00:00Z"
}
}Update Channel
/notifications/channels/{channelID}Update an existing notification channel.
curl -X PUT https://zopnight.com/api/notifications/channels/ch_s1a2b3 \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Infra Alerts",
"config": {
"webhookURL": "https://hooks.slack.com/services/T00/B00/newtoken"
}
}'Delete Channel
/notifications/channels/{channelID}Delete a notification channel and all its subscriptions.
curl -X DELETE https://zopnight.com/api/notifications/channels/ch_s1a2b3 \
-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
| Event Key | Display Name | Triggered When |
|---|---|---|
resource.started | Resource Started | A resource is successfully started by the executor |
resource.stopped | Resource Stopped | A resource is successfully stopped by the executor |
resource.failed | Action Failed | A start or stop action fails during execution |
resource.override | Override Triggered | An override is created for a resource or group |
resource.retry_exhausted | Retry Exhausted | All retry attempts for an action have been exhausted |
budget.warning | Budget Warning | Spending approaches a configured budget threshold |
budget.exceeded | Budget Exceeded | Spending exceeds a configured budget threshold |
cost.anomaly.warning | Cost Anomaly (Warning) | Org-level cost exceeds 7-day baseline by 30% |
cost.anomaly.critical | Cost Anomaly (Critical) | Org-level cost exceeds 7-day baseline by 100% |
cost.anomaly.emergency | Cost Anomaly (Emergency) | Org-level cost exceeds 7-day baseline by 500% |
cost.anomaly.cloud_account.* | Cloud Account Anomaly | A cloud account's cost spikes beyond baseline — each * expands to warning, critical, emergency |
cost.anomaly.resource_group.* | Resource Group Anomaly | A resource group's cost spikes beyond baseline — each * expands to warning, critical, emergency |
cost.anomaly.resource.* | Resource Anomaly | A single resource's cost spikes beyond baseline — each * expands to warning, critical, emergency |
cost.anomaly.team.* | Team Anomaly | A team's attributed cost spikes beyond baseline — each * expands to warning, critical, emergency |
Scope Types
| Scope Type | Scope ID | Description |
|---|---|---|
org | (none) | Matches all events across the organization |
cloud_account | Cloud account ID | Matches events for resources in a specific cloud account |
resource_group | Resource group ID | Matches events for resources in a specific group |
resource | Resource UID | Matches events for a single resource |
team | Team ID | Matches events for resources attributed to a specific team |
List Subscriptions
/notifications/subscriptionsList all notification subscriptions.
curl https://zopnight.com/api/notifications/subscriptions \
-H "Authorization: Bearer <token>"{
"data": [
{
"id": "sub_x1y2z3",
"channelID": "ch_s1a2b3",
"eventType": "resource.stopped",
"scopeType": "org",
"scopeID": "",
"enabled": true,
"createdAt": "2025-06-01T09:15:00Z",
"updatedAt": "2025-06-01T09:15:00Z"
}
]
}Create Subscription
/notifications/subscriptionsSubscribe a channel to an event type.
curl -X POST https://zopnight.com/api/notifications/subscriptions \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"channelID": "ch_s1a2b3",
"eventType": "resource.failed",
"scopeType": "cloud_account",
"scopeID": "acc_prod_aws",
"enabled": true
}'{
"data": {
"id": "sub_f4g5h6",
"channelID": "ch_s1a2b3",
"eventType": "resource.failed",
"scopeType": "cloud_account",
"scopeID": "acc_prod_aws",
"enabled": true,
"createdAt": "2025-06-02T11:00:00Z",
"updatedAt": "2025-06-02T11:00:00Z"
}
}Update Subscription
/notifications/subscriptions/{subID}Update an existing subscription.
curl -X PUT https://zopnight.com/api/notifications/subscriptions/sub_f4g5h6 \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"enabled": false
}'Delete Subscription
/notifications/subscriptions/{subID}Delete a notification subscription.
curl -X DELETE https://zopnight.com/api/notifications/subscriptions/sub_f4g5h6 \
-H "Authorization: Bearer <token>"Bulk Create / Update Subscriptions
/notifications/subscriptions/bulkCreate or update multiple subscriptions in a single request. Existing subscriptions matched by channelID + eventType + scope are updated; otherwise new ones are created.
curl -X POST https://zopnight.com/api/notifications/subscriptions/bulk \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"subscriptions": [
{
"channelID": "ch_s1a2b3",
"eventType": "resource.started",
"scopeType": "org",
"scopeID": "",
"enabled": true
},
{
"channelID": "ch_s1a2b3",
"eventType": "resource.stopped",
"scopeType": "org",
"scopeID": "",
"enabled": true
},
{
"channelID": "ch_s1a2b3",
"eventType": "budget.exceeded",
"scopeType": "cloud_account",
"scopeID": "acc_prod_aws",
"enabled": true
}
]
}'{
"data": {
"created": 2,
"updated": 1
}
}Event Types
/notifications/event-typesList all available event types that can be used in subscriptions.
curl https://zopnight.com/api/notifications/event-types \
-H "Authorization: Bearer <token>"{
"data": [
{ "key": "resource.started", "name": "Resource Started", "category": "resource" },
{ "key": "resource.stopped", "name": "Resource Stopped", "category": "resource" },
{ "key": "resource.failed", "name": "Action Failed", "category": "resource" },
{ "key": "resource.override", "name": "Override Triggered", "category": "resource" },
{ "key": "resource.retry_exhausted", "name": "Retry Exhausted", "category": "resource" },
{ "key": "budget.warning", "name": "Budget Warning", "category": "budget" },
{ "key": "budget.exceeded", "name": "Budget Exceeded", "category": "budget" },
{ "key": "cost.anomaly.warning", "name": "Cost Anomaly (Warning)", "category": "cost_anomaly" },
{ "key": "cost.anomaly.critical", "name": "Cost Anomaly (Critical)", "category": "cost_anomaly" },
{ "key": "cost.anomaly.emergency", "name": "Cost Anomaly (Emergency)", "category": "cost_anomaly" },
{ "key": "cost.anomaly.cloud_account.warning", "name": "Cloud Account Anomaly (Warning)", "category": "cost_anomaly" },
{ "key": "cost.anomaly.cloud_account.critical", "name": "Cloud Account Anomaly (Critical)", "category": "cost_anomaly" },
{ "key": "cost.anomaly.cloud_account.emergency", "name": "Cloud Account Anomaly (Emergency)", "category": "cost_anomaly" },
{ "key": "cost.anomaly.resource_group.warning", "name": "Resource Group Anomaly (Warning)", "category": "cost_anomaly" },
{ "key": "cost.anomaly.resource_group.critical", "name": "Resource Group Anomaly (Critical)", "category": "cost_anomaly" },
{ "key": "cost.anomaly.resource_group.emergency", "name": "Resource Group Anomaly (Emergency)", "category": "cost_anomaly" },
{ "key": "cost.anomaly.resource.warning", "name": "Resource Anomaly (Warning)", "category": "cost_anomaly" },
{ "key": "cost.anomaly.resource.critical", "name": "Resource Anomaly (Critical)", "category": "cost_anomaly" },
{ "key": "cost.anomaly.resource.emergency", "name": "Resource Anomaly (Emergency)", "category": "cost_anomaly" },
{ "key": "cost.anomaly.team.warning", "name": "Team Anomaly (Warning)", "category": "cost_anomaly" },
{ "key": "cost.anomaly.team.critical", "name": "Team Anomaly (Critical)", "category": "cost_anomaly" },
{ "key": "cost.anomaly.team.emergency", "name": "Team Anomaly (Emergency)", "category": "cost_anomaly" }
]
}Email Preferences
Email preferences control per-event-type opt-in/opt-out for the authenticated user's email notifications. These are independent of channel subscriptions and apply only to the built-in email delivery.
Get Email Preference
/notifications/email-preferences/{eventKey}Get the email preference for a specific event type.
curl https://zopnight.com/api/notifications/email-preferences/resource.failed \
-H "Authorization: Bearer <token>"{
"data": {
"eventKey": "resource.failed",
"enabled": true,
"updatedAt": "2025-06-01T12:00:00Z"
}
}Update Email Preference
/notifications/email-preferences/{eventKey}Enable or disable email notifications for a specific event type.
curl -X PUT https://zopnight.com/api/notifications/email-preferences/resource.failed \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"enabled": false
}'{
"data": {
"eventKey": "resource.failed",
"enabled": false,
"updatedAt": "2025-06-03T08:45:00Z"
}
}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.
/notifications/share/recommendation/{recID}Share a recommendation via configured notification channels.
curl -X POST https://zopnight.com/api/notifications/share/recommendation/rec_abc123 \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"channelIDs": ["ch_s1a2b3"],
"message": "This EC2 instance has been idle for 14 days. Consider stopping or downsizing."
}'{
"data": {
"sent": 1,
"failed": 0
}
}