SendQL
Consent and membership
Subscriptions, opt-outs, suppression, and testing membership of a list or another segment.
Deliverability rules are not a separate system bolted onto SendQL. They are terms in the language, and they read like English.
Consent
Four forms, covering the four questions worth asking:
subscribed to "product-updates"
opted out of "promos"
unsubscribed from all
suppressed
A topic is a consent grouping — a subscription a contact can opt into or out
of independently of every other. subscribed to "marketing" and opted out of "marketing" are not quite negations of each other: the first asks about a
positive opt-in, the second about an explicit opt-out, and a contact who has done
neither is in neither set.
unsubscribed from all is the global opt-out — the “unsubscribe from everything”
link, not a per-topic preference.
suppressed is different in kind, and it is the one to understand. A
suppressed contact is one you cannot mail: a hard bounce, a spam complaint, a
manual block. It is not a preference, it is a deliverability fact, and ignoring
it is how a sender damages its reputation.
Which is why almost every segment you write should end the same way:
attr.plan = "trial" and not suppressed
Get in the habit. not suppressed costs six characters.
Membership
Two forms, both taking a quoted key:
in list "beta-testers"
in segment "power-users"
A list is a named bag of contacts — something you add people to, by hand or
from a workflow (add to list "engaged").
A segment is a saved SendQL query. in segment "power-users" composes one
segment into another, which is how you keep a complicated definition in one place
instead of copy-pasting a predicate into nine campaigns:
in segment "power-users" and not exists(activity.login within 30d)
Both compose with not:
in list "beta-testers" and not in segment "power-users"
They are strings, so they can be anything
Topics, lists and segments are all quoted strings, never bare identifiers. That is a deliberate design decision with a pleasant consequence: their names are not constrained by the language’s grammar at all.
subscribed to "timeout" and in list "count"
Both of those names are reserved words, and
both are perfectly fine, because a quoted string can never be confused with a
keyword. Hyphens, spaces and punctuation are equally unproblematic —
"product-updates" needs no escaping or special handling.
A realistic deliverability preamble
Putting the consent terms together with the rest of the language, a production-grade marketing segment usually looks something like this:
// Reachable, engaged, opted-in — and demonstrably not a lost cause.
subscribed to "marketing"
and not suppressed
and not unsubscribed from all
and count(bounce within 90d) = 0
and count(complaint) = 0
and count(open within 60d) >= 1
The last three lines are worth stealing. Filtering out recent bouncers and anyone who has ever complained, and requiring a single open in two months, is most of what list hygiene actually is — and here it is just five more terms in the same expression, checked by the same type checker as everything else.