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

# Informe de qüestionari: esquema JSON de respostes

> Referència de l'informe de qüestionari de Didit: seccions, elements, visibilitat condicional i respostes per element en decisions V3.

L'informe del qüestionari conté el formulari estructurat que es va mostrar a l'usuari, el camí que va seguir a través de qualsevol branca condicional i la resposta per a cada element visible. Es retorna per node, de manera que els fluxos de treball amb múltiples instàncies (per exemple, un qüestionari per UBO) inclouen una entrada per ocurrència.

![Informe del qüestionari KYC de Didit que mostra respostes estructurades, seccions i tipus d'elements](https://mintcdn.com/didit-0f962782/z6T2GHM4Zh-iSj-K/images/questionnaire-report.png?fit=max\&auto=format\&n=z6T2GHM4Zh-iSj-K\&q=85\&s=9e483a61e829c6b94dd2dc7592a2c59b)

## Visió general

Cada resposta del qüestionari descriu:

* La **versió del qüestionari** que va veure l'usuari (títol, descripció, idiomes, metadades de la versió, seccions).
* Els **elements visibles** per al camí que l'usuari va seguir realment a través del graf del formulari — els elements ocults per la lògica condicional s'ometen de la resposta.
* La **resposta** per a cada element interactiu visible, en l'estructura corresponent al seu `element_type`.
* Un únic **estat** per a la resposta en conjunt.

Els elements de maquetació es reestructuren en lloc de respondre's: cada `SECTION_HEADER` es converteix en un límit de secció (el seu títol i descripció passen a ser el `title`/`description` de la secció), mentre que `HEADING`, `PARAGRAPH` i `SEPARATOR` romanen a `items[]` sense la clau `answer` perquè l'informe mantingui la mateixa estructura visual que va veure l'usuari.

## On apareix

L'informe del qüestionari apareix com la matriu en plural **`questionnaire_responses[]`** a `GET /v3/session/{sessionId}/decision/`, tant per a sessions de KYC com de KYB, sempre que s'hagi executat una funcionalitat de qüestionari. El camp és `null` fins que com a mínim s'hagi iniciat una instància de qüestionari. Cada entrada conté un `node_id` perquè els fluxos de treball amb múltiples instàncies puguin desambiguar quin pas del graf l'ha generada.

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

## Estructura de l'element

Consulta la [Resposta del qüestionari a la referència de Models de dades](https://docs.didit.me/ca/reference/data-models.md#resposta-del-qüestionari) per a l'esquema canònic.

```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
}
```

Els elements `SECTION_HEADER` no apareixen mai a `items[]` — obren una nova secció i proporcionen el seu `title` i `description`.

### Tipus d'elements

| Tipus d'element | Estructura de la resposta | Notes |
| - | - | - |
| `SHORT_TEXT`, `LONG_TEXT` | `{ value: string }` | Text lliure. |
| `EMAIL`, `DATE_PICKER`, `TIME` | `{ value: string }` | Variants de text amb tipus. |
| `NUMBER` | `{ value: number }` | Número JSON — validat al servidor com a numèric. |
| `COUNTRY` | `{ value: string }` | Codi ISO 3166-1 alfa-3 (p. ex. `"ESP"`), validat al servidor. |
| `PHONE` | `{ value: { countryCode, callingCode, number } }` | Objecte de telèfon estructurat. |
| `ADDRESS` | `{ value: { street, streetExtraInfo, city, state, postalCode, country } }` | Objecte d'adreça estructurat. |
| `DROPDOWN`, `SINGLE_CHOICE` | `{ value: string, text?: string }` | `value` és el valor de l'opció; `text` s'omple quan l'opció seleccionada té `requires_text_input: true`. |
| `MULTIPLE_CHOICE` | `{ value: string[], text?: string }` | Matriu de valors d'opcions. |
| `CONSENT` | `{ value: boolean }` | Booleà JSON. |
| `FILE_UPLOAD`, `IMAGE` | `{ files: string[] }` | Cada entrada és un URL presignat. |
| `REPEATABLE_GROUP` | `{ items: Array<{ [fieldValue]: Answer }> }` | Un objecte per repetició, amb una clau corresponent al `value` de cada subcamp i el seu propi objecte de resposta. |
| `HEADING`, `PARAGRAPH`, `SEPARATOR` | *(sense clau `answer`)* | Són només elements de maquetació — es mantenen a `items[]` per conservar l'estructura. |

Un element interactiu visible que l'usuari no hagi respost mai es retorna amb `"answer": null`.

### Visibilitat condicional

Quan un qüestionari defineix un graf (lògica condicional), només s'inclouen els elements del camí que l'usuari ha seguit realment. Un element ocult per una branca que l'usuari no ha seguit **no** apareix a `sections[].items` — fins i tot si existeix a la plantilla. Les seccions que es queden sense cap element visible s'ometen completament.

## Valors d'estat

L'`status` a nivell de resposta és un de tres valors possibles. Internament, l'estat base (`Approved`, o `In Review` quan el flux de treball força la revisió manual) es combina amb qualsevol regla d'estat personalitzada coincident aplicant la precedència global de la plataforma Declined > In Review > Approved; posteriorment, un resultat `Declined` a nivell de qüestionari es transforma a `In Review` perquè els operadors en determinin la disposició final durant la revisió.

| Estat | Significat |
| - | - |
| `Not Finished` | L'usuari encara no ha enviat el qüestionari. |
| `In Review` | Enviat i pendent de revisió manual (el flux de treball força la revisió manual, o una regla d'estat ha escalat la resposta). |
| `Approved` | Enviat i acceptat. |

## Advertències

Els qüestionaris emeten un únic codi d'advertència, generat quan una **regla d'estat personalitzada** configurada al node del qüestionari coincideix amb una resposta:

| Etiqueta | Descripció |
| - | - |
| `CUSTOM_STATUS_RULE_TRIGGERED` | Una regla d'estat del flux de treball ha avaluat una resposta del qüestionari i ha canviat (o confirmat) l'estat de la funcionalitat. |

El camp `additional_data` de l'advertència inclou `field`, `operator`, `rule_value`, `actual_value`, `target_status` i `score` quan la regla en defineix un. El seu `log_type` segueix l'estat de destinació de la regla: `error` per a Declined, `warning` per a In Review, `information` en altres casos.

A diferència d'altres funcionalitats, l'entrada del qüestionari no incrusta una matriu `warnings[]` — els registres de regles activades s'enregistren a la sessió sota `feature: "QUESTIONNAIRE"` i es mostren a la pantalla de revisió de la Console (consulta també el [llistat d'advertències de Verificació d'empreses (KYB)](https://docs.didit.me/ca/business-verification/warnings.md#qüestionari); el mateix codi s'aplica a sessions de KYC).

## Exemple — Qüestionari d'origen dels fons

```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 — No finalitzat

```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"
    }
  ]
}
```

Quan l'usuari ha arribat al pas del qüestionari però encara no ha enviat les respostes, la resposta es retorna amb `status: "Not Finished"` i `"answer": null` a cada element visible. Una sessió que mai no ha arribat al pas no genera cap entrada en absolut — `questionnaire_responses` roman `null` quan no existeix cap instància.

## Notes

* **Les URL dels fitxers caduquen.** Les entrades a `answer.files` són URL presignades (validesa de 4 hores per defecte). Torna a cridar l'endpoint de decisió quan necessitis URL actualitzades.
* **Localització.** El `title`, la `description` i el `placeholder` de l'element, la `label` de l'opció i el `title`/`description` de la secció es retornen en anglès si el qüestionari ho admet; en cas contrari, es retornen en el `default_language` del qüestionari. El `value` d'una opció es manté estable en tots els idiomes, de manera que pots basar-hi la teva lògica de negoci de forma segura.
* **La `description` d'un element és el text d'ajuda de l'element.** Qualsevol element en pot tenir un, incloses les preguntes, i és `null` si no se n'ha definit cap. Un `SEPARATOR` mai no en té.

## Contingut relacionat

> [card] [Visió general de Qüestionaris](https://docs.didit.me/ca/core-technology/questionnaires/overview.md)
>
> Com crear, versionar i adjuntar qüestionaris a un flux de treball.

> [card] [Models de dades — Resposta del qüestionari](https://docs.didit.me/ca/reference/data-models.md#resposta-del-qüestionari)
>
> Esquema canònic camp per camp per a aquest objecte.

> [card] [Recuperar la sessió](https://docs.didit.me/ca/sessions-api/retrieve-session.md)
>
> Referència de l'endpoint per al payload de decisió V3.


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