- In-app inbox - the bell icon in the top nav. Free, per-user, automatic.
- Personal email - opt-in toggles per event type, scoped to the events that concern you (e.g.
cluster.disconnectedfor a cluster you own). - Org destinations - Slack and HMAC-signed webhooks for org-wide subscriptions. Owner-only.
Event kinds
Members don’t see billing events in their inbox - that lane is owner-scoped.
The cluster, member, and billing events above are built-in and routed by per-destination kind filters. Issue alerts work differently - they’re driven by notification rules you define over the Issues stream, with their own filtering, timing, and a durable Alerts history. The
issue.opened / issue.resolved rows here are just where those alerts land as inbox and destination deliveries.
In-app inbox
The bell icon shows unread count. Click it to open the inbox tray. Read state is per-user-per-event: marking read on your laptop syncs across your sessions but doesn’t affect anyone else. The inbox doesn’t expire on its own today; deletion is manual. (Archive / snooze is on the roadmap.)Personal email preferences
Settings → Preferences → Notifications.Org destinations (Slack / webhook)
Settings → Organization → Notifications → Add destination (owner-only).Slack
We use Slack’s incoming-webhook model. Click Add destination → Slack, paste a Slack webhook URL, and pick which event kinds the destination subscribes to. Test with the Send test message button. The webhook URL is sealed at rest (NaClsecretbox, key from the control plane’s HUB_NOTIFY_KEY env var). Owners only see a redacted view (https://hooks.slack.com/services/T***/B***/...) after creation.
Generic webhook
For anything that isn’t Slack - PagerDuty event API, Statuspage, your own incident tool. Click Add destination → Webhook:- URL - the endpoint we POST to.
- HMAC secret (optional) - if set, every request includes
X-Radar-Signature: sha256=<hex>over the raw body. - Event kinds - the lane filter (empty = subscribe to everything).
data is per-event-kind. Schemas live alongside the event-kind table on the Audit log page.
Verifying signatures
X-Radar-Signature: sha256=<hex> header. If they don’t match, drop the request.
Delivery
- Best-effort. Failed deliveries retry on a fixed backoff (3 attempts) and then drop.
- Each delivery records a row in
notification_deliveriesso you can see latency and outcome in the Deliveries tab of the destination. - Strict per-destination kind filtering. If a destination subscribes to
["cluster.disconnected"], it never receivescluster.reconnected.
Subscribing to specific clusters
Today the personal toggles are global (“notify me on any cluster disconnect”). Per-cluster filtering is on the roadmap - until then, use a webhook destination with kind filter + your own routing logic.See also
- Audit log - the underlying event taxonomy.
- Cluster token rotation - rotating a token also fires a
cluster.token_rotatedevent.