> ## 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.

# Responses & Signals

> Read individual responses with their AI follow-up history, and route survey signals into Views and the rest of your analysis

## Responses vs Signals

BuildBetter deliberately keeps two numbers separate:

* **Responses received** — raw completed responses.
* **Signals generated** — extracted signals produced from those responses.

They are not the same, and a survey can score well on one and poorly on the other. Keeping them distinct means a survey that collected 40 responses but produced few signals is visible as exactly that, rather than hidden behind a single "results" count.

## Reading a Response

Response rows open the complete answer history for that respondent — including every AI follow-up, paired with the answer that triggered it. Because follow-ups are per-respondent and model-decided, two people who answered the same survey may show different chains, and comparing those chains is often where the useful detail is.

Answers are stored **incrementally** as the respondent moves through the survey. Completion marks the response and the recipient complete, attaches recipient metadata, and queues extraction.

<Info>
  A response is interpreted against the `survey_version` its recipient was pinned to. If you edited questions mid-flight, older responses are still read against the version they actually saw.
</Info>

## Signal Extraction

Completed **non-preview** responses queue `GenerateSurveyResponseExtractions`. The extraction worker:

1. Calls `extractSurveyResponse` for the response.
2. Creates an `extraction_job` keyed to the `survey_response_id`.
3. Inserts `extraction` rows tied to that response.
4. Creates citation rows pointing at the specific answer evidence.

The result is that a survey signal behaves like every other signal in BuildBetter — same signal tables, same token similarity scopes, same auto-fill jobs, same permission materialization. Signals cite the answer they came from, so you can trace any claim back to the respondent's words.

Preview and test responses never queue extraction and never bill.

## Connecting a Survey to a View

Connecting a survey to a View through a **View connection** makes that survey's response signals available in the View's analysis. This is how survey data joins your existing datasets rather than sitting in a separate silo — the same View that analyzes calls and documents can include survey signals once connected.

## When Things Are Blocked

The design goal is that a raw response is never lost, even when downstream work can't proceed:

| Situation                                | What happens                                                                                              |
| ---------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| Credits exhausted before extraction      | Response stays visible in Surveys; the extraction job stays retryable/blocked with a clear billing reason |
| Credits exhausted before a follow-up     | The answer saves and the survey continues; no follow-up is generated                                      |
| Follow-up model error                    | Answer saves, no fallback prompt shown, no follow-up billing                                              |
| Queue failure during extraction dispatch | The dispatch claim is released so a retry can pick it up                                                  |

<Note>
  Extraction dispatch is *claimed* before publishing, so successful retries cannot fan out duplicate extraction jobs for the same response. Concurrent answer retries likewise share one generated follow-up prompt and one charge.
</Note>

## Tracing a Response

Extraction jobs are tracked by survey id and response id specifically so the question "was this response actually analyzed?" has a definite answer. If a response looks like it produced nothing, that's the path to check — the response existing and the response having been extracted are separate facts.

## Next

<CardGroup cols={2}>
  <Card title="Settings & Billing" icon="gear" href="./settings-and-billing">
    What each outcome costs and how allowances are enforced.
  </Card>

  <Card title="Signals" icon="signal" href="../Signals/overview">
    How signals work across every BuildBetter source.
  </Card>
</CardGroup>
