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

# Open and click tracking

> Know when a sent email is opened or one of its links is clicked.

## Turn it on when sending

Add `tracking_options` to [send an email](/emails/send) or [create a draft](/emails/drafts):

```bash theme={null}
curl -X POST "$EE_URL/api/v1/emails" \
  -H "X-API-KEY: $EE_KEY" -H "Content-Type: application/json" \
  -d '{
    "account_id": "acc_ba1fa6938d8548298e8ce62e4b4b4e99",
    "to": ["ana@example.com"],
    "subject": "Our offer",
    "body": "<p>See <a href=\"https://acme.com/offer\">the offer</a>.</p>",
    "tracking_options": { "opens": true, "links": true, "label": "campaign-7" }
  }'
```

<ParamField body="tracking_options.opens" type="boolean">Add an invisible 1×1 image that records opens.</ParamField>
<ParamField body="tracking_options.links" type="boolean">Send every http(s) link through the engine, which records the click and redirects.</ParamField>
<ParamField body="tracking_options.label" type="string">Your own tag, sent back in the events.</ParamField>

<ParamField body="tracking_options.custom_domain" type="string">
  A domain of yours that points at the engine (a CNAME), such as `links.acme.com`. It's used in the tracking URLs instead of the engine's address, so links look like your own.
</ParamField>

```json Response 201 theme={null}
{ "object": "EmailSent", "account_id": "acc_ba1fa6938d8548298e8ce62e4b4b4e99", "message_id": "84c3db9476d84b288bc6fa055a576764@mail-api.example.com", "provider_id": null, "tracking_id": "trk_5d0c3e2f1a4b4c6d8e7f9a0b1c2d3e4f" }
```

The response contains a `tracking_id`. The sent email has the same `tracking_id` once it syncs. Tracking works on the HTML body only, so plain-text emails can't be tracked.

## Events

Subscribe a [webhook endpoint](/webhooks/overview) to `tracking.open` and `tracking.click`.

```json tracking.open theme={null}
{
  "object": "Event",
  "id": "evt_9e8d7c6b5a4f43e2d1c0b9a8f7e6d5c4",
  "type": "tracking.open",
  "created_at": "2026-10-06T10:01:44Z",
  "account_id": "acc_ba1fa6938d8548298e8ce62e4b4b4e99",
  "endpoint_id": "we_e3f1a2b4c5d64e7f8a9b0c1d2e3f4a5b",
  "data": {
    "tracking_id": "trk_5d0c3e2f1a4b4c6d8e7f9a0b1c2d3e4f",
    "label": "campaign-7",
    "message_id": "84c3db9476d84b288bc6fa055a576764@mail-api.example.com",
    "email_id": "email_94a0d77db739407e932c3b97fef44aac",
    "date": "2026-10-06T10:01:44Z",
    "ip": "203.0.113.7",
    "user_agent": "Mozilla/5.0 …"
  }
}
```

`tracking.click` has the same fields plus `url`, the link that was clicked. `email_id` is the sent email's copy in the Sent folder, or `null` if it hasn't synced yet.

## Good to know

* **Opens are a hint, not proof.** Some mail apps block images, so opens are missed. Others, such as Apple Mail Privacy Protection and Gmail's image proxy, load images on their own, so an email can look opened when nobody read it. Clicks are more reliable.
* Tracked links are signed, so nobody can use your engine to redirect to other sites.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.