Notifications API
The Notifications API lets you configure how and when STACK alerts you about events in your organization. The system has two concepts: destinations (where to send) and channels (rules that map events to destinations). Set up and verify destinations first, then create channel rules to route events.
All endpoints require an Authorization: Bearer sk_live_... header with a valid operator API key or team member API key.
Notification Destinations
A destination is a verified address where STACK can send notifications. Three channel types are supported: email, sms, and webhook. Destinations must be verified before they can receive notifications.
Add a Destination
POST /v1/notifications/destinations
{
"channel_type": "email",
"destination": "alerts@example.com"
}- channel_type (string, required) — One of "email", "sms", or "webhook".
- destination (string, required) — The email address, phone number, or webhook URL.
Request Examples
# Email destination
curl -X POST https://api.getstack.run/v1/notifications/destinations \
-H "Authorization: Bearer sk_live_op_abc123" \
-H "Content-Type: application/json" \
-d '{
"channel_type": "email",
"destination": "alerts@example.com"
}'
# Webhook destination
curl -X POST https://api.getstack.run/v1/notifications/destinations \
-H "Authorization: Bearer sk_live_op_abc123" \
-H "Content-Type: application/json" \
-d '{
"channel_type": "webhook",
"destination": "https://example.com/hooks/stack"
}'
# SMS destination
curl -X POST https://api.getstack.run/v1/notifications/destinations \
-H "Authorization: Bearer sk_live_op_abc123" \
-H "Content-Type: application/json" \
-d '{
"channel_type": "sms",
"destination": "+14155551234"
}'Response — 201 Created
{
"id": "ndst_abc123",
"operator_id": "op_abc123",
"channel_type": "email",
"destination": "alerts@example.com",
"verified": false,
"webhook_secret": null,
"created_at": "2026-04-15T10:00:00.000Z"
}Email destinations are auto-verified if the email matches the operator's registered email. Webhook destinations are auto-verified on creation (they receive a webhook_secret for signature verification). SMS and other email destinations require the two-step verification flow.
Error Responses
- 401 Unauthorized — Missing or invalid Authorization header.
- 409 Conflict — A destination with the same channel_type and destination already exists.
List Destinations
GET /v1/notifications/destinations
curl https://api.getstack.run/v1/notifications/destinations \
-H "Authorization: Bearer sk_live_op_abc123"Delete a Destination
DELETE /v1/notifications/destinations/:id
curl -X DELETE https://api.getstack.run/v1/notifications/destinations/ndst_abc123 \
-H "Authorization: Bearer sk_live_op_abc123"{
"deleted": true
}Verify a Destination
Verification is a two-step process for email and SMS destinations. First, request a verification code. Then submit the code to complete verification.
Step 1: Send Verification Code
POST /v1/notifications/destinations/:id/send-code
curl -X POST https://api.getstack.run/v1/notifications/destinations/ndst_abc123/send-code \
-H "Authorization: Bearer sk_live_op_abc123"Step 2: Submit Verification Code
POST /v1/notifications/destinations/:id/verify
curl -X POST https://api.getstack.run/v1/notifications/destinations/ndst_abc123/verify \
-H "Authorization: Bearer sk_live_op_abc123" \
-H "Content-Type: application/json" \
-d '{
"code": "123456"
}'Response — 200 OK
{
"verified": true
}Error Response — 400 Bad Request
If the code is invalid or expired, the response includes an error message.
Destinations must be verified before they can be used in notification channel rules. Creating a rule with unverified destinations returns a 400 error.
Test a Destination
POST /v1/notifications/destinations/:id/test
Send a test notification to a verified destination to confirm it works correctly.
curl -X POST https://api.getstack.run/v1/notifications/destinations/ndst_abc123/test \
-H "Authorization: Bearer sk_live_op_abc123"Notification Channels (Rules)
Channels are rules that map event types to one or more notification destinations. When a matching event fires, STACK delivers a notification to all destinations on the rule.
Create a Channel Rule
POST /v1/notifications/channels
{
"destination_ids": ["ndst_abc123", "ndst_def456"],
"events": ["passport.flagged", "agent.blocked"],
"min_severity": "warning"
}- destination_id (string, optional) — Single destination ID. Use either this or destination_ids.
- destination_ids (string[], optional) — Array of destination IDs for multi-destination rules. At least one destination is required.
- events (string[], required) — Array of event types to match. At least one required.
- min_severity (string, optional) — Minimum severity to trigger: "info", "warning", or "critical". Default: "warning".
Request Example
curl -X POST https://api.getstack.run/v1/notifications/channels \
-H "Authorization: Bearer sk_live_op_abc123" \
-H "Content-Type: application/json" \
-d '{
"destination_ids": ["ndst_abc123"],
"events": ["passport.flagged", "passport.blocked", "agent.blocked"],
"min_severity": "warning"
}'Response — 201 Created
{
"id": "nch_abc123",
"operator_id": "op_abc123",
"channel_type": "email",
"destination": "alerts@example.com",
"destination_id": "ndst_abc123",
"destination_ids": ["ndst_abc123"],
"events": ["passport.flagged", "passport.blocked", "agent.blocked"],
"min_severity": "warning",
"verified": true,
"active": true,
"created_at": "2026-04-15T10:10:00.000Z"
}Error Responses
- 400 Bad Request — Missing events, unverified destination, or no destination specified.
- 401 Unauthorized — Missing or invalid Authorization header.
- 404 Not Found — Destination ID does not exist or belongs to a different operator.
List Channel Rules
GET /v1/notifications/channels
Returns all channel rules with enriched delivery_methods array containing the full destination objects.
curl https://api.getstack.run/v1/notifications/channels \
-H "Authorization: Bearer sk_live_op_abc123"Update a Channel Rule
PATCH /v1/notifications/channels/:id
{
"destination_ids": ["ndst_abc123", "ndst_ghi789"],
"events": ["passport.flagged", "passport.blocked", "agent.blocked", "passport.missed_checkout"],
"min_severity": "info"
}- destination_ids (string[], optional) — Updated list of destination IDs. All must be verified.
- events (string[], optional) — Updated list of event types.
- min_severity (string, optional) — Updated minimum severity.
Request Example
curl -X PATCH https://api.getstack.run/v1/notifications/channels/nch_abc123 \
-H "Authorization: Bearer sk_live_op_abc123" \
-H "Content-Type: application/json" \
-d '{
"events": ["passport.flagged", "agent.blocked"],
"min_severity": "critical"
}'Delete a Channel Rule
DELETE /v1/notifications/channels/:id
curl -X DELETE https://api.getstack.run/v1/notifications/channels/nch_abc123 \
-H "Authorization: Bearer sk_live_op_abc123"{
"deleted": true
}Supported Event Types
These are the event types you can use in notification channel rules:
- passport.flagged — A passport checkout raised warning or critical flags during review.
- passport.blocked — An agent was blocked from passport issuance due to accountability violations.
- agent.blocked — An agent was blocked (overlaps with passport.blocked for backward compatibility).
- passport.missed_checkout — A passport expired without the agent submitting a checkout report.
When creating rules without specifying events, the system defaults to all four event types: passport.flagged, passport.blocked, agent.blocked, and passport.missed_checkout.
Legacy Channel Creation
For backward compatibility, you can also create channels with inline destination details instead of referencing a destination ID. This creates an unverified channel (unless the type is webhook) that must be verified separately.
{
"channel_type": "email",
"destination": "alerts@example.com",
"events": ["passport.flagged"],
"min_severity": "warning"
}- channel_type (string, required) — "email", "sms", or "webhook".
- destination (string, required) — The email, phone number, or webhook URL.
- events (string[], optional) — Event types to match. Defaults to all events.
- min_severity (string, optional) — Minimum severity. Default: "warning".
- destination_id (string, optional) — Reference to a verified destination.
Legacy Channel Verification
Legacy channels without a destination_id can be verified directly using the same send-code and verify flow:
- POST /v1/notifications/channels/:id/send-code — Send verification code.
- POST /v1/notifications/channels/:id/verify — Submit code to verify.
- POST /v1/notifications/channels/:id/test — Send test notification.
Webhook Payload Format
When a rule fires and delivers to a webhook destination, STACK sends a POST request. Webhook destinations receive a webhook_secret on creation that can be used to verify the payload signature.
{
"event_type": "passport.flagged",
"timestamp": "2026-04-15T10:05:00.000Z",
"operator_id": "op_abc123",
"severity": "warning",
"data": {
"jti": "ppt_abc123",
"agent_id": "agt_xyz",
"flags": [
{
"type": "undeclared_service",
"severity": "warning",
"message": "Agent accessed slack but did not declare it in intent"
}
]
}
}