# Open and click tracking

Tracking tells you who opened an email and which links they clicked. You turn it on per sending domain, and every HTML email from that domain is tracked, whether it comes from the API, the SMTP relay, a broadcast or an automation. Opens and clicks show up on the email in the dashboard, in [Metrics](https://hatang.dev/docs/guides/email/metrics-and-logs.md) and as `email.opened` and `email.clicked` webhooks.

## Before you start

- A domain added to Ha Tang. See [Domains](https://hatang.dev/docs/guides/email/domains.md).
- For the API, a key with `email:write`.

## Turn tracking on

In the dashboard, open **Email → Domains**, pick the domain and switch **Open tracking** and **Click tracking** under **Tracking**. You can also set them when you add the domain (**Advanced options → Tracking options**). Both are off by default.

**cURL**

```bash
curl -X PATCH https://api.hatang.dev/domains/$DOMAIN_ID \
  -H "Authorization: Bearer $HATANG_API_KEY" -H "Content-Type: application/json" \
  -d '{ "open_tracking": true, "click_tracking": true }'
```

**Node.js**

```ts
await hatang.domains.update({ id: domainId, open_tracking: true, click_tracking: true });
```

**Python**

```python
requests.patch(
    f"https://api.hatang.dev/domains/{domain_id}",
    headers={"Authorization": f"Bearer {os.environ['HATANG_API_KEY']}"},
    json={"open_tracking": True, "click_tracking": True},
)
```

**PHP**

```php
$client->patch("/domains/$domainId", [
    'headers' => ['Authorization' => 'Bearer ' . getenv('HATANG_API_KEY')],
    'json' => ['open_tracking' => true, 'click_tracking' => true],
]);
```

The setting is copied onto each email when Ha Tang accepts it, so a change applies to emails sent from then on. Tracking cannot be switched per email.

## How open tracking works

Ha Tang adds a 1×1 transparent image at the end of the HTML body. When a mail client loads it, Ha Tang records an open for that recipient.

- Only the HTML part is tracked. A plain-text-only email cannot record opens.
- Every open is stored. The `email.opened` webhook is sent at most once an hour per recipient.
- Opens are an estimate. Some mail clients and security gateways load images without anyone reading the email (Apple Mail Privacy Protection, for example), and others block images, so the real number can be higher or lower. Ha Tang marks opens from known image proxies with `suspected_proxy` in the event data.

## How click tracking works

Ha Tang rewrites each `http` or `https` link in the HTML to a tracking address. A click records the event and redirects the recipient (`302`) to the original URL.

- Links that are not `http(s)` are left alone: `mailto:`, `tel:`, `sms:`, `#anchors`.
- To leave one link untouched, add the `data-no-track` attribute: `<a href="https://example.com/account" data-no-track>`.
- The original URL is encrypted inside the tracking link, so nobody can change it to redirect to another site.
- Each click is stored and sends an `email.clicked` webhook with the link:

```json
{
  "type": "email.clicked",
  "created_at": "2026-10-14T09:20:11.000Z",
  "data": {
    "email_id": "0199e6c1-7a2b-7f00-9c1e-3f6a2b1d9e10",
    "from": "Acme <orders@example.com>",
    "to": ["lan@example.net"],
    "subject": "Order #1024 is confirmed",
    "created_at": "2026-10-14T09:12:03.000Z",
    "tags": {},
    "click": { "link": "https://example.com/orders/1024", "timestamp": "2026-10-14T09:20:11.000Z", "ipAddress": "203.0.113.7", "userAgent": "Mozilla/5.0 …" }
  }
}
```

The email page in the dashboard (**Engagement**) shows unique and total opens, and the clicks per link.

## Use your own tracking subdomain

By default tracked links and the open pixel use the platform's tracking host. A tracking subdomain such as `links.example.com` makes them use your domain instead, so links in your emails match your brand and do not share a host with other senders.

1. Set the subdomain label: when you add the domain (**Tracking Subdomain**), or later with `PATCH /domains/{id}` and `{ "tracking_subdomain": "links" }`. The label must differ from the return-path label (`send`).
2. Publish the **Tracking** CNAME record shown on the domain page, for example `links.example.com CNAME` to the tracking host it lists.
3. Verify the domain again (**Re-check DNS** or `POST /domains/{id}/verify`).

Until the CNAME is verified, links keep using the platform host (the dashboard says so under **Tracking**). Once it is verified, `tracking_domain_verified` is `true` and new emails use `https://links.example.com/…`. Ha Tang gets the HTTPS certificate for the subdomain by itself. Set `tracking_subdomain` to `null` to go back to the platform host.

## Privacy

- An open or click event stores the recipient, the time, the IP address and the user agent of the request. These show up in webhooks and in `GET /emails/{id}/events`.
- Open tracking adds an image that a recipient's mail client loads from Ha Tang. Tell your recipients about tracking in your privacy policy, and get consent where the law requires it.
- If you do not need it, leave tracking off for transactional mail such as password resets.
- Links in password-reset or sign-in emails work through the redirect too. Add `data-no-track` to keep a sensitive URL out of the tracking link.

## Next steps

- [Metrics and logs](https://hatang.dev/docs/guides/email/metrics-and-logs.md)
- [Webhooks](https://hatang.dev/docs/guides/getting-started/webhooks.md)
- [Domains](https://hatang.dev/docs/guides/email/domains.md)

Source: https://hatang.dev/docs/guides/email/tracking
