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

  1. 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.
  2. Pick the Survey template (skip if you used the deep link above).
  3. Set the survey title, description, submit-button label, and thank-you message in the builder panel.
  4. Add as many questions (steps) as you need. Drag to reorder.
  5. Configure trigger, position, schedule, and targeting like any other floating message.
  6. Save and embed — visitors see the survey on your site.

Question types

TypeDescriptionStored as
nps0–10 scale with “Not likely” / “Very likely” labels.number 0–10
rating1–N stars (configurable max, 3–10).number 1–max
single_choiceRadio-style picker from a list of custom options.string
multi_choiceCheckbox-style picker allowing multiple answers.string[]
short_textSingle-line free-text input.string
long_textMulti-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.