Surveys
The Survey template is an all-in-one feedback builder. Use it for NPS, satisfaction ratings, polls, multi-question surveys, or open-ended research — all from the same template. Responses live in your dashboard with live aggregation and CSV export.
Creating a survey
- Open the message editor with the Survey template pre-selected: dashboard/messages?action=new&template=survey. Or go to Dashboard → Messages and click + New Message.
- Pick the Survey template (skip if you used the deep link above).
- Set the survey title, description, submit-button label, and thank-you message in the builder panel.
- Add as many questions (steps) as you need. Drag to reorder.
- Configure trigger, position, schedule, and targeting like any other floating message.
- Save and embed — visitors see the survey on your site.
Question types
| Type | Description | Stored as |
|---|---|---|
nps | 0–10 scale with “Not likely” / “Very likely” labels. | number 0–10 |
rating | 1–N stars (configurable max, 3–10). | number 1–max |
single_choice | Radio-style picker from a list of custom options. | string |
multi_choice | Checkbox-style picker allowing multiple answers. | string[] |
short_text | Single-line free-text input. | string |
long_text | Multi-line textarea for longer feedback. | string |
Toggle Required per question. Required questions block the visitor from advancing to the next step (or submitting the last step) until answered.
Multi-step flows
Add multiple questions to the same survey to build a multi-step flow. Visitors see one question at a time with:
- Progress dots at the top showing how many steps total and which step they're on.
- Back button (hidden on the first step) to revisit earlier answers.
- Next button on intermediate steps and Submit on the last step.
Per-step validation runs before advancing — required questions can't be skipped, NPS / rating / choice values must be valid, and text answers can't be all whitespace.
Survey config schema
Internally, surveys are stored as a JSON document on the message row. You normally edit them through the dashboard builder, but the schema is documented here for completeness:
type SurveyConfig = {
title: string;
description?: string;
submitLabel?: string; // default: "Submit"
thankYouMessage?: string; // shown after submit
steps: SurveyStep[];
};
type SurveyStep = {
id: string; // stable client UUID
question: string;
helpText?: string;
type:
| "nps"
| "rating"
| "single_choice"
| "multi_choice"
| "short_text"
| "long_text";
required: boolean;
options?: string[]; // for single_choice / multi_choice
max?: number; // for rating (default 5, range 3–10)
};Response storage
Each response is stored with a snapshot of the question text at submission time. This means you can edit the survey later (rename a question, reorder steps, change options) without breaking historical responses. Each entry in the JSON is keyed by the original step ID:
{
"stp_a1b2c3": {
"question": "How likely are you to recommend us?",
"type": "nps",
"value": 9
},
"stp_d4e5f6": {
"question": "What do you like most?",
"type": "multi_choice",
"value": ["Speed", "Customization"]
},
"stp_g7h8i9": {
"question": "Anything else?",
"type": "long_text",
"value": "Love the live preview in the editor."
}
}Aggregation
Open Dashboard → Surveys and pick a survey to see live aggregation cards, calculated client-side from the raw responses. Each step gets its own card based on its type:
- NPS — Net Promoter Score:
% promoters (9–10) − % detractors (0–6), plus a 0–10 distribution histogram. - Rating — average stars and total rating count.
- Single / Multi choice — bar chart of option counts (descending).
- Text — list of the 5 most recent text answers, with a count of how many more exist.
CSV export
Click Export CSV on the surveys page to download every response for the selected survey:
Date, Country, Page, Question 1, Question 2, Question 3, ...Each question column uses the snapshotted question text from the first response that included that step. Multi-choice answers are joined with semicolons.
Webhook forwarding
Survey messages reuse the same webhook URL field as contact forms. When set, FloatMessage POSTs every survey response to your endpoint:
{
"messageId": "msg_abc123",
"type": "survey_response",
"answers": {
"stp_a1b2c3": {
"question": "How likely are you to recommend us?",
"type": "nps",
"value": 9
}
},
"pageUrl": "https://example.com/dashboard",
"country": "US",
"submittedAt": "2026-04-10T18:42:31.123Z"
}The type field distinguishes survey payloads from regular contact-form payloads so a single webhook endpoint can handle both.