Skip to main content

Triage the Notification Center

The Notification Center is the dashboard’s persistent alert feed — the full list behind the bell icon. Where the bell dropdown gives you a quick glance at what’s new, this page is where you triage, batch-mark-read, and review history. Its own subtitle says what it holds: persistent platform alerts that need your attention. Open it from /notifications (bell icon, top right).

What a notification is

A notification is a durable, row-scoped platform event that surfaced somewhere in your org and needs a human view. It carries:
  • a title + body — what happened, in plain terms
  • a kind — which event class it belongs to (campaign, payment, security, inbox, …)
  • a severityinfo, warning, or error
  • an optional action URL — a deep link to the surface that resolves it
  • a read/unread state and an optional expiry
Below the persistent row feed, the page also pins Active platform alerts — a cross-module snapshot of issue states still resolving (outbound paused, KYC pending, compliance risk, webhook backlog, number document expiry) — so the center is never empty while a real issue is outstanding.

What raises a notification

Notification kinds are a closed enum on the API, and the dashboard’s filter dropdown mirrors that enum. The major groupings: Platform alerts
  • campaign_completed / campaign_failed — a campaign finished (or finished with errors)
  • payment_failed / top_up_succeeded / credit_low / wallet_emptied / number_renewal_failed / unusual_billing_activity — billing state changes
  • dlq_alert / webhook_endpoint_disabled / webhook_endpoint_decryption_failed — integration failures
  • port_status_changed / telnyx_* (regulatory, number order, port request) / number_compliance_requested — number lifecycle
  • kyc_decision / sender_id_review / compliance_incident — compliance decisions
  • account_fraud_alert — account-level fraud / traffic anomaly
  • email_dns_regression — deliverability regression
  • system_alert — generic platform alert
Security alerts
  • new_signin_from_new_ip / new_signin_from_new_device / password_changed / email_changed / recovery_email_changed
  • two_factor_disabled / two_factor_method_removed / mfa_backup_codes_regenerated
  • api_key_created / api_key_revoked
  • org_member_role_changed / org_member_removed
Security kinds are always shown regardless of your notification preferences — suppressible preferences would let a hijacked session mute the takeover signal.
Agent + inbox alerts
  • agent_handoff_pending — AI agent escalated to a human
  • agent_kpi_alert_fired / voice_queue_sla_warning / voice_queue_alert_rule_fired / messaging_deliverability_alert_fired / acd_disposition_required — operational thresholds breached
  • inbox_new_message / inbox_conversation_assigned / inbox_new_conversation / inbox_mention / inbox_sla_breach / inbox_follower_update / inbox_ticket_follower_update / team_chat_message / csat_low / whatsapp_template_status_changed — inbox + messaging state changes

Delivery channels

Every notification lands in-app — the bell row, the live stream, and the Notification Center list. Outbound delivery is layered on top:
  • In-app — persisted row + live SSE feed. This is the only delivery for a few high-frequency, low-stakes kinds (for example team_chat_message), where per-event email would be spam.
  • Email digest — for outbound-eligible kinds, a per-user digest (daily or weekly) rolls up unread notifications in opted-in categories: billing, security, messaging, campaigns, agents, system. Configure it under Settings → notification digest, or via the API below.
  • Category-level preferences — you can mute a whole category for outbound delivery per user (Settings → notifications). Muted categories still mint the in-app bell row; security-critical kinds ignore the mute entirely.

Digest API

PUT /notifications/digest/settings sets frequency (daily | weekly) and categories you want emailed; GET /notifications/digest/recipients lists recipients and PATCH /notifications/digest/recipients/:user_id toggles a recipient’s opt-in.

Read, dismiss, retention

  • Read/unread — a PUT /notifications/:id/read call marks a single row read; POST /notifications/read-all clears the badge. The dashboard streams delivery so read state syncs across open browser tabs.
  • Dismiss — user-scoped notifications can be dismissed; the row hides immediately and the delete commits after a short undo window (~5s in the UI).
  • Retention — rows carrying an expires_at timestamp are automatically filtered out of every list and unread-count response after that moment passes, so a stale “campaign completed” never lingers past its useful life. Rows without an expiry persist until you dismiss them.

API endpoints

  • GET /notifications — cursor-paginated list (filters: unread_only, kind, severity, category, since, until)
  • GET /notifications/unread-count — badge count
  • PUT /notifications/:id/read and POST /notifications/read-all
  • DELETE /notifications/:id — dismiss
  • GET /notifications/stream — SSE feed of new notifications

Notifications vs webhooks

Notifications are for a human operator; webhooks are for your code.
  • A notification is a durable UI row an operator triages from the dashboard. Read, dismiss, filter — no endpoints to expose.
  • A webhook is a server-to-server POST to an endpoint you control. You subscribe to webhook events and process them automatically.
The two overlap intentionally: developer-facing failure modes (delivery stuck in the dead-letter queue, an endpoint auto-disabled, decryption failing) also mint an in-app notification so an operator sees it — even when your webhook handler isn’t watching. For the full event catalog, see Webhook Events.

Operator runbook tips

The notification center and on-call alerting serve different altitude:
  • Notification Center = state an entire org sees; any member with dashboard access can triage it.
  • On-Call alerting = an engineering-to-action escalation loop (rotation → escalation policy → page via Messages) for time-critical issues.
Compose the two deliberately:
  1. A dashboard notification lands (e.g. dlq_alert, wallet_emptied, webhook_endpoint_disabled).
  2. Your on-call rotation consumes that queue if it needs a human now — page the current on-call via On-Call, with dashboard access to review the row before acting.
  3. If the alert is genuinely routine, the center’s filters + category digests keep on-call pages from flooding the rotation with noise.
For operator-facing runbooks: subscribe a category digest to the rotation’s on-call email for low-severity alerts, and reserve On-Call paging for security-critical, wallet-pausing, and integration-failure kinds.