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

# Rapport de questionnaire : schéma JSON des réponses

> Rapport de questionnaire Didit : sections, types d'éléments, visibilité conditionnelle et réponses JSON par élément dans les décisions V3.

Le rapport de questionnaire contient le formulaire structuré présenté à un utilisateur, le chemin qu'il a emprunté à travers les éventuelles branches conditionnelles, ainsi que la réponse pour chaque élément visible. Il est renvoyé par nœud, de sorte que les workflows multi-instances (par exemple, un questionnaire par UBO) comportent une entrée par occurrence.

![Rapport de questionnaire KYC Didit présentant les réponses structurées, les sections et les types d'éléments](https://mintcdn.com/didit-0f962782/z6T2GHM4Zh-iSj-K/images/questionnaire-report.png?fit=max\&auto=format\&n=z6T2GHM4Zh-iSj-K\&q=85\&s=9e483a61e829c6b94dd2dc7592a2c59b)

## Vue d'ensemble

Chaque réponse au questionnaire décrit :

* La **version du questionnaire** vue par l'utilisateur (titre, description, langues, métadonnées de version, sections).
* Les **éléments visibles** correspondant au chemin réellement emprunté par l'utilisateur dans le graphe du formulaire — les éléments masqués par la logique conditionnelle sont retirés de la réponse.
* La **réponse** pour chaque élément interactif visible, sous la forme correspondant à son `element_type`.
* Un unique **statut** pour l'ensemble de la réponse.

Les éléments de mise en page sont restructurés plutôt que de faire l'objet d'une réponse : chaque `SECTION_HEADER` devient une délimitation de section (son titre et sa description deviennent les `title`/`description` de la section), tandis que `HEADING`, `PARAGRAPH` et `SEPARATOR` restent dans `items[]` sans clé `answer`, afin que le rapport conserve la même structure visuelle que celle vue par l'utilisateur.

## Où il apparaît

Le rapport de questionnaire apparaît sous la forme du tableau **`questionnaire_responses[]`** dans `GET /v3/session/{sessionId}/decision/`, aussi bien pour les sessions KYC que KYB, dès lors qu'une fonctionnalité de questionnaire a été exécutée. Le champ vaut `null` tant qu'aucune instance de questionnaire n'a démarré. Chaque entrée comporte un `node_id` afin que les workflows multi-instances puissent lever toute ambiguïté sur l'étape du graphe qui l'a produite.

```text theme={null}
GET /v3/session/{sessionId}/decision/
  ──▶ { "questionnaire_responses": [ { node_id, questionnaire_id, title, status, sections, … }, … ] }
```

## Structure d'un élément

Consultez [Réponse de questionnaire dans la référence des modèles de données](https://docs.didit.me/fr/reference/data-models.md#réponse-au-questionnaire) pour le schéma canonique.

```typescript theme={null}
interface QuestionnaireResponse {
  questionnaire_id: string;          // UUID of the questionnaire version that was answered
  title: string;                     // Questionnaire name, as set in the Console
  description: string | null;
  languages: string[];               // Supported language codes
  default_language: string;          // Default language code
  is_active: boolean;
  is_simple_questionnaire: boolean;  // true = flat list, false = branching graph
  questionnaire_group_id: string;    // UUID shared by all versions of the same questionnaire
  version: number;                   // Version number within the group
  published_at: string | null;       // ISO 8601 — when this version was published
  status: "Approved" | "In Review" | "Not Finished";
  sections: Array<{
    title: string | null;            // From the SECTION_HEADER that opens the section
    description: string | null;
    items: QuestionnaireItem[];
  }>;
  node_id: string | null;            // Workflow graph node that ran this questionnaire
}

interface QuestionnaireItem {
  uuid: string;                      // Form element UUID
  value: string;                     // Stable node id of the element within the questionnaire graph
  element_type:
    | "SHORT_TEXT" | "LONG_TEXT"
    | "DROPDOWN" | "SINGLE_CHOICE" | "MULTIPLE_CHOICE"
    | "NUMBER" | "EMAIL" | "PHONE" | "ADDRESS" | "COUNTRY"
    | "DATE_PICKER" | "TIME"
    | "CONSENT"
    | "FILE_UPLOAD" | "IMAGE"
    | "REPEATABLE_GROUP"
    | "HEADING" | "PARAGRAPH" | "SEPARATOR";   // layout-only — no answer key
  is_required: boolean;
  title: string | null;              // Localized
  description: string | null;        // Localized help text, or null when none is set
  placeholder: string | null;        // Localized
  choices: Array<{                   // DROPDOWN / SINGLE_CHOICE / MULTIPLE_CHOICE
    label: string;                   // Localized
    value: string;                   // Stable across languages
    requires_text_input?: boolean;   // Selecting this option triggers a free-text follow-up
  }> | null;
  max_files: number | null;          // FILE_UPLOAD / IMAGE upload cap (1–5)
  required_if: {                     // Conditional requirement rule, or null
    rules: Array<{ field: string; operator: string; value?: unknown }>;
    logic: "and" | "or";
  } | null;
  repeatable_config: {               // REPEATABLE_GROUP only, or null
    min_items?: number;
    max_items?: number;
    item_label?: string;             // Localized
    fields: Array<object>;           // Sub-field definitions (value, element_type, title, …)
  } | null;
  answer?: Answer | null;            // Omitted on HEADING / PARAGRAPH / SEPARATOR; null when unanswered
}
```

Les éléments `SECTION_HEADER` n'apparaissent jamais dans `items[]` — ils ouvrent une nouvelle section et fournissent ses `title` et `description`.

### Types d'éléments

| Type d'élément | Format de la réponse | Notes |
| - | - | - |
| `SHORT_TEXT`, `LONG_TEXT` | `{ value: string }` | Texte libre. |
| `EMAIL`, `DATE_PICKER`, `TIME` | `{ value: string }` | Variantes de texte typé. |
| `NUMBER` | `{ value: number }` | Nombre JSON — validé côté serveur comme étant numérique. |
| `COUNTRY` | `{ value: string }` | Code ISO 3166-1 alpha-3 (par ex. `"ESP"`), validé côté serveur. |
| `PHONE` | `{ value: { countryCode, callingCode, number } }` | Objet téléphone structuré. |
| `ADDRESS` | `{ value: { street, streetExtraInfo, city, state, postalCode, country } }` | Objet adresse structuré. |
| `DROPDOWN`, `SINGLE_CHOICE` | `{ value: string, text?: string }` | `value` est la valeur du choix ; `text` est renseigné lorsque le choix sélectionné a `requires_text_input: true`. |
| `MULTIPLE_CHOICE` | `{ value: string[], text?: string }` | Tableau de valeurs de choix. |
| `CONSENT` | `{ value: boolean }` | Booléen JSON. |
| `FILE_UPLOAD`, `IMAGE` | `{ files: string[] }` | Chaque entrée est une URL pré-signée. |
| `REPEATABLE_GROUP` | `{ items: Array<{ [fieldValue]: Answer }> }` | Un objet par répétition, indexé par la `value` de chaque sous-champ avec son propre objet de réponse. |
| `HEADING`, `PARAGRAPH`, `SEPARATOR` | *(pas de clé `answer`)* | Mise en page pure — conservée dans `items[]` pour la structure. |

Un élément interactif visible auquel l'utilisateur n'a jamais répondu est renvoyé avec `"answer": null`.

### Visibilité conditionnelle

Lorsqu'un questionnaire définit un graphe (logique conditionnelle), seuls les éléments situés sur le chemin réellement emprunté par l'utilisateur sont inclus. Un élément masqué par une branche que l'utilisateur n'a pas suivie n'apparaît **pas** dans `sections[].items` — même s'il existe dans le modèle. Les sections qui ne contiennent aucun élément visible sont totalement supprimées.

## Valeurs de statut

Le `status` au niveau de la réponse prend l'une des trois valeurs possibles. En interne, le statut de base (`Approved`, ou `In Review` lorsque le workflow impose un examen manuel) est combiné avec toute règle de statut personnalisée correspondante selon l'ordre de priorité global de la plateforme : Declined > In Review > Approved ; un résultat `Declined` au niveau du questionnaire est ensuite mis en correspondance avec `In Review` afin que les opérateurs déterminent la décision finale lors de l'examen.

| Statut | Signification |
| - | - |
| `Not Finished` | L'utilisateur n'a pas encore soumis le questionnaire. |
| `In Review` | Soumis et en attente d'examen manuel (le workflow impose un examen manuel, ou une règle de statut a fait remonter la réponse). |
| `Approved` | Soumis et accepté. |

## Avertissements

Les questionnaires émettent un unique code d'avertissement, généré lorsqu'une **règle de statut personnalisée** configurée sur le nœud du questionnaire correspond à une réponse :

| Balise | Description |
| - | - |
| `CUSTOM_STATUS_RULE_TRIGGERED` | Une règle de statut du workflow a évalué une réponse au questionnaire et a modifié (ou confirmé) le statut de la fonctionnalité. |

Le champ `additional_data` de l'avertissement contient `field`, `operator`, `rule_value`, `actual_value`, `target_status` et `score` lorsque la règle en définit un. Son `log_type` suit le statut cible de la règle : `error` pour Declined, `warning` pour In Review, `information` dans les autres cas.

Contrairement aux autres fonctionnalités, l'entrée du questionnaire n'intègre pas de tableau `warnings[]` — les journaux des règles déclenchées sont enregistrés sur la session sous `feature: "QUESTIONNAIRE"` et apparaissent dans l'écran d'examen de la Console (voir également la [liste des avertissements de vérification d'entreprise](https://docs.didit.me/fr/business-verification/warnings.md#questionnaire) ; le même code s'applique aux sessions KYC).

## Exemple — Questionnaire sur l'origine des fonds

```json theme={null}
{
  "questionnaire_responses": [
    {
      "questionnaire_id": "9f7485e0-b00b-4d56-9d3e-7859b68d1213",
      "title": "Source of Funds",
      "description": "Reply to this questionnaire to help us understand the source of funds.",
      "languages": ["en"],
      "default_language": "en",
      "is_active": true,
      "is_simple_questionnaire": true,
      "questionnaire_group_id": "2b6a9d40-13a8-4b1e-9a6c-3f1d2e4b5a60",
      "version": 1,
      "published_at": "2025-11-02T09:14:55.000000Z",
      "status": "Approved",
      "sections": [
        {
          "title": null,
          "description": null,
          "items": [
            {
              "uuid": "618636d9-7d5c-41ce-b8d0-1ab2a4be20db",
              "value": "question_1",
              "element_type": "DROPDOWN",
              "is_required": true,
              "title": "What is your primary source of funds?",
              "description": null,
              "placeholder": null,
              "choices": [
                { "label": "Salary", "value": "salary" },
                { "label": "Business Income", "value": "business_income" },
                { "label": "Savings", "value": "savings" },
                { "label": "Investments", "value": "investments" },
                { "label": "Inheritance/Gift", "value": "inheritance_gift" },
                { "label": "Other", "value": "other", "requires_text_input": true }
              ],
              "max_files": 1,
              "required_if": null,
              "repeatable_config": null,
              "answer": { "value": "salary" }
            },
            {
              "uuid": "2d16b527-72be-42e0-8e96-b164b818386c",
              "value": "question_2",
              "element_type": "LONG_TEXT",
              "is_required": true,
              "title": "Provide details of the primary source.",
              "description": null,
              "placeholder": null,
              "choices": null,
              "max_files": 1,
              "required_if": null,
              "repeatable_config": null,
              "answer": { "value": "Software engineer at Acme Ltd since 2018." }
            },
            {
              "uuid": "1bf8a2a3-14ee-48a8-bb3d-175481aae4aa",
              "value": "question_3",
              "element_type": "SINGLE_CHOICE",
              "is_required": true,
              "title": "Will any funds originate from third parties?",
              "description": null,
              "placeholder": null,
              "choices": [
                { "label": "Yes", "value": "yes", "requires_text_input": true },
                { "label": "No", "value": "no" }
              ],
              "max_files": 1,
              "required_if": null,
              "repeatable_config": null,
              "answer": { "value": "yes", "text": "One-off gift from parents, EUR 8,000." }
            },
            {
              "uuid": "a90a073d-e098-404c-bbce-5130d8b12a13",
              "value": "question_4",
              "element_type": "FILE_UPLOAD",
              "is_required": true,
              "title": "Upload a proof of funds document",
              "description": null,
              "placeholder": null,
              "choices": null,
              "max_files": 3,
              "required_if": null,
              "repeatable_config": null,
              "answer": {
                "files": [
                  "https://<media-host>/.../payslip-jul.pdf",
                  "https://<media-host>/.../payslip-aug.pdf"
                ]
              }
            }
          ]
        }
      ],
      "node_id": "feature_questionnaire"
    }
  ]
}
```

## Exemple — Non terminé

```json theme={null}
{
  "questionnaire_responses": [
    {
      "questionnaire_id": "9f7485e0-b00b-4d56-9d3e-7859b68d1213",
      "title": "Source of Funds",
      "description": "Reply to this questionnaire to help us understand the source of funds.",
      "languages": ["en"],
      "default_language": "en",
      "is_active": true,
      "is_simple_questionnaire": true,
      "questionnaire_group_id": "2b6a9d40-13a8-4b1e-9a6c-3f1d2e4b5a60",
      "version": 1,
      "published_at": "2025-11-02T09:14:55.000000Z",
      "status": "Not Finished",
      "sections": [
        {
          "title": null,
          "description": null,
          "items": [
            {
              "uuid": "618636d9-7d5c-41ce-b8d0-1ab2a4be20db",
              "value": "question_1",
              "element_type": "DROPDOWN",
              "is_required": true,
              "title": "What is your primary source of funds?",
              "description": null,
              "placeholder": null,
              "choices": [
                { "label": "Salary", "value": "salary" },
                { "label": "Other", "value": "other", "requires_text_input": true }
              ],
              "max_files": 1,
              "required_if": null,
              "repeatable_config": null,
              "answer": null
            }
          ]
        }
      ],
      "node_id": "feature_questionnaire"
    }
  ]
}
```

Lorsque l'utilisateur a atteint l'étape du questionnaire mais n'a pas encore soumis de réponses, la réponse est renvoyée avec `status: "Not Finished"` et `"answer": null` sur chaque élément visible. Une session qui n'a jamais atteint cette étape ne génère aucune entrée — `questionnaire_responses` reste `null` lorsqu'aucune instance n'existe.

## Remarques

* **Les URL de fichiers expirent.** Les entrées dans `answer.files` sont des URL pré-signées (validité de 4 heures par défaut). Appelez à nouveau l'endpoint de décision lorsque vous avez besoin d'URL actualisées.
* **Localisation.** Les champs `title`, `description` et `placeholder` de l'élément, le `label` du choix, ainsi que les champs `title`/`description` de la section sont renvoyés en anglais lorsque le questionnaire le prend en charge, sinon dans la `default_language` du questionnaire. La `value` d'un choix reste stable d'une langue à l'autre, vous permettant de fonder votre logique métier sur celle-ci en toute sécurité.
* **La `description` de l'élément correspond à son texte d'aide.** Tout élément peut en comporter une, questions comprises, et elle vaut `null` lorsqu'aucune n'est définie. Un élément `SEPARATOR` n'en a jamais.

## Pages associées

> [card] [Vue d'ensemble des questionnaires](https://docs.didit.me/fr/core-technology/questionnaires/overview.md)
>
> Comment concevoir, versionner et associer des questionnaires à un workflow.

> [card] [Modèles de données — Réponse au questionnaire](https://docs.didit.me/fr/reference/data-models.md#réponse-au-questionnaire)
>
> Schéma canonique champ par champ pour cet objet.

> [card] [Récupérer la session](https://docs.didit.me/fr/sessions-api/retrieve-session.md)
>
> Référence de l'endpoint pour le payload de décision V3.


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