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

# Tracking and engagement

> Configure optional open/click tracking and interpret engagement without confusing automated activity with human reads.

<Warning>
  **Live with caveats.** This area is real and usable, but the docs intentionally call out operational or UX limits that still matter.
</Warning>

## Goal

Configure optional open/click tracking and interpret engagement without confusing automated activity with human reads.

## Prerequisites

* Keep Mail credentials on your backend. API examples use [https://api.stackshift.cloud/v1](https://api.stackshift.cloud/v1) unless a public /api/v1 route is stated.

## Workflow

<Steps>
  <Step>
    Check tracking availability and set appropriate consent/privacy defaults.
  </Step>

  <Step>
    Override opens/clicks per send where required.
  </Step>

  <Step>
    Verify a branded host if desired, then inspect engagement with its automation and scope caveats.
  </Step>
</Steps>

## Settings and per-send overrides

* GET /mail/tracking/settings returns \{settings: \{opens, clicks}, available}. PUT accepts \{opens, clicks}. Availability is deployment-controlled; do not assume a stored preference enables an unavailable feature.
* Use tracking: \{opens: true, clicks: true} on a send or campaign to override the applicable defaults. Tracking requires HTML: plain-text-only messages do not receive a pixel or rewritten links. Per-message decisions are stored with the message; changing workspace settings does not retroactively rewrite existing messages.
* These settings and branded tracking management routes are Live-only. Test sends are excluded from live engagement reports and do not create real recipient opens/clicks.

## SDK operations

* GET /mail/messages/\{id}/engagement returns a message report; GET /mail/campaigns/\{id}/engagement returns campaign engagement. The SDK also exposes campaigns.engagement(id).
* Report fields are counts, openEligible, clickEligible, openEngagedDelivered, clickEngagedDelivered, openDelivered, clickDelivered, scope and retentionDays. counts groups kind (open/click), variant and optional link with total, unique, suspectedAutomated, firstAt and lastAt.
* Use the returned eligible/delivered denominators instead of dividing every engagement count by all campaign members. Message and recipient scope differ; a multi-recipient message cannot identify which human opened a shared pixel. Opens are approximate because proxies, caches, privacy features and scanners affect them. Suspected automation is separately counted, not proof of a human or bot.

```ts theme={null}
const current = await client.mail.tracking.settings()
if (current.available) {
  await client.mail.tracking.updateSettings({ opens: false, clicks: true })
}
const report = await client.mail.tracking.campaign(campaign.id)
console.table(report.counts)
```

## Rewriting and privacy

* Only HTTP(S) links are rewritten; up to 100 distinct tracked links per email. mailto, tel, fragments, unsubscribe links and anchors marked data-ss-no-track are excluded.
* Engagement produces mail.message.opened and mail.message.clicked timeline/events and can be delivered through signed webhooks. Verify StackShift-Signature and StackShift-Timestamp over the raw body and deduplicate the event ID.
* Engagement details and internal webhook copies expire after 90 days. Campaign aggregates remain. Encrypted click destinations can continue redirecting after their message/campaign association expires; this does not preserve per-message reporting forever. Your exported or received webhook copies are your responsibility.

## Branded domains

* GET /mail/tracking/domains returns data, target and available. POST accepts domainId and hostname. The hostname must be a dedicated subdomain below a verified sending domain; one tracking domain is associated with that domain.
* Publish the returned DNS-only CNAME pointing to target and the ownership TXT token at \_stackshift-mail.\<hostname>. Do not proxy or flatten the CNAME in a way that hides the required ownership target.
* POST /mail/tracking/domains/\{id}/verify checks DNS and HTTPS. Status progresses through pending, provisioning, active, degraded or revoked. Use only the returned configuration; successful DNS lookup alone does not prove HTTPS readiness.
* PUT /mail/tracking/domains/\{id} accepts enabled and optional revoke. Disabling stops new sends from selecting the branded host while preserving existing links when DNS remains valid. Revocation deliberately disables existing links.
* New sends use an available active branded host or the shared tracking host. Automatic checks continue; retain both DNS records so older tracked links remain valid.

## Expected result

<Check>
  Reports expose enabled tracking counts and their scope, including automated activity and the limits of interpreting opens.
</Check>

## Related guides

<CardGroup cols={2}>
  <Card title="StackShift Mail overview" href="/stackshift-mail/overview">
    Mail APIs and workflows: isolated simulation, explicit brands, consent-aware campaigns, engagement, domain health, migration, spending, inbound delivery and diagnostics.
  </Card>

  <Card title="Events, webhooks, and timelines" href="/stackshift-mail/events-webhooks-and-timelines">
    List mail events, inspect per-message timelines, subscribe webhooks, rotate secrets, retry deliveries, and verify webhook signatures.
  </Card>

  <Card title="Diagnostics, analytics, and exports" href="/stackshift-mail/diagnostics-analytics-and-exports">
    Diagnose rendered templates, measure Mail operations, and create encrypted recipient-level delivery exports.
  </Card>

  <Card title="Streams, audiences, and campaigns" href="/stackshift-mail/streams-audiences-and-campaigns">
    Separate transactional and broadcast traffic, retain consent evidence, and build private campaign drafts with unsubscribe protection.
  </Card>
</CardGroup>
