Knowledge base

The node can insert pixels and rewrite links by itself

engine-side engagement tracking
Tracking built into the mail engine

The engine takes on what a sending platform usually does: it parses outgoing HTML, rewrites links so that clicks go through the tracking domain, and inserts an open pixel. It works only together with the vendor’s analytics service (sparkpost-signals) — the events go to it.

Three independent switches. The top pixel, the bottom pixel and link rewriting are enabled separately; you can take only what you need.

The tracking domain is the vendor’s by default, but it can be replaced with your own: the client’s domain is pointed at their infrastructure with a DNS record. For European senders there is a regional variant, and it is mandatory, not merely advisable.

Individual links are excluded right in the markup — with an attribute the engine removes from the delivered message. That way the unsubscribe link stays untracked instead of turning into a click through someone else’s domain.

Secure links are off by default and require a properly configured domain with a certificate.

What to do when the HTML cannot be parsed is decided by a setting: either the message bounces or it goes out unchanged. In both cases the error is written to the log.

The main trap is a message rewritten differently than intended. The engine parses someone else’s markup, and parsing does not always succeed: a message from a third-party editor, stitched together from pieces, or markup with errors. By default such a message goes out unchanged — that is, without tracking, which you learn about only from a dip in the reports; or, with a different setting, it bounces entirely — and then part of the mailing simply does not go out. Neither is harmless, and the choice has to be deliberate.
What the Hub does. It does not use it — the vendor’s service is not connected for us, so its tracking does not work either.

We are building the same thing on our own. The Hub issues and maintains tracking domains itself: TrackingDomainManager sets up the client’s domain on the node, obtains a certificate and keeps it renewed.

The difference is fundamental: at the vendor clicks go through its infrastructure, for us — through our node. For a boxed product this is decisive: data about the client’s recipients’ clicks must not go to a third party.

The experience in this entry is directly useful to us — the set of decisions is the same: where to put the pixel, how to exclude the unsubscribe link, what to do with unparsable markup.

Recommended values

Decisions that have to be made — both at the vendor and on your own side:

Decision Options What to watch
open pixel top, bottom, both the bottom is more reliable: some clients truncate long messages
link rewriting on or off without it there are no clicks, but the message stays untouched
tracking domain the vendor’s or your own your own means recipient trust and your own data
secure links off by default require a domain with a certificate
unparsable markup bounce or let through bouncing loses messages, letting through loses data

Always exclude the unsubscribe link. A click on it through someone else’s domain is an extra point of failure exactly where failure is most expensive: a recipient who could not unsubscribe clicks “spam.”

For European senders the regional variant is mandatory — this is a requirement, not a recommendation.

The decision table and the advice about the unsubscribe link are ours. From the manual here come the three independent switches, replacing the domain with a DNS record, the mandatory regional variant for Europe, the link exclusion attribute and the choice of behavior for unparsable markup.
Example configuration
# at the vendor these are settings of the analytics block
<signals>
    engagement-tracking sparkpost
    tracking-domain track.example.com
    html-edit-error-mode bounce</signals>
The highlighted line is exactly the decision worth making deliberately: bounce a message with unparsable markup or let it through without tracking. The default is to let it through, and you learn about the data loss only from reports.
yellow — — directive names, blue — blocks. They are highlighted the same way in the text of the card.
▲

Common mistakes and problems

what people get wrong and how it ends3 mistakes▶

Leaving the default for unparsable markup

§ 11.1.6.2.3

What it costsA message with markup the engine could not parse goes out unchanged — without a pixel and without rewritten links. Sending succeeds, the reports show an engagement dip, and the cause is sought in anything but markup parsing.
How to spot itOpens and clicks dropped for one mailing, while delivery is normal.
How to do it rightChoose the behavior deliberately and watch the log: the parsing error gets into it with either option.

Tracking the unsubscribe link

§ 11.1.6.2.3

What it costsA click on it goes through the tracking domain — an extra point of failure where failure is most expensive. A recipient whose unsubscribe page did not open clicks “spam.”
How to spot itThe complaint rate is higher than usual for mailings with tracking enabled.
How to do it rightExclude the unsubscribe link with an attribute in the markup: the engine will remove it from the delivered message.

Putting the pixel only at the top

§ 11.1.6.2.3

What it costsSome mail clients truncate long messages, and the bottom part loads on a button click. The bottom pixel fires less often, but the top one does not always survive until display either — both are more reliable.
How to spot itThe open rate is noticeably lower than expected with normal delivery.
How to do it rightEnable both positions: the switches are independent, and the cost of the second pixel is negligible.
Compatibility
PowerMTA 6.0
described in the manual of this version · platform: any
The vendor does not state the first version for every directive — there is no note here. The name also appears in the 5.0 edition of the manual.
Inheritance
The mechanism has no inheritance — its settings live in the analytics block at the root of the file. The only inherited thing is whether the export is enabled at all: the service switch works at three levels — node, address pool, individual address. A disabled export also disables tracking.
How to check on the node
Check the delivered message, not the configuration:
grep -n -A6 '^<signals' /etc/pmta/config
dig +short track.example.com
The first shows whether tracking is enabled at all. The second shows where the tracking domain actually points: recipients’ clicks will go exactly there. The rewritten links themselves are visible only in the delivered message.
In the Hub
Cost of a mistake
dangerous: effects outlast a rollback
Scenarios
Tracking infrastructure