Tracking

Click tracking

Enable click tracking to record when a recipient follows a supported link in an HTML email.

How it works

When click tracking is enabled for a route, Lettermint automatically rewrites links in your HTML emails to route through our tracking domain. The original link:

Code
<a href="https://example.com/product/123">View Product</a>

Becomes:

Code
<a href="https://p{sid}.t.ltrmnt.com/t/c/{destination}/{tracking_token}">View Product</a>

Where {sid} is your project's short ID. {destination} shows the original URL for transparency; the redirect always uses the signed {tracking_token}.

Want branded tracking links? Custom tracking domains let you use your own subdomain (e.g., track.yourcompany.com) instead of the default tracking domain. Available on Pro plans.

Redirect flow

When a recipient clicks a tracked link:

  1. Token validated - We verify the tracking token's signature. An invalid token returns 404
  2. Click observed - For a token that has not expired, we store the click observation with timestamp
  3. Instant redirect - Recipient is immediately redirected (302) to the original URL
  4. Classification and promotion - The observation is classified before it contributes to customer-visible events and metrics
  5. Webhook sent - Human-countable clicks send a message.clicked event to your configured webhooks

The redirect happens in milliseconds, so recipients notice nothing.

Enabling click tracking

Via dashboard

  1. Navigate to your project
  2. Go to Routes and select your transactional or broadcast route
  3. In Route Settings, enable Track Clicks
  4. Save your changes

Via API

Use the route update method shown in Tracking with this settings payload:

JSONCode
{ "settings": { "track_clicks": true } }

Click tracking is only available for transactional and broadcast routes. Inbound routes cannot have tracking enabled.

Per-email override

You can override the route's click tracking setting for a single email. This lets you keep a route default while opting individual messages in or out.

API sends use settings.track_clicks:

JSONCode
{ "from": "sender@yourdomain.com", "to": ["recipient@example.com"], "subject": "Your download link", "html": "<p><a href=\"https://example.com/download\">Download</a></p>", "settings": { "track_clicks": false } }

SMTP sends use the Lettermint override header:

Code
X-LM-Override-Track-Clicks: false

The override applies only to that email and takes precedence over the selected route's Track Clicks setting.

Lettermint rewrites absolute HTTP/HTTPS links in HTML <a> elements:

  • https://example.com/page
  • http://example.com/page

The following link types are not rewritten to preserve functionality:

Link TypeExampleReason
Email linksmailto:support@example.comOpens email client
Phone linkstel:+1234567890Opens phone dialer
SMS linkssms:+1234567890Opens messaging app
JavaScriptjavascript:void(0)Client-side only
Anchors#section-nameSame-page navigation
Data URIsdata:image/png;base64,...Embedded content
Other links/account, cid:logo, ftp://example.com/fileOnly absolute HTTP/HTTPS links can redirect
Unsubscribe linkshttps://example.com/unsubscribe/..., link text such as "Unsubscribe" or "Afmelden", or the List-Unsubscribe URLUnsubscribes are not counted as clicks and work without the tracking domain

Bot detection

Security scanners and link preview features can click links before humans do. Lettermint detects these automated clicks to ensure accurate analytics.

Lettermint classifies identified scanner clicks as security_scanner. Clicks that Lettermint counts but cannot confirm with high confidence, such as a click without a prior open, report engagement_state likely_human and still count. See Security scanner detection.

Webhook payload

When a human-countable click is detected, Lettermint sends a message.clicked webhook event. Machine, link preview, and security scanner clicks are excluded by default and are only sent to webhooks with Include machine events enabled.

JSONCode
{ "id": "b2c3d4e5-f6a7-8901-bcde-f01234567892", "event": "message.clicked", "timestamp": "2025-08-08T20:18:30.000Z", "data": { "message_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "subject": "Your weekly recommendations", "metadata": { "X-Campaign-ID": "weekly-recs" }, "tag": "recommendations", "tags": [ {"name": "__lettermint_tag", "value": "recommendations"}, {"name": "variant", "value": "B"} ], "recipient": "user@example.com", "clicked_at": "2025-08-08T20:18:30+00:00", "tracking_event_id": "0198a5be-cfa8-78e4-8339-144ab5a92fb1", "classification_revision": 1, "destination_url": "https://example.com/product/123", "link_index": 0, "anchor_text": "View Product", "first_click": true, "device_type": "mobile", "client_type": "browser", "client_name": "Safari", "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X)...", "bot": { "detected": false, "probability": 0, "classification": "genuine", "proxy_type": null, "reason_codes": [], "machine": false, "counts_for_metrics": true } } }

Click-specific fields:

  • destination_url - The original destination URL that was clicked
  • link_index - Zero-based index of the link in the email (order of appearance)
  • anchor_text - The visible text of the clicked link
  • clicked_at - Timestamp when the click occurred

Engagement fields:

  • tracking_event_id - Stable ID for this click observation. The click has an ID that is different from the ID of an earlier privacy open.
  • classification_revision - Revision number for this click. A new click starts at revision 1.
  • engagement - Optional engagement conclusion and evidence times. It is present when the click confirms an earlier privacy open.
  • first_click - true if this is the first time this recipient clicked any link in this email
  • device_type - Device category: desktop, mobile, or tablet
  • client_type - Client category: browser, email_client, etc.
  • client_name - Specific client name: Chrome, Safari, Outlook, etc.

Bot detection fields:

  • bot.detected - true if the click appears automated
  • bot.probability - Confidence score from 0-100 (higher = more likely a bot)
  • bot.classification - Source classification such as genuine, privacy_proxy, security_scanner, or generic_bot
  • bot.proxy_type - Known proxy family when applicable, otherwise null
  • bot.reason_codes - Broad categories behind the classification. See Reason code guidance
  • bot.machine - true when the click is classified as machine, preview, or security activity
  • bot.counts_for_metrics - Whether the click contributes to default engagement metrics

Privacy inference revisions

A high-confidence click can confirm human engagement for an earlier supported privacy fetch. Lettermint then sends revision 2 of the message.opened event. The revised open keeps the same privacy-open tracking_event_id and the same privacy-fetch time.

The message.clicked event uses the click observation's own tracking_event_id and starts at revision 1. Its engagement.engagement_confirmed_at value contains the click time. Store the highest classification_revision for each tracking_event_id.

See Bot Detection Field Values for the stable classification contract and guidance for open diagnostic strings.

Limitations

Token expiration

Tracking tokens expire 30 days after the email is sent. After expiration:

  • Clicks are not recorded
  • Recipients are still redirected to the original URL (graceful degradation)

Corporate security pre-clicking

Some corporate email security tools pre-click all links in emails to scan for malware. Lettermint excludes identified security scanner clicks from default metrics and webhooks. They remain available to opted-in webhooks and reporting requests that include machine activity. Corporate web gateways and cloud desktops are not scanners, so their clicks still count.

Plain text emails

Click tracking only works for HTML emails. Links in plain-text email parts are not rewritten.

The tracking URL is visible if recipients hover over links or inspect the email source. This is standard for email tracking and does not affect the user experience. For a more branded appearance, consider using a custom tracking domain.

Best practices

  1. Track specific campaigns - Use metadata and tags to attribute clicks to campaigns
  2. Monitor unique clicks - Use first_click to distinguish initial engagement from repeat clicks
  3. Test your links - Send test emails to verify tracked links redirect correctly
  4. Respect privacy - Disclose tracking in your privacy policy

Next steps

  • Open Tracking - Combine with open tracking for complete engagement data
  • Webhook Events - Full payload reference for all tracking events
  • Tags - Organize and filter your tracked emails