Skip to main content

Configure notification channels

The notifications feed guide covers rendering and filtering on /notifications. This page covers where you tune delivery — per-category channel toggles on Settings → Notifications, the per-user digest on Settings → Notifications → Digest, and org-level webhook sinks under Developer → Webhooks.

How the two freshness mechanisms interact

The notifications page combines a live-push stream (server-sent events on GET /api/v1/notifications/stream) with a 30-second poll safety net. SSE is the primary — a new row lands without a refresh and read state syncs across tabs. The poll exists because a stream frame can be missed: a laptop resumes from sleep between heartbeats, or an inbox row arrives that the stream didn’t carry. In those cases the poll self-corrects within 30 seconds, so the feed converges even when the live channel hiccups. This explains the “sporadic stale content” an operator sometimes sees: stale for up to ~30 seconds is the fallback working, not a bug — the poll was re-arming after a dropped stream. The bell badge polls on the same cadence, so it can never get stuck on a stale number either. If rows never converge, that is a real failure — check the stream’s connection budget (50 per tenant, enforced cluster-wide, browser UA + trusted Origin required) before filing.
The optional webhook consumer path is unaffected by either mechanism — webhooks are server-to-server POSTs to your endpoint regardless of your notifications-page freshness. See Webhook events and the webhook consumer guide.

Per-user push subscriptions vs org webhook sinks

These live in different settings surfaces deliberately:
  • Settings → Notifications is per user — each member of the org tunes their own category/channel matrix (billing, security, messaging, campaigns, agents, system) across email, push, and webhook, plus a frequency (immediate / daily / weekly).
  • Developer → Webhooks is an org-level sink — it fans out developer event webhooks to your endpoint, not to a user’s notification bell.
  • The digest-opt-in API (GET /api/v1/notifications/digest/settings) is the tenant-owned control; the dashboard surface above maps to it.

Per-category channel matrix

Each member sets three toggles per category, and the defaults are on until you change them. Frequencies are immediate (default), daily, or weekly: Worked example — to route campaign completion emails into one daily email instead of one per event: open Settings → Notifications, find the campaigns row, and set Frequency to daily. New campaign events queue on the digest worker and land as one aggregated email instead of N separate ones. Categories other than campaigns are unaffected. Security categories ignore whatever you pick here; see the next section.

Security-critical categories are always on

The following event kinds bypass the matrix entirely — they mint a row and deliver regardless of what the preferences say, so a hijacked session can’t silence the takeover signal:
  • Sign-in from a new IP
  • Sign-in from a new device
  • Two-factor disabled or a 2FA method removed
  • Password changed
  • Email changed (primary or recovery)
  • MFA backup codes regenerated
  • API key created or revoked
  • Member role changed or member removed
  • Unusual billing activity / billing anomaly
  • Account fraud alert (toll-fraud signal on your own traffic)
Example of a mute being ignored: an attacker who has taken over a session opens Settings → Notifications and switches every category off. When they then create an API key and revoke the old one, both events still mint a bell row and dispatch the email to every admin — the attacker succeeded at copying the key out but did not succeed at hiding it.

Digest API worked sample

The digest is the org-level opt-in for a daily or weekly aggregate email. Fetch the current org settings:
Response (defaults shown — enabled off, weekly, every category):
An empty categories array means all six categories are included. Turn the digest on with a daily cadence restricted to campaigns and billing:
The route writes an audit-log row recording before/after. Both GET and PUT require an authenticated session; PUT is restricted to owner and admin.

Freshness debugging — decision table

Use this when the notifications page looks stale: Connection budget checks, in order:
  1. The stream caps at 50 concurrent connections per tenant, enforced cluster-wide — a browser with many open tabs on the same org can exhaust it.
  2. The stream requires a browser user-agent and a trusted origin. API clients and non-browser proxies are rejected.
  3. If neither is the cause, file it with a timestamp and the affected org id.

Operator walkthrough

  1. Settings → Notifications — tune your own per-category email/push toggles and pick a frequency per category. This affects only you, not your teammates.
  2. Settings → Notifications → Digest — flip the org digest on/off, choose daily or weekly, and narrow the categories. This affects the org, and only owner/admin roles can change it.
  3. Developer → Webhooks — register an endpoint for developer event fan-out. This is unrelated to the bell and unaffected by any setting above; the divergence boundary is that per-user push runs through your personal preference matrix whereas the org webhook sink fires regardless of any member’s opt-out.

Not covered today

The notifications section in Settings is dashboard-only — there is no public API for the per-category channel matrix itself (the digest API covers org-level outlet selection). The webhook guide remains separate; this page only covers where the operator-facing toggles live.