Knowledge base

Personalization inside the engine

mailmerge variables and parts
One message, many messages — substitution on the node side

The only capability the manual explicitly calls an advantage of the bindings over regular SMTP.

How it works. Each recipient has its own set of named variables. The message body is added with two different actions: as verbatim data or as merge data — and in the second case the variables are substituted at delivery, by the engine, not by the submitting system.

Why separate the two kinds of data. One message can hold both what must not be touched and what is personalized: the signature, the unsubscribe link and legal text are added verbatim, while the greeting and content are added via merge.

The savings are real. One submitted message serves many recipients: the body is transferred to the node once and expanded by the number of addresses on the node itself. That is exactly why the manual says the bindings are faster than a regular connection only in this case.

Line breaks inside a variable are written as escape sequences. The manual distinguishes a real line break from a literal backslash in its examples — and this is not pedantry: a mistake produces either a broken layout or service characters visible to the recipient.

Numbered parts exist for multipart merges: the first is implied, and each number is used once.

The main trap is substituting where substitution must not happen. Merge data is expanded in full, including anything in it that happens to look like a variable. A piece of the message added via merge “along with the rest” — legal text, an unsubscribe link, someone else’s layout — can be changed unexpectedly. The split into verbatim data and merge data exists precisely for this, and bypassing it “to keep things simple” is a sure way to get a corrupted message for some recipients.
What the Hub does. It does not use it — warm-up sends messages one recipient at a time, so there is nothing to expand.

In our setup personalization is done by the platform before submission: the message arrives at the node already assembled. This is deliberate — that way the content is visible in the preview and in the log before sending, rather than appearing at the last step inside the engine.

Merging would become interesting if the Hub itself sent large campaigns: then one transfer instead of a thousand would noticeably reduce traffic to the node. As long as submission is handled by the platforms, there is no gain.

Recommended values

What to add with what:

Part of the message Which action Why
greeting, per-recipient content merge data this is what the mechanism exists for
legal text, signature verbatim data must not change for anyone
unsubscribe link verbatim all the more so if it has special characters
layout from a third-party editor verbatim it may contain something resembling a variable

Check line breaks on a live message. An escape sequence and a literal backslash differ by one character, and the result is either a line break or characters visible to the recipient. This can be checked only by sending to yourself.

Merging also has to be allowed in the submission block (allow-mailmerge): without that the submitting system will not apply it.

The table and the advice to check line breaks on a live message are ours. From the manual here come the split into verbatim data and merge data, substitution at delivery, numbered parts and the caveat about writing line breaks.
Example configuration
# the recipient has its own variables, and one message is assembled
#   rcpt.defineVariable("name", "Maria")
#   msg.addMergeData("Hello, [name]!")
#   msg.addData("Best regards, the sales team")# the first body line will be substituted, the second will go out as is
The highlighted line is verbatim data: the engine does not touch it. The line above was added via merge, and the variable in it will be replaced at delivery, separately for each recipient.
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▶

Adding everything via merge

§ 7.4.19

What it costsMerge data is expanded in full. Legal text, an unsubscribe link or someone else’s layout that ends up in it can be changed wherever it happens to resemble a variable.
How to spot itSome recipients get the message with a corrupted piece — usually where the text had square brackets.
How to do it rightAdd everything that is not personalized as verbatim data. That is what the split between the two actions is for.

Writing a line break as a literal backslash

§ 7.4.19

What it costsInstead of a line break the recipient sees service characters, or the other way around — where a backslash was expected, you get a line break and a broken layout.
How to spot itThe delivered message shows service characters, or lines have run together.
How to do it rightCheck against the manual’s examples — it distinguishes these two cases — and verify by sending to yourself.

Submitting a merge without allowing it on the node

§ 3.3.7

What it costsThe submission block decides whether merging applies. Without permission the submitting system will not apply it, and the message will go out with template text instead of substituted values.
How to spot itRecipients see variable names instead of their own data.
How to do it rightAdd the permission to the submission block and check it before the mailing, not after.
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: variables belong to the recipient, data to the message, and both live only within one submission. On the node side there is only permission: the submission block decides whether merging applies at all, and that permission merges by the usual source rule.
How to check on the node
Check not the configuration but the result — by sending to yourself:
grep -n 'allow-mailmerge' /etc/pmta/config
pmta show jobs
The first shows whether merging is allowed in the submission block: without permission it simply will not apply. The substitution itself can be checked only with a delivered message — otherwise line breaks and special characters in variables cannot be seen.
In the Hub
Cost of a mistake
safe: a wrong value breaks nothing
Scenarios
Address warm-up · Connect a sending platform