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

json
{
  "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

bash
# 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

json
{
  "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

bash
curl https://api.getstack.run/v1/notifications/destinations \
  -H "Authorization: Bearer sk_live_op_abc123"

Delete a Destination

DELETE /v1/notifications/destinations/:id

bash
curl -X DELETE https://api.getstack.run/v1/notifications/destinations/ndst_abc123 \
  -H "Authorization: Bearer sk_live_op_abc123"
json
{
  "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

bash
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

bash
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

json
{
  "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.

bash
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

json
{
  "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

bash
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

json
{
  "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.

bash
curl https://api.getstack.run/v1/notifications/channels \
  -H "Authorization: Bearer sk_live_op_abc123"

Update a Channel Rule

PATCH /v1/notifications/channels/:id

json
{
  "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

bash
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

bash
curl -X DELETE https://api.getstack.run/v1/notifications/channels/nch_abc123 \
  -H "Authorization: Bearer sk_live_op_abc123"
json
{
  "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.

json
{
  "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.

json
{
  "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"
      }
    ]
  }
}
STACK — Infrastructure for AI Agents