> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Triage the Notification Center

> What the in-dashboard Notification Center is for, what raises a notification, how delivery works, and how to manage read, unread, and dismiss.

# 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 **severity** — `info`, `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`

<Note>
  Security kinds are **always shown** regardless of your notification preferences — suppressible preferences would let a hijacked session mute the takeover signal.
</Note>

**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

```bash theme={null}
curl https://api.orbit.devotel.io/api/v1/notifications/digest/settings \
  -H "X-API-Key: dv_live_sk_your_key_here"
```

`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](/webhooks/events.mdx).

## Operator runbook tips

The notification center and [on-call alerting](/guides/oncall-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.
