> ## 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 Deep Links and Tracked URLs

> How Notifizz handles links inside notifications — tracking semantics, custom redirects, security, click attribution, UTM parameters.

# Link routes

Links inside notifications are first-class citizens — Notifizz tracks the click and (optionally) routes through a redirect for analytics, attribution, or short-link replacement. This page covers the link-route concept and its tracking semantics.

## TL;DR

* Every clickable link in a notification is wrapped in a Notifizz redirect (per-message id).
* The redirect records the click event, then redirects to your destination URL.
* Click attribution flows into the campaign's funnel — Delivery → Read → Opened → Clicked.
* UTM parameters can be added at the campaign level or hard-coded in the link itself.

## How it works

```mermaid theme={null}
sequenceDiagram
    participant User
    participant Widget
    participant Notifizz
    participant App as Your destination

    Widget->>User: Click "View order"
    User->>Notifizz: GET /v1/redirect/<routeId>
    Notifizz-->>Notifizz: Record click event
    Notifizz->>User: 302 Redirect to <destinationUrl>
    User->>App: Land on https://app.example.com/orders/4521
```

Each link in your template renders as a Notifizz redirect URL when the message is created. The redirect carries an opaque `routeId` that ties back to:

* The message id (for delivery-level attribution).
* The recipient id.
* The original destination URL.

When the user clicks, Notifizz records the click event (visible in the campaign's funnel) and then 302s to the destination.

## Setup

The dashboard's template editor handles link routes transparently:

<Steps>
  <Step title="Insert a link in the template">
    Use the editor's "Link" toolbar button or the rich-text shortcut. Paste your destination URL.
  </Step>

  <Step title="Configure tracking">
    By default every link is tracked. Toggle off per-link if you want a raw `mailto:` or `tel:` URL with no Notifizz redirect.
  </Step>

  <Step title="Variables in URLs">
    Use `{{ variable.name }}` inside the URL — the editor resolves at send time. For example, `https://app.example.com/orders/{{ event.orderId }}`.
  </Step>
</Steps>

For NC messages, the widget intercepts clicks and posts to `POST /v1/notification/event/register` with `eventType: "clicked"` directly — no redirect chain on the user's browser. For email, the destination URL is rewritten at render time to point at the Notifizz redirect; the redirect handles the click event server-side.

## Tracking semantics

| Step        | When it fires                                                                       | Counts toward    |
| ----------- | ----------------------------------------------------------------------------------- | ---------------- |
| **send**    | Backend delivered the message (NC) or accepted it for delivery (email)              | Delivery counter |
| **read**    | The user saw the message in the dropdown / preview pane                             | Read funnel      |
| **opened**  | The user clicked into the message detail (NC) or the tracking pixel fetched (email) | Opened funnel    |
| **clicked** | A link inside the message was followed                                              | Clicked funnel   |

Each event is keyed by `(messageId, eventType)` — duplicates dedupe. A user who clicks twice doesn't double-count.

## Per-link tracking off

If you have a link you don't want tracked (e.g. a mailto: that doesn't make sense to redirect), toggle tracking off in the editor. The link renders as a raw URL with no Notifizz wrapping.

```html theme={null}
<!-- Tracked -->
<a href="https://app.example.com/orders/{{ orderId }}">View order</a>

<!-- Untracked (raw) -->
<a href="mailto:support@example.com">Email support</a>
```

## UTM parameters

Two patterns:

### Hard-code per template

```html theme={null}
<a href="https://app.example.com/orders/{{ orderId }}?utm_source=notifizz&utm_campaign=order-shipped">View order</a>
```

The redirect appends nothing; UTM lands at your destination. Use this when UTM tagging is per-template.

### Inject at the campaign level

The campaign config can declare UTM parameters that the redirect appends to every destination URL automatically. Use this when UTM tagging is per-campaign and the templates shouldn't repeat the boilerplate.

The exact UI is in the campaign settings → Link tracking section.

## A/B testing two URLs

