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

# Notification Channels — In-App and Email

> Per-channel setup and dispatch — Notification Center widget today, email next. Postmark inbound webhooks, sender domain verification, channel selection.

# Channels (detailed)

This page extends the [channels concept](/docs/concepts/channels) with per-channel setup, dispatch internals, and the email-as-if-shipped surface. For the high-level mental model, start there; this page is the practical setup reference.

## TL;DR

* A campaign step picks a `notificationConfig` whose `channelType` decides the dispatcher (`notificationcenter` or `email`).
* The orchestrator builds the recipient list once; per channel, the system iterates and dispatches.
* Notification Center is the in-app widget channel — real-time delivery.
* Email lands next: dashboard sender-domain verification, Postmark inbound webhooks for open/click, same campaign editor.

## The dispatch model

Every campaign step references a `notificationConfig` document. Each config has a `channelType`:

| `channelType`        | Dispatcher                                                                                                | Status                                      |
| -------------------- | --------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| `notificationcenter` | the dispatcher writes the message to the inbox + bumps `unreadNotifications`                              | Available today                             |
| `email`              | Email channel processor renders the template, sends via Postmark, records open/click via inbound webhooks | Wired in code; queue dispatch flips on next |

The orchestrator returns one recipient list per workflow instance. The dispatcher iterates that list **per channel** — same recipient receives the message on every channel the campaign configures.

## Notification Center

In-app widget channel. Real-time delivery via real-time stream. Three frontend SDKs (React / Angular / Vanilla) wrap the same widget — see [Notification Center overview](/docs/sdks/notification-center/overview) for the SDK surface.

### Setup

1. **Create an NC config** in the dashboard — the template (subject + body + variables) for this notification.
2. **Reference it from a campaign step** — the dashboard editor lets you pick the config from the org's library.
3. **No additional infrastructure** — the widget script + your Front API Key + the right `authType` is all the frontend needs.

### Real-time mechanism

The widget subscribes to a notification document per user (`users/{userId}/notifications/{messageId}`). The backend delivers new messages to the inbox; the widget's real-time subscription fires. The widget renders the new entry in the dropdown and updates the unread badge.

Reconnection, offline queueing, and per-document subscriptions are handled by the platform — your code never deals with reconnection logic or polling. The dashboard's [activity log](/docs/concepts/activity-log) uses a separate streaming channel for collaborative team feeds; don't conflate the two.

### Read / opened / clicked tracking

The widget reports back to the backend:

| Event     | Trigger                                  | Endpoint                               |
| --------- | ---------------------------------------- | -------------------------------------- |
| `read`    | The message renders in the dropdown list | `POST /v1/notification/event/register` |
| `opened`  | The user clicks into the message detail  | `POST /v1/notification/event/register` |
| `clicked` | A link inside the message is followed    | `POST /v1/notification/event/register` |

Each event is keyed by `(messageId, eventType)` — duplicates dedupe. See [delivery history & stats](/docs/operations/delivery-history-and-stats) for the funnel visualisation.

## Email

The email channel ships next; the docs describe the surface as it will be.

### Customer-facing setup

<Steps>
  <Step title="Verify a sending domain">
    Add your domain in dashboard → Channels → Email. Configure DKIM, SPF, and (recommended) DMARC. Verification is one-click after the DNS records propagate.
  </Step>

  <Step title="Set the From address">
    Pick a verified address — typically `notifications@yourdomain.com`. The dashboard exposes a friendly-name field separately.
  </Step>

  <Step title="Configure inbound webhooks">
    Postmark inbound webhooks deliver opened / clicked / bounce / complaint events back to Notifizz. The dashboard guides the Postmark side; Notifizz manages the webhook secret.
  </Step>

  <Step title="Create an email config">
    Same dashboard editor as the NC config — subject, body, variables. The editor exposes email-specific fields (preheader text, plain-text fallback).
  </Step>

  <Step title="Reference from a campaign step">
    Add an email step alongside (or instead of) the NC step. The orchestrator builds the recipient list; the email dispatcher renders + sends per recipient.
  </Step>
</Steps>

### Multi-channel campaigns

A single campaign can pick more than one channel step. Common patterns:

* **NC + email** — in-app for active users + email as a fallback for offline users.
* **NC only for transactional** — invoice paid (in-app receipt) + reserve email for marketing.
* **Email only** — pure marketing campaigns where the user isn't expected to be in-app.

The orchestrator runs once per matching event; channel dispatchers iterate the same recipient list. There's no double counting — each `(messageId, eventType)` pair is unique per channel.

## Why no `client.send()`

The pre-event-driven design exposed a `client.send()` method that wrote a Notification Center message directly. It was removed — channel decisions belong to the campaign, not the call site.

The migration is straightforward — emit an event, let a campaign decide channel and recipients. See the ADR for examples.

## FAQ

<AccordionGroup>
  <Accordion title="Single campaign send to NC AND email?">
    Yes — add both as separate steps in the campaign editor. The orchestrator runs once; both channels dispatch to the same recipient list. Each channel has its own template; you can copy-paste between them and adjust per-channel formatting.
  </Accordion>

  <Accordion title="Email config not sending — why?">
    Two layers to check:

    1. **Sender domain verified?** Email delivery requires DKIM + SPF on the sending domain. Unverified domains fail at the provider level (visible in the dashboard delivery history with the bounce reason).
    2. **Email queue dispatch flipped on?** Until the queue is wired (Wave 0.2 in the doc plan), email-channel campaigns are configured but don't fire. Check the dashboard banner.
  </Accordion>

  <Accordion title="Bring my own SMTP / Postmark account?">
    Not at launch — Notifizz uses its built-in provider so deliverability is handled for you. BYO-provider is on the longer-term roadmap.
  </Accordion>

  <Accordion title="Where do open / click events come back?">
    On each delivery's stats funnel and on the campaign's aggregated metrics. The widget reports NC events directly via `POST /v1/notification/event/register`; email reports the same shape via inbound webhooks. The funnel renders both side-by-side per channel.
  </Accordion>

  <Accordion title="Add a new channel later (push / SMS)?">
    The dispatch model accommodates it — a new `channelType` value plus a new dispatcher. Push and SMS are on the roadmap; they'll feel exactly like NC and email from the campaign-author side.
  </Accordion>

  <Accordion title="Channel-specific templating — how different from NC?">
    The dashboard editor exposes channel-specific fields (preheader for email, action buttons for NC). Variables and brands work the same across channels — see [brands and variables](/docs/concepts/brands-and-variables).
  </Accordion>
</AccordionGroup>

## See also

<CardGroup cols={2}>
  <Card title="Channels overview" icon="bell" href="/docs/concepts/channels">
    Higher-level mental model.
  </Card>

  <Card title="Notification Center overview" icon="bell" href="/docs/sdks/notification-center/overview">
    Widget SDK surface across React / Angular / Vanilla.
  </Card>

  <Card title="Brands and variables" icon="palette" href="/docs/concepts/brands-and-variables">
    Templating across channels.
  </Card>

  <Card title="Delivery history & stats" icon="chart-line" href="/docs/operations/delivery-history-and-stats">
    Per-channel funnel.
  </Card>
</CardGroup>
