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

# First message

> Deliver an introduction or a GDPR notice on the session's first flow response, wherever the flow starts.

Conversational entry means the first thing a user hears is rarely the flow's first question. When the user opens with "I need home insurance for my flat at 12 rue de Rivoli, 75001 Paris", the model answers the `address`, `postcode` and `city` questions from that message without asking them, so its opening line to that user is "Is the flat owned or rented?", with no introduction and no data notice anywhere in the conversation. A node whose fields an action node already filled is skipped outright, with the same result.

`intro` fixes that. Declare it on the flow config and it is attached to whichever response the engine returns first for a session, then never again.

```ts theme={null}
createFlow({
  id: "home_quote",
  title: "Home insurance quote",
  description: "Quote a home insurance policy.",
  intro: {
    verbatim:
      "Acme Insurance is the data controller. Your answers are used for this quote only and deleted after 30 days.",
    instructions:
      "Introduce yourself as Léa from Acme in one short friendly sentence before the notice.",
  },
  state: { /* … */ },
})
```

The assistant's first turn then reads something like: "Hi, I'm Léa from Acme. Acme Insurance is the data controller. Your answers are used for this quote only and deleted after 30 days. Is the flat owned or rented?"

## verbatim and instructions

| Key | Behavior |
| - | - |
| `verbatim` | Reproduced word for word. No paraphrase, no translation, no reformatting, no merging into another sentence. |
| `instructions` | Guidance the assistant writes its own opening from. |

Set both and the assistant writes the prose around the notice from `instructions` while leaving the `verbatim` text untouched. Set one and it does only that. A bare string is shorthand for `verbatim`:

```ts theme={null}
intro: "Acme Insurance is the data controller. Your answers are deleted after 30 days."
```

Passing an empty `intro`, or an object with neither key, throws at `.compile()` rather than at conversation time.

> [!WARNING]
>
> `verbatim` is an instruction to a language model, not a rendering guarantee. It holds nearly always and it is the right tool for a notice you want stated up front. For a legal requirement where the exact characters must reach the screen every time, render the text from your own surface (a widget, or a message your backend prepends) instead of relying on the model.

## Once per conversation

Delivery is tracked in the flow store alongside `step` and `state`, under the session record's `internal` object. A new session starts with the intro pending there, and the engine drops it from `internal` once it is delivered. That object is engine bookkeeping grouped per feature, never flow state, so nothing in it reaches a node or can be written through `stateUpdates`. The engine attaches `intro` only while it is pending:

* The first `start` for a session carries it.
* Every following `continue` and `reset` leaves it out.
* A second `start` on the same session leaves it out. The user is not re-introduced because the model restarted the flow.
* `error` responses never carry it and leave it pending, so a failed call does not consume the intro.

Since the store keys on the session id, delivery is tracked per conversation rather than per flow. An assistant with several flows introduces itself on whichever one the user reaches first.

## Where it lands

`intro` rides on the response the engine was going to return anyway, so it costs no extra conversation turn and no skipped node can take it with it:

```json theme={null}
{
  "intro": {
    "verbatim": "Acme Insurance is the data controller. …",
    "instructions": "Introduce yourself as Léa from Acme …"
  },
  "status": "interrupt",
  "question": "What's the address?",
  "field": "address",
  "fieldSchema": { "type": "string", "description": "Street address" }
}
```

When the model answers that question from the user's message and resumes the flow straight away, the intro still opens the first message it writes to the user.

That includes the cases an intro node would miss. A flow whose first step is a widget carries the intro next to the widget instruction, and a `start` that runs to `END` because action nodes filled every field still carries it:

```json theme={null}
{
  "intro": { "verbatim": "Acme Insurance is the data controller. …" },
  "status": "complete"
}
```

## Delivery rules given to the model

A response that carries an `intro` also carries, in its `nextStep`, the rules for delivering it: at the very start of the model's next message to the user, before the question, before calling a widget tool, before presenting a result. They state that `verbatim` is word for word, that `instructions` govern the surrounding prose, and that the intro appears at most once per conversation and must not be repeated from earlier context. If the model resumes the flow before writing to the user, the intro opens the message it writes after that.

A flow without an `intro` carries neither the key nor the rules.

## Related

> **[State](https://docs.waniwani.ai/sdk/flows/state.md)**
>
> How the model fills fields the user already gave.

> **[Flow tool contract](https://docs.waniwani.ai/sdk/reference/flow-tool-contract.md)**
>
> The full response shape, including `intro`.


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