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

# Questions and questionnaires

> How Omneo captures structured feedback with reusable questions and versioned forms, and routes each answer to a profile, rating, transaction, or interaction.

A **Questionnaire** in Omneo is a versioned form built from reusable Questions. It is how the platform captures structured input from a customer: NPS and CSAT surveys, product and location ratings, profile updates, and the booking questions attached to an [appointment](/concepts/visits/appointments). The same model underpins every feedback surface, and each answer can be routed automatically to a destination such as a profile field, a Rating, a Transaction, or an Interaction.

## The three layers

| Layer             | What it is                                                                                                                                                         |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Question**      | A reusable definition: a stable `handle`, a `label`, an input `type`, `options`, and `validation`. Authored once, then referenced by any number of questionnaires. |
| **Questionnaire** | A form. An ordered set of questions, optionally attached to another object (such as an appointment definition) or used standalone, identified by its `purpose`.    |
| **Submission**    | One fill of a form. Records the answers plus the context they were collected in.                                                                                   |

## Questions

A Question is the definition of a single question, independent of any form. It carries:

* **Identity**: a unique `handle`, a human `name`, and an optional `description`.
* **Rendering**: a `label`, optional `help_text`, `icon`, and `image_url`, the input `type`, `options`, `validation`, and a `default_value`.
* **Link configuration**: where each answer is routed. See [Routing answers](#routing-answers).

Supported input types are `text`, `textarea`, `number`, `slider`, `boolean`, `single_select`, `multi_select`, `date`, `datetime`, `email`, `phone`, and `json`. A `slider` requires a `validation.min` and `validation.max`.

### Versioning

Questions are versioned. Editing a question's wording, type, or options creates a new immutable version and advances the question's current version. Answers already captured stay pinned to the version that was active when they were given, so changing a question never rewrites historical responses.

Link configuration is the exception: it lives on the question directly and is not versioned. Changing where answers are routed reroutes future submissions only. Past answers keep the destination they were written to.

## Questionnaires

A Questionnaire groups questions into a form. It has:

* A `name`, a `handle`, and a `purpose` that callers use to find the right form for a context (for example `booking` for an appointment form, or `general`, `survey`, `post_visit`, and `profile_onboarding` for standalone forms).
* An optional owner: a questionnaire can be attached to another object (such as an appointment definition), targeted at a specific profile, or float free as a global form.
* An ordered set of question slots, each pinning a specific question and version, with its own `mapping_key`, `sort_order`, required flag, and optional visibility condition.
* One or more **pages** for multi-step forms, plus **visibility conditions** that can reference earlier answers or profile attributes to show or hide questions dynamically.

Like questions, questionnaires are versioned: each change to the slot list creates a new version, and every submission is pinned to the version it was filled under. At most one active questionnaire exists per owner and purpose.

## Submissions

Each time a customer fills a form, Omneo records one submission capturing:

* Which form and version was filled, and which profile filled it.
* The **answerable**: what the answers are about (a profile, a transaction, a product variant, or an appointment).
* A **context** object holding resolution hints such as a related transaction or staff member.

A booking appointment and a standalone survey both create a submission. The answers then flow through the routing pipeline.

## Routing answers

Every question declares a `link_type` that decides what happens to its answer once captured. This is what turns a survey response into a Rating, or a profile-update form into an actual profile change.

| `link_type`        | Destination                                                                                                                                 |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `none`             | Captured only. No side effect.                                                                                                              |
| `profile`          | Written to the customer's profile. See [Routing to profiles](#routing-to-profiles).                                                         |
| `rating`           | Creates a [Rating](/concepts/ratings/nps) row. The `link_target` sets the score type: `nps`, `csat`, `ces`, `product`, `place`, or `staff`. |
| `transaction`      | Written into the related transaction's `meta`.                                                                                              |
| `transaction_item` | Written against a specific transaction line item.                                                                                           |
| `interaction`      | Appended as an [Interaction](/api-reference/interaction/browse-interactions) record.                                                        |
| `appointment`      | Written against the related appointment.                                                                                                    |
| `connection`       | Written against a profile [Connection](/concepts/profiles/connections).                                                                     |

Routing runs after the submission is saved, and each answer is routed independently: one answer failing to route does not affect the others. An answer ends in one of three states: `mapped` (the destination was written), `skipped` (nothing to write, for example a capture-only question), or `failed` (the write could not be applied).

### Routing to profiles

When `link_type` is `profile`, the `link_target` decides which part of the profile receives the answer:

| `link_target` shape                     | Destination                                                                                                                                                                  |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<column>`                              | A profile field, for example `first_name`.                                                                                                                                   |
| `attributes_comms.<column>`             | A [comms preference](/concepts/profiles/comms-preferences) attribute.                                                                                                        |
| `attributes_appearance.<column>`        | An [appearance attribute](/concepts/profiles/appearance-attributes).                                                                                                         |
| `custom_attribute.<namespace>.<handle>` | A [profile custom attribute](/concepts/profiles/custom-attributes). The namespace and handle are both required so different features can store attributes without colliding. |

A **write policy** controls whether an existing value is replaced:

| Policy                  | Behaviour                                                              |
| ----------------------- | ---------------------------------------------------------------------- |
| `overwrite_if_answered` | Write the new value whenever the question is answered.                 |
| `only_if_empty`         | Write only when the destination is currently empty.                    |
| `never_overwrite`       | Never write. The answer is captured but the profile is left untouched. |

This is how a profile-update questionnaire keeps a customer's details current, and how a styling survey can populate appearance attributes or custom attributes without manual data entry.

## How this relates to ratings

NPS, CSAT, and product or location ratings are all questionnaires whose questions route to `rating`. The questionnaire is the capture mechanism; the [Rating](/concepts/ratings/nps) is the stored result that feeds aggregations and reactions. See the individual rating concepts for what each score measures.

## Related

* [NPS](/concepts/ratings/nps)
* [CSAT](/concepts/ratings/csat)
* [Product ratings](/concepts/ratings/product-ratings)
* [Location ratings](/concepts/ratings/location-ratings)
* [Appointments](/concepts/visits/appointments)
* [Custom attributes](/concepts/profiles/custom-attributes)
* [Question API](/api-reference/question/browse-questions)
* [Questionnaire API](/api-reference/questionnaire/browse-questionnaires)
* [Submit questionnaire API](/api-reference/questionnaire-submission/submit-questionnaire)
