Lumail.io
DocsBlogChangelog
⌘K
IntroductionTutorialsAI IntegrationSDKAPI ReferenceIntegrationsFeaturesWorkflows

Tutorials

Create an API TokenSend Transactional Email with SMTPSend React Email Templates with LumailBuild a V0 Capture PageDynamic Promo Codes with Webhooks

AI Integration

Claude Code (Plugin)Codex (Plugin)ChatGPT PluginHermesSkills (CLI)OpenClawCursor (MCP)TypeScript SDK IntegrationsTools API (v2)Examples & Recipes

SDK

SDK IntroductionSDK ConfigurationSDK ResourcesSDK ToolsErrors and Retries

API Reference

API TokensTypeScript SDKCLIMCP ServerTools API (v2)Admin Tools APIRate LimitsSMTP EndpointPOSTSend Transactional EmailPOSTEmail Verification APIPOSTCreate SubscriberGETGet SubscriberPATCHUpdate SubscriberDELETEDelete SubscriberPOSTAdd Tags to SubscriberDELETERemove Tags from SubscriberPOSTTrack EventGETGet Subscriber EventsGETGet All TagsPOSTCreate a TagGETList All CampaignsPOSTCreate CampaignGETGet CampaignPATCHUpdate CampaignDELETEDelete CampaignPOSTSend CampaignSend Email in HTMLSend Email in MarkdownSend Email in TiptapGETList SubscribersGETGet Tag by ID or Name

Integrations

ClickFunnels IntegrationSystemIO Integration

Features

VariablesTag Action LinksSurveysContent Deliverability CheckerEmail Deliverability ScoreEmail Engagement ScoreSubscriber EventsRevenue TrackingEmail Sending Queue

Workflows

WorkflowWorkflow Getting StartedWorkflow TriggersWorkflow BranchingWorkflow A/B TestingWorkflow GoalsWorkflow Exit RulesWorkflow Publishing and VersionsWorkflow Test Runs and ResultsWait StepEmail StepAction StepWebhook StepWorkflow Groups

domains

Email DomainsWeb Domains

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.

StyleWhat the recipient sees
ButtonsAnswers stacked as equal-width buttons, labels left-aligned
Yes / NoTwo stacked equal-width answers. Switching to it rewrites the first two options as Yes / No
EmojiStacked answers prefixed with an emoji you choose
NPSA fixed 0–10 scale, left-aligned with the question

Block settings

Click the block to open the toolbar.

SettingValues / behaviorDefault
Stylebuttons · yes_no · nps · emojibuttons
CommentallowComment — free-text note after the vote, max 1000 charactersfalse
Alignmentleft · center · right. Moves the question and the NPS row. Stacked answers stay full widthleft
Button colorFill of each answer. Falls back to the theme button color#000000
Text colorLabel color inside each answer#ffffff
Show ifTag conditions (showIfConditions). Same visibility rules as a Sectionalways shown
NPS low captionnpsLowLabel — under 0. null uses the recipient's languagenull
NPS high captionnpsHighLabel — under 10. Same fallbacknull

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

ThingLimit
Answers2–8 (buttons, yes_no, emoji). NPS is fixed at 0–10
Question1–300 characters, required to send
Answer label120 characters
NPS captions60 characters each
Comment1000 characters
surveyIdsvy_ + 10 alphanumeric characters, unique in the document
Option idStable 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": "🙅" }
    ]
  }
}
AttrRequiredNotes
surveyIdyesMint once. Copying a campaign regenerates it so results do not pool
questionyesNo {{variables}}
stylenobuttons (default), yes_no, nps, emoji
optionsyes*2–8 items with unique id + label. Ignored for nps
options[].emojinoPrinted only when style is emoji
allowCommentnofalse by default
npsLowLabelnoAuthor caption, or null to translate
npsHighLabelnoSame
alignmentnoleft (default), center, right
buttonColornoHex. null uses the theme
textColornoHex. null is white
showIfConditionsnoSame 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.

OperatorMatches
ANSWEREDAnyone who answered this survey
NOT_ANSWEREDAnyone who did not (including bot-only rows)
ANSWERED_WITHCurrent answer is this option (optionId required)
NOT_ANSWERED_WITHCurrent 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_ANSWERED entry on the subscriber's timeline, carrying the question and the answer as the recipient saw them;
  • a subscriber.survey.answered workflow 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 filterRequiredEffect
(none)—Starts on every survey answer in the organization, including surveys created later. Do not leave this empty unless that is the intent
surveyIdnoRestrict to one survey
optionIdnoRestrict 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 — survey node
  • Workflow Triggers — subscriber.survey.answered
  • Subscriber Events — timeline
Tag Action LinksContent Deliverability Checker

On This Page

Adding a surveyBlock settingsLimitsTipTap nodeWhat the recipient seesReading the resultsAutomated answersFiltering subscribers on an answerAutomationsWorkflow trigger paramsEditing a survey after sendingRelated

Lumail.io

Email marketing for AI agents. Send newsletters, manage subscribers, and build campaigns with ChatGPT, Claude, Hermes, or OpenClaw.

Plugins

Claude pluginCodex pluginChatGPTCLI + skillsIn-app integration

Product

BlogDocumentationChangelogDashboard

Company

AboutAccount

Legal

TermsPrivacy

8 The Green STE B, Dover Delaware 19901, United States

© 2025 Codelynx, LLC. All rights reserved.

Sign in