✦ THE LANGUAGE BEHIND THE SUGGESTER
NLT — Natural Language Templating.
NLT is a templating language designed for customer communications. It reads like English, draws its grammar from Behaviour-Driven Development, and is the default language inside Synapse — generated for you by the Smart Suggester, executed by a production-grade engine. This page is the full story: the design philosophy, the complete syntax, and what the language can do.
Why a new templating language?
Every modern customer communications platform inherits its templating language from the engineering ecosystem it was built in. Most chose Jinja, Liquid, Handlebars, or EJS — languages designed by engineers, for engineers, in the late 2000s and early 2010s. Each is powerful. Each is also, for the marketers, lifecycle managers, and reviewers who actually run modern customer programs, an obstacle.
The result is a familiar pattern. The marketer drafts the message. The developer translates it into syntax. The QA cycle catches a missing brace, an unescaped variable, a broken conditional. The campaign ships late. Velocity is constrained not by strategy, not by data, not by creative — but by punctuation.
NLT was built to remove that constraint. The language is designed around a single principle: if you can describe what you want in plain English, you should be able to template it in plain English. The Smart Suggester makes the language easier to write; NLT itself makes the language easier to read. Together, they collapse the boundary between the people who design messages and the people who write them.
A borrowed idea from engineering.
NLT did not arrive at its design by accident. It draws directly from Behaviour-Driven Development — the testing practice that gave engineering teams executable specifications written in near-natural English (“Given the user is logged in, When they click Checkout, Then the cart should be displayed”).
BDD’s foundational insight was that the costliest miscommunications in software happen at the boundary between business intent and technical implementation. When the people who understand the customer and the people who write the code speak different languages, every translation step introduces ambiguity, error, and delay. BDD’s answer was a shared, executable vocabulary.
NLT applies that same insight to customer communications. The marketer writes the template. The developer reviews the template. The compliance team audits the template. Everyone is reading the same sentence, and the sentence happens to also be the program.
The same template, in two languages.
Below is the same set of operations written in Jinja2 — the standard most CCPs ship — and in NLT. Read both columns. The difference is not stylistic. It is the difference between a language designed for compilers and a language designed for humans.
Variables with fallbacks
{{ user.first_name | default("there") }}{the user's First Name, or "there"}Currency formatting
{{ "${:,.2f}".format(user.balance) }}{the user's Balance, as "currency"}Conditionals
{% if user.plan == "premium" %}
Welcome, VIP!
{% elif user.score > 80 %}
Almost there.
{% else %}
Upgrade today.
{% endif %}{if the user's Plan is premium}
Welcome, VIP!
{else if the user's Score is more than 80}
Almost there.
{else}
Upgrade today.
{end if}Loops with formatting
{% for item in user.orders[:3] %}
{{ item.name }}: ${{ "{:,.2f}".format(item.price) }}
{% endfor %}{for item in the user's Orders, show first 3}
{item.Name}: {item.Price, as "currency"}
{end for}Filter chains
{{ user.orders | selectattr("status", "eq", "active") | map(attribute="name") | sort | join(", ") }}{the user's Orders, where "status" is "active", map "name", sort, join ", "}Every NLT expression reads top to bottom, left to right. No pipe operators. No nested brackets. No format-string syntax to memorise. The marketer reads it. The developer reviews it. The compliance team audits it. One artifact, three readers, zero translation overhead.
A complete templating language. Just one you can read out loud.
NLT is not a stripped-down toy. Underneath the English-language surface is a full templating engine, with every primitive a production team expects — and a few that most engines never bothered to ship.
Variables: Three data sources
Access contact data, trigger event data, and named event data — all with the same readable syntax.
{the user's First Name} -- contact field
{the Order ID from the trigger event} -- event that triggered the flow
{the Amount from the latest payment event} -- specific named event
{the user's Address.City} -- nested propertiesConditionals: 19 comparison operators
Full conditional logic with operators that read like English.
{if the user's Plan is premium and the user's Last Purchase is within the last 30 days}
Thank you for your continued support.
{end if}Loops: Iterate with control
Loop variables, limit control, and empty fallbacks.
{for item in the user's Orders}
{loop.index}. {item.Name} -- {item.Price, as "currency"}
{else}
You have no orders yet.
{end for}19 chainable filters
String, array, and number transforms that chain left to right.
{the user's Bio, strip_html, truncate 100, trim}17 currency formats
USD, EUR, GBP, JPY, VND, and 12 more supported currencies.
{the user's Balance, as "currency"} -- $1,250.00 (USD default)
{the user's Balance, as "currency EUR"} -- 1.250,00 €
{the user's Balance, as "currency VND"} -- 1.250.000 ₫Math and aggregates
Arithmetic, variable assignment, and aggregate functions.
{the user's Subtotal times 1.08, as "currency"} -- tax calculation
{sum of the user's Order Totals, as "currency"} -- aggregate
{count of the user's Items, pluralize "item"} -- "3 items"NLT, written by selection.
NLT is designed to be readable, but you don’t have to write it from scratch. The Smart Suggester — Synapse’s in-editor authoring tool — generates every NLT construct for you. Pick a category, pick a feature, see the syntax with parameters and an example output, and press Enter. The Suggester is schema-aware: variables come from your live workspace data, not from a static reference. Most NLT templates inside Synapse are written without ever consulting documentation, because the Suggester is the documentation.
Synapse Chat, for the rest.
When you need to express intent in a sentence rather than pick from a list, Synapse Chat takes over. It reads your current template, understands NLT, and applies edits in place. Ask it to write a welcome email for premium users with their balance and recent orders, and it generates a complete NLT template — conditionals, currency formatting, loops included — and inserts it into the editor. Ask it why an email isn’t sending, and it detects the required modifier on a null field, explains the suppression, and suggests a fallback. The Suggester handles the routine. The Chat handles the rest.
A safety net the language enforces for you.
Mark any field as required. If the value is null when the email is about to send, NLT suppresses the entire message — subject line and body — and writes a structured log entry explaining why. Your customer never receives “Hi {{first_name}},” in their inbox. Your team gets a clear signal in the dashboard. The class of bug that has embarrassed every marketing team at least once is, in NLT, structurally impossible.
{the Reference Number from the trigger event, required}If Reference Number is missing, the email does not send. The log records: “Required attribute 'Reference Number' is missing.”
Security as a property of the language. Not a checkbox.
Every value rendered by NLT — whether it comes from a contact field, an event attribute, or a computed expression — is HTML-escaped by default. There is no “unsafe” mode. There is no flag to flip. Cross-site scripting, HTML injection, and broken markup from user-generated content are not configuration concerns in NLT, because the engine simply does not permit them. Security is a property of the language, not a setting on a form.
Write your first NLT template before your next stand-up.
Free tier: 2,000 emails/month, 2,000 contacts, every NLT capability available from the first send. No credit card required, no feature paywalls. Use NLT directly, or write Jinja and migrate later — both are first-class.