Surveys
Ask a one-question survey inside an email and read the answers per campaign
A survey block turns a campaign into a one-question poll. Recipients answer by clicking an answer directly in their inbox — there is nothing to load, no form to fill in, and no account to create. Answers land on the campaign's Survey tab, on each subscriber's timeline, and in subscriber filters.
See every style with a screenshot on the Surveys gallery.
Adding a survey
In the campaign editor, open the slash menu (/) and pick Survey. Each
block holds one question and its answers. One campaign can carry several survey
blocks; each one is tracked separately.
| Style | What the recipient sees |
|---|---|
| Buttons | Answers stacked as equal-width buttons, labels left-aligned |
| Yes / No | Two stacked equal-width answers. Switching to it rewrites the first two options as Yes / No |
| Emoji | Stacked answers prefixed with an emoji you choose |
| NPS | A fixed 0–10 scale, left-aligned with the question |
Block settings
Click the block to open the toolbar.
| Setting | Values / behavior | Default |
|---|---|---|
| Style | buttons · yes_no · nps · emoji | buttons |
| Comment | allowComment — free-text note after the vote, max 1000 characters | false |
| Alignment | left · center · right. Moves the question and the NPS row. Stacked answers stay full width | left |
| Button color | Fill of each answer. Falls back to the theme button color | #000000 |
| Text color | Label color inside each answer | #ffffff |
| Show if | Tag conditions (showIfConditions). Same visibility rules as a Section | always shown |
| NPS low caption | npsLowLabel — under 0. null uses the recipient's language | null |
| NPS high caption | npsHighLabel — under 10. Same fallback | null |
NPS options are virtual (nps_0 … nps_10) and are not stored on the block.
Yes / No only sends the first two options; extra options stay on the block if
you switch back to Buttons.
Colors, alignment and Show if are presentation. Changing them does not create a new survey version. Changing the question, style, answers, comment toggle or NPS captions does.
Limits
| Thing | Limit |
|---|---|
| Answers | 2–8 (buttons, yes_no, emoji). NPS is fixed at 0–10 |
| Question | 1–300 characters, required to send |
| Answer label | 120 characters |
| NPS captions | 60 characters each |
| Comment | 1000 characters |
surveyId | svy_ + 10 alphanumeric characters, unique in the document |
Option id | Stable string, max 64 characters. Never reuse across options |
The editor can hold an incomplete survey. Sending (schedule, send now, API, workflow publish) rejects a block with no question, fewer than two labelled answers, a duplicated id, or merge fields in immutable text.
TipTap node
Campaigns, workflow emails and the Tiptap send API
all use the same node. Insert it as a top-level block, or inside a section /
column — never inside a repeat.
{
"type": "survey",
"attrs": {
"surveyId": "svy_abcdefghij",
"question": "What should we write about next?",
"style": "buttons",
"allowComment": false,
"alignment": "left",
"buttonColor": "#000000",
"textColor": "#ffffff",
"npsLowLabel": null,
"npsHighLabel": null,
"options": [
{ "id": "opt_a1b2c3d4e5", "label": "Talk about AI", "emoji": "🤖" },
{ "id": "opt_f6g7h8i9j0", "label": "No AI please", "emoji": "🙅" }
]
}
}
| Attr | Required | Notes |
|---|---|---|
surveyId | yes | Mint once. Copying a campaign regenerates it so results do not pool |
question | yes | No {{variables}} |
style | no | buttons (default), yes_no, nps, emoji |
options | yes* | 2–8 items with unique id + label. Ignored for nps |
options[].emoji | no | Printed only when style is emoji |
allowComment | no | false by default |
npsLowLabel | no | Author caption, or null to translate |
npsHighLabel | no | Same |
alignment | no | left (default), center, right |
buttonColor | no | Hex. null uses the theme |
textColor | no | Hex. null is white |
showIfConditions | no | Same shape as a Section |
Do not put {{name}} (or any merge field) in the question, labels or NPS
captions. Results need one immutable label shared by every recipient.
What the recipient sees
Clicking an answer opens a small confirmation page and records the answer. The question and the answers sit in a bordered card — the same chrome as the editor — so the poll reads as one block in the inbox. Opening that page never records anything on its own — the answer is only saved once the page confirms it, so a mail scanner that pre-fetches every link in your email does not pollute your results.
After answering, the recipient can change their mind: picking another answer replaces the previous one. Only their latest answer counts. They can add, edit or clear a comment (empty submit clears it) even without JavaScript.
Test sends use an inert /s/test link that records nothing.
Reading the results
Open the campaign, then the Survey tab. For every survey block you get:
- the number of answers, and what share of the delivered emails that is;
- one bar per answer, with its count and percentage;
- for NPS, the score (
% promoters − % detractors), where 9–10 are promoters, 7–8 passives and 0–6 detractors; - the comments, newest first, each next to the answer it came with.
Answers to an option you have since deleted are still counted and shown, marked as removed. Nothing is ever silently dropped from your totals.
Automated answers
Some answers are not human — link scanners in corporate mail gateways click every URL in a message. Lumail flags an answer as automated when it comes from a known bot user agent, when it arrives implausibly soon after the email was sent, or when one IP address exceeds 120 answers per minute.
Flagged answers are stored but excluded from every count, percentage and NPS score, and the results page tells you how many were excluded. Bot-only rows count as unanswered for filters.
Filtering subscribers on an answer
In Subscribers, add a Survey filter and pick a survey.
| Operator | Matches |
|---|---|
ANSWERED | Anyone who answered this survey |
NOT_ANSWERED | Anyone who did not (including bot-only rows) |
ANSWERED_WITH | Current answer is this option (optionId required) |
NOT_ANSWERED_WITH | Current answer is not this option |
Answer identity is stable: renaming an answer, reordering the list, or editing
the question keeps every filter and every recorded answer pointing at the same
option. Deleting an option makes ANSWERED_WITH stop matching it.
Filter payload (audience filters, campaign recipient filters, tools):
{
"type": "SURVEY",
"field": "survey",
"surveyId": "svy_abcdefghij",
"surveyName": "What should we write about next?",
"operator": "ANSWERED_WITH",
"optionId": "opt_a1b2c3d4e5",
"optionLabel": "Talk about AI"
}
surveyName and optionLabel are display-only. Matching uses surveyId and
optionId.
Automations
A survey answer emits two things:
- a
SURVEY_ANSWEREDentry on the subscriber's timeline, carrying the question and the answer as the recipient saw them; - a
subscriber.survey.answeredworkflow trigger, so a workflow can react to a specific answer.
Both fire on the first genuine answer only. Changing an answer updates the result but never re-enrolls the subscriber into a workflow they already went through.
Workflow trigger params
On a trigger that listens to subscriber.survey.answered:
| Event filter | Required | Effect |
|---|---|---|
| (none) | — | Starts on every survey answer in the organization, including surveys created later. Do not leave this empty unless that is the intent |
surveyId | no | Restrict to one survey |
optionId | no | Restrict to one answer. Requires surveyId |
{
"surveyId": "svy_abcdefghij",
"optionId": "opt_a1b2c3d4e5"
}
Pin the survey. Duplicating a campaign mints a fresh surveyId but keeps
option ids, so an unscoped trigger on a copied campaign would not enrol into
the original's workflow — unless you forgot surveyId and matched every
survey in the org.
See Workflow Triggers.
Editing a survey after sending
Once a campaign is sent, its survey block is frozen: the question and the answers can no longer be changed. Everything else about the campaign — its name, its subject, the rest of its content — stays editable. Recolor and realign still work; they do not change recorded answers.
To ask a different question, duplicate the campaign; the copy starts a fresh
survey with its own results (surveyId is regenerated, option ids are kept).
In a workflow, where the same email keeps going out over time, editing the survey creates a new version. Older answers stay attached to the version the recipient actually received, and the results page merges them by answer.
Related
- Surveys gallery — screenshots of all four styles
- Send Email in Tiptap —
surveynode - Workflow Triggers —
subscriber.survey.answered - Subscriber Events — timeline