> ## Documentation Index
> Fetch the complete documentation index at: https://docs.buildbetter.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Creating Surveys

> Build a survey from a template or from scratch, choose question types, and configure AI follow-ups

Survey creation runs through a setup wizard at `/surveys/new`. It is template-first — you pick a starting point and adjust — but there is always an explicit path to build your own from an empty survey.

## Question Types

Native surveys store five primitives: `text`, `single_select`, `multi_select`, `rating`, and `nps`. The authoring UI exposes richer variants by saving presentation config on top of those primitives, so you get familiar survey building blocks without a separate data model:

| Family         | Variants available                                          |
| -------------- | ----------------------------------------------------------- |
| **Text**       | Long text, short text, email, URL, number, date             |
| **Choice**     | Single select, multi-select, dropdown, yes/no, image choice |
| **Scale**      | Rating, opinion scale, slider, NPS                          |
| **Structured** | Ranking, matrix / Likert, best-worst                        |

Answer validation runs server-side regardless of which variant you pick. It checks typed text formats, valid option ids, duplicate multi-selects, matrix row and column selections, and whether a required matrix was fully completed.

<Tip>
  Rating and NPS questions carry their own scale settings — the authoring controls expose them rather than flattening everything into a generic prompt. Set the scale deliberately; it affects how the response reads later.
</Tip>

## Question Descriptions

Non-follow-up questions can carry a description that renders on the respondent page beneath the question. Use it for context the question itself shouldn't have to carry ("we're asking because we're deciding what to build next quarter"), not for restating the question.

## Versioning and Edits

Questions are written into an immutable `survey_version` snapshot. This matters more than it sounds:

* A recipient is pinned to the version that existed **when they were added**.
* Editing questions after people have been invited does not change what an in-flight respondent sees.
* Responses and their extracted signals are interpreted against the recipient's snapshot version.

<Warning>
  Because recipients are pinned to a version, editing a live survey's questions produces a mixed dataset — early recipients answered a different version than late ones. If you need a clean comparison, launch a new survey rather than editing a running one.
</Warning>

Once a survey is launched, editing happens through a deliberate **edit mode** rather than inline, so a live survey can't be changed by accident.

## AI Follow-Ups

Any question can set `allow_ai_follow_up`. When enabled, and a respondent gives a low-detail answer, BuildBetter may generate one concise clarifying prompt.

The behavior worth understanding before you enable it:

* **The model decides.** It evaluates whether a follow-up would actually add anything. It frequently decides not to ask, and that is the intended behavior.
* **There is no canned fallback.** If the model suppresses a follow-up or the call fails, the answer saves and the respondent continues. You will never see a generic "Can you tell us more?" standing in for a real generated question.
* **Respondents can stop.** A respondent who declines or asks to stop will not be asked again.
* **Depth is capped.** You configure a maximum follow-up depth per survey, up to **5**. Set it to `0` to disable follow-ups entirely for that survey.

A follow-up answer can itself produce the next follow-up, chaining until the configured depth is reached.

### How follow-ups are stored

Follow-up answers are ordinary `survey_response_answer` rows carrying three extra fields:

* `parent_answer_id` — the answer that triggered this follow-up
* `prompt_text_override` — the generated question text
* `is_ai_generated_prompt` — flags it as model-generated

Generated prompts are deliberately **not** added to the shared survey version, because they are unique to one respondent. That is why two people answering the same survey can have different follow-up chains.

<Info>
  Follow-ups use `gpt-5-nano`. Raw survey answers and generated prompts are excluded from AI telemetry input/output capture. Each generated prompt costs 1 credit; suppressed, no-op, and failed decisions cost nothing. See [Settings & Billing](./settings-and-billing).
</Info>

## Duration Claims

Because follow-ups are dynamic, a survey's real length varies by respondent. Avoid promising a fixed completion time in your intro copy — a survey with follow-ups enabled genuinely does not have one.

## Creating Surveys Programmatically

MCP and Quick Agent create complete surveys in a single operation through `SurveyCompositionService` — delivery copy, questions, follow-up settings, branding, recipients, View connections, and optional activation together.

Failure handling is deliberately split:

* If branding, View connection, recipient import, or scheduling fails **before activation starts**, the whole survey and its child records are deleted and the original error is returned. You don't get a half-built survey.
* If something fails **after activation begins**, the survey and recipients are preserved so already-dispatched invitations stay valid and activation can be retried.

## Next

<CardGroup cols={2}>
  <Card title="Audience & Delivery" icon="paper-plane" href="./audience-and-delivery">
    Choose who gets it and how it reaches them.
  </Card>

  <Card title="Branding & Respondent Experience" icon="palette" href="./branding-and-respondent-experience">
    Control what the respondent actually sees.
  </Card>
</CardGroup>
