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

# Open & click tracking

> See who read what, how often, and when.

Robase rewrites tracked links through our proxy and injects a 1×1 pixel into HTML bodies. You opt in per send:

```typescript theme={null}
await pm.emails.send({
  from, to, subject, html,
  track_opens: true,
  track_clicks: true,
});
```

## Events fired

| Event           | When                                                                                            |
| --------------- | ----------------------------------------------------------------------------------------------- |
| `email.opened`  | Tracking pixel fetched. Fires once per open (but the same recipient opening twice fires twice). |
| `email.clicked` | A rewritten link was clicked.                                                                   |

Both include the original email's ID + recipient in the webhook `data`.

## Privacy considerations

<Warning>
  Open tracking relies on a 1×1 image. Some mail clients (Apple Mail Privacy Protection, ProtonMail) pre-fetch images, so `email.opened` fires even if the human never looked. Treat open rates as a relative signal, not absolute truth.
</Warning>

Click tracking is more reliable — it only fires on actual click-through. For GDPR / NDPR compliance, your privacy policy should disclose that you track opens/clicks in transactional email.

## Turning it off per message

```typescript theme={null}
// Sensitive transactional email — no tracking
await pm.emails.send({
  from, to,
  subject: 'Your password reset link',
  html: '<p>Reset: <a href="https://app.example/reset?token=...">here</a></p>',
  track_opens: false,    // don't leak "you read the email"
  track_clicks: false,   // don't rewrite the one-time token link
});
```

<Tip>
  Never turn on click tracking for emails containing one-time tokens (password reset, magic link). The rewrite proxy changes the URL, which can invalidate tokens that are cryptographically tied to the URL.
</Tip>

## Dashboard analytics

The dashboard aggregates opens / clicks by email, campaign tag, and time range. Filter by a `tags[]` value set at send time to see a specific campaign's performance:

```typescript theme={null}
await pm.emails.send({
  from, to, subject, html,
  tags: ['campaign:launch-q2-2026'],
});
```

Then filter the dashboard by `tag:campaign:launch-q2-2026`.
