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

# Survey messages

> Use SurveyMessage to add display-only, routable pages such as introductions, consent text, transitions, eligibility notices, and completion messages to an EDSL Survey.

`SurveyMessage` adds a page of information to a survey without asking for an answer. It has a `question_name` and a position in the survey, so you can show it at the start, between sections, or on a particular branch.

Use it for introductions, consent or privacy information, section transitions, eligibility notices, and thank-you pages.

When you need a recorded choice, such as agreement to participate, use a question with explicit answer options alongside the information. A message's continuation value records that the step was visited, rather than a substantive answer.

## Basic usage

```python theme={null}
from edsl import QuestionFreeText, Survey, SurveyMessage

welcome = SurveyMessage(
    question_name="welcome",
    question_text="Welcome. This survey takes about two minutes.",
)

feedback = QuestionFreeText(
    question_name="feedback",
    question_text="What could we improve?",
)

thanks = SurveyMessage(
    question_name="thanks",
    question_text="Thank you for your feedback.",
)

survey = Survey([welcome, feedback, thanks])
```

This defines a welcome page, one feedback question, and a closing page. A supported human survey interface displays the messages with **Continue** or **Finish**, without an answer box.

## Routing to a message

Because a message is a normal survey node, rules can route respondents to it by name. This example sends ineligible respondents to a terminal message while eligible respondents continue to a follow-up question:

```python theme={null}
from edsl import EndOfSurvey, QuestionFreeText, QuestionYesNo, Survey, SurveyMessage

eligible = QuestionYesNo(
    question_name="eligible",
    question_text="Are you at least 18 years old?",
)

follow_up = QuestionFreeText(
    question_name="experience",
    question_text="Tell us about your experience.",
)

ineligible = SurveyMessage(
    question_name="ineligible",
    question_text="You are not eligible for this survey. Thank you for your time.",
)

survey = Survey([eligible, follow_up, ineligible])
survey.add_rule(
    "eligible",
    "{{ eligible.answer }} == 'No'",
    next_question="ineligible",
)
survey.add_rule("experience", "True", next_question=EndOfSurvey)
```

The message participates in ordinary navigation, including back navigation and resume behavior in clients that support those features.

## Running with language models

The following uses the routing example above and a fixed test response of `No`; it makes no paid model calls. When an EDSL job reaches a `SurveyMessage`, EDSL records a deterministic response and continues without calling the language model:

```python theme={null}
from edsl import Cache, Model

results = survey.by(Model("test", canned_response="No")).run(
    cache=Cache(), disable_remote_inference=True,
    disable_remote_cache=True,
)
results.select("answer.ineligible")
```

If the message was visited, its recorded answer is `"continued"`. If routing skipped it, it has no response. The deterministic value makes the visited path observable in `Results` without spending inference tokens on display-only content.

## `SurveyMessage` versus `Instruction`

| Use | `SurveyMessage` | `Instruction` |
| - | - | - |
| Show a standalone page to a respondent | Yes | No |
| Route to or from the item by question name | Yes | No |
| Record that the item was visited | Yes, as `"continued"` | No |
| Supply context to later model questions | No | Yes |

Use `Instruction` when text should become model context for later questions. Use `SurveyMessage` when the text is itself a visible step in the survey experience.

For example, put an instruction before the questions it should affect:

```python theme={null}
from edsl import Instruction, QuestionFreeText, Survey

context = Instruction(name="context", text="Evaluate the proposed service as a new customer.")
feedback = QuestionFreeText(question_name="feedback", question_text="What is unclear?")
survey = Survey([context, feedback])
```

When assembling a survey incrementally, `survey.add_instruction(instruction)` appends an instruction at the current point; add the subsequent questions after it. Instructions do not produce answer columns.

## Human survey clients

Preview the survey with `survey.preview()` to check that the hosted interface displays the messages and follows the intended routes. Human survey interfaces must support the `survey_message` type. Messages need no answer-format settings in the Humanize schema because they collect no respondent input.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.