Branch in the orchestrator:

```typescript theme={null}
const variant = Math.random() < 0.5 ? "A" : "B";
return [{
  id: user.id,
  email: user.email,
  ctaUrl: variant === "A" ? "/checkout" : "/checkout-v2",
  variant,
}];
```

Then reference `{{ recipient.ctaUrl }}` and `{{ recipient.variant }}` in the template. The funnel splits by `variant` if you wire the campaign's branching schema.

For full A/B testing infrastructure (statistical significance, automatic variant pickup), the campaign editor exposes a dedicated experimentation surface — the "branch in orchestrator" pattern is the manual fallback.

## Security

The redirect is open by design (302 to any URL), but Notifizz prevents some classes of abuse:

* **Domain allow-list per organisation** — optional. The dashboard can restrict redirects to a configured allow-list. Useful for orgs with strict open-redirect policy.
* **Signed redirect IDs** — the `routeId` is opaque and tied to the message; you can't construct a redirect URL externally that bypasses tracking.
* **Per-recipient tokens** — the `routeId` references the message-recipient pair; another user's `routeId` lands on the same destination but the click is recorded against the original recipient.

## Custom domain for short links

The default redirect URL is `https://eu.api.notifizz.com/v1/redirect/<routeId>`. For branded short links, configure a custom domain (e.g. `https://l.example.com/<routeId>`) — DNS CNAME + dashboard settings. The destination resolution and tracking are identical; only the visible host changes.

## FAQ

<AccordionGroup>
  <Accordion title="UTM parameters per campaign — how do I configure?">
    Campaign settings → Link tracking → "Append UTM" section. The configured parameters are appended to every tracked link's destination at render time. Per-template overrides win when both are set.
  </Accordion>

  <Accordion title="A/B test two URLs — recommended pattern?">
    Use the campaign's experimentation surface for proper A/B testing. For one-off tests, branch in the orchestrator (set a `variant` field per recipient, reference it in the template).
  </Accordion>

  <Accordion title="Click never fires — what's wrong?">
    Two suspects: (1) tracking is toggled off for that specific link in the editor; (2) the link is in a section the user never sees (collapsed accordion, mobile-hidden). Check the funnel — if "opened" fires but "clicked" doesn't, suspect (2).
  </Accordion>

  <Accordion title="Custom domain for short links — DNS setup?">
    CNAME from `l.example.com` to the Notifizz redirect host (the dashboard shows the target value). Allow up to 24h for DNS propagation; once verified, configure in the dashboard's Link tracking section. The custom host applies to every campaign in that organisation.
  </Accordion>

  <Accordion title="Open-redirect security — can someone use my redirect to phish?">
    Three layers: (1) the redirect ID is opaque and message-bound — you can't construct one externally; (2) Notifizz can be configured to allow-list destination domains per organisation; (3) the click event includes the user identity, so abuse is auditable. Combined, these make Notifizz redirects unattractive for phishing — the destination is bound at message creation time, not at click time.
  </Accordion>

  <Accordion title="Click on email link — same routeId as click in NC?">
    No, separate. Each rendered message has its own `routeId` per channel. The funnel aggregates clicks across channels by campaign id, but you can drill down per channel.
  </Accordion>
</AccordionGroup>

## See also

<CardGroup cols={2}>
  <Card title="Channels (detail)" icon="bell-concierge" href="/docs/concepts/channels-detail">
    Per-channel dispatch internals.
  </Card>

  <Card title="Brands and variables" icon="palette" href="/docs/concepts/brands-and-variables">
    `{{ }}` resolution at template-render time.
  </Card>

  <Card title="Delivery history & stats" icon="chart-line" href="/docs/operations/delivery-history-and-stats">
    The funnel (Delivery → Read → Opened → Clicked).
  </Card>

  <Card title="Observability" icon="magnifying-glass-chart" href="/docs/operations/observability">
    Tracing one click through to the destination.
  </Card>
</CardGroup>
