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

# 설문지 보고서: 답변 JSON 스키마

> Didit의 V3 결정 응답 내 섹션, 항목, 요소 유형, 조건부 표시 및 항목별 답변을 다루는 설문지 보고서 레퍼런스입니다.

설문지 보고서에는 사용자에게 표시된 구조화된 양식, 조건부 분기를 거친 경로, 표시된 각 항목에 대한 답변이 포함됩니다. 노드별로 반환되므로 다중 인스턴스 워크플로(예: UBO당 하나의 설문지)의 경우 발생 건당 하나의 항목이 전달됩니다.

![Didit KYC questionnaire report showing structured answers, sections and element types](https://mintcdn.com/didit-0f962782/z6T2GHM4Zh-iSj-K/images/questionnaire-report.png?fit=max\&auto=format\&n=z6T2GHM4Zh-iSj-K\&q=85\&s=9e483a61e829c6b94dd2dc7592a2c59b)

## 개요

각 설문지 응답에는 다음 내용이 포함됩니다.

* 사용자가 본 **설문지 버전**(제목, 설명, 언어, 버전 메타데이터, 섹션).
* 양식의 그래프를 통해 사용자가 실제로 거친 경로의 **표시된 항목** — 조건부 로직에 의해 숨겨진 항목은 응답에서 제외됩니다.
* 표시된 모든 대화형 항목에 대한 `element_type`과 일치하는 형태의 **답변**.
* 응답 전체에 대한 단일 **상태**.

레이아웃 요소는 답변되지 않고 형태가 재구성됩니다. 각 `SECTION_HEADER`는 섹션 경계가 되며(해당 제목과 설명은 섹션의 `title`/`description`이 됨), `HEADING`, `PARAGRAPH`, `SEPARATOR`는 보고서가 사용자가 본 것과 동일한 시각적 구조를 유지하도록 `answer` 키 없이 `items[]`에 유지됩니다.

## 표시 위치

설문지 보고서는 설문지 기능이 실행되었을 때 KYC 및 KYB 세션 모두에서 `GET /v3/session/{sessionId}/decision/`의 복수형 배열 **`questionnaire_responses[]`**로 표시됩니다. 이 필드는 최소 하나의 설문지 인스턴스가 시작될 때까지 `null`입니다. 각 항목에는 `node_id`가 포함되어 다중 인스턴스 워크플로에서 어떤 그래프 단계가 이를 생성했는지 명확히 구분할 수 있습니다.

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

## 항목 구조

표준 스키마는 [데이터 모델 레퍼런스의 설문지 응답](https://docs.didit.me/ko/reference/data-models.md#설문지-응답)을 참고하십시오.

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

`SECTION_HEADER` 요소는 `items[]`에 나타나지 않으며, 새 섹션을 시작하고 해당 섹션의 `title`과 `description`을 제공합니다.

### 요소 유형

| 요소 유형 | 답변 형태 | 참고 사항 |
| - | - | - |
| `SHORT_TEXT`, `LONG_TEXT` | `{ value: string }` | 자유 형식 텍스트입니다. |
| `EMAIL`, `DATE_PICKER`, `TIME` | `{ value: string }` | 유형이 지정된 텍스트 변형입니다. |
| `NUMBER` | `{ value: number }` | JSON 숫자 — 서버 측에서 숫자로 유효성이 검사됩니다. |
| `COUNTRY` | `{ value: string }` | ISO 3166-1 alpha-3 코드(예: `"ESP"`), 서버 측에서 유효성이 검사됩니다. |
| `PHONE` | `{ value: { countryCode, callingCode, number } }` | 구조화된 전화번호 객체입니다. |
| `ADDRESS` | `{ value: { street, streetExtraInfo, city, state, postalCode, country } }` | 구조화된 주소 객체입니다. |
| `DROPDOWN`, `SINGLE_CHOICE` | `{ value: string, text?: string }` | `value`는 선택지 값입니다. 선택한 항목에 `requires_text_input: true`가 설정된 경우 `text`가 채워집니다. |
| `MULTIPLE_CHOICE` | `{ value: string[], text?: string }` | 선택지 값의 배열입니다. |
| `CONSENT` | `{ value: boolean }` | JSON 불리언입니다. |
| `FILE_UPLOAD`, `IMAGE` | `{ files: string[] }` | 각 항목은 사전 서명된 URL입니다. |
| `REPEATABLE_GROUP` | `{ items: Array<{ [fieldValue]: Answer }> }` | 각 반복에 대해 하나의 객체가 반환되며, 각 객체는 각 하위 필드의 `value`를 키로 하고 해당 하위 필드의 답변 객체를 값으로 합니다. |
| `HEADING`, `PARAGRAPH`, `SEPARATOR` | *(`answer` 키 없음)* | 순수 레이아웃 요소 — 구조를 위해 `items[]`에 유지됩니다. |

사용자가 답변하지 않은 표시된 대화형 항목은 `"answer": null`로 반환됩니다.

### 조건부 가시성

설문지에 그래프(조건부 로직)가 정의된 경우 사용자가 실제로 거친 경로의 항목만 포함됩니다. 사용자가 따르지 않은 분기에 의해 숨겨진 항목은 템플릿에 존재하더라도 `sections[].items`에 나타나지 **않습니다**. 표시된 항목이 남지 않은 섹션은 완전히 제거됩니다.

## 상태 값

응답 수준의 `status`는 세 가지 값 중 하나입니다. 내부적으로 기본 상태(워크플로에서 수동 검토를 강제하는 경우 `Approved` 또는 `In Review`)는 플랫폼 전체 우선순위인 Declined > In Review > Approved를 사용하여 일치하는 커스텀 상태 규칙과 결합됩니다. 그런 다음 검토 중에 운영자가 최종 처리를 진행할 수 있도록 설문지 수준의 `Declined` 결과는 `In Review`에 매핑됩니다.

| 상태 | 의미 |
| - | - |
| `Not Finished` | 사용자가 아직 설문지를 제출하지 않았습니다. |
| `In Review` | 제출 후 수동 검토 대기 중입니다(워크플로에서 수동 검토를 강제하거나 상태 규칙에 의해 응답이 에스컬레이션됨). |
| `Approved` | 제출 후 수락되었습니다. |

## 경고

설문지는 설문지 노드에 구성된 **커스텀 상태 규칙**이 답변과 일치할 때 생성되는 단일 경고 코드를 생성합니다.

| 태그 | 설명 |
| - | - |
| `CUSTOM_STATUS_RULE_TRIGGERED` | 워크플로 상태 규칙이 설문지 답변을 평가하고 기능 상태를 변경(또는 확인)했습니다. |

경고의 `additional_data`에는 `field`, `operator`, `rule_value`, `actual_value`, `target_status`, 그리고 규칙에 정의되어 있는 경우 `score`가 포함됩니다. 해당 `log_type`은 규칙의 대상 상태를 따릅니다. Declined의 경우 `error`, In Review의 경우 `warning`, 그 외의 경우 `information`입니다.

다른 기능과 달리 설문지 응답 항목에는 `warnings[]` 배열이 포함되지 않습니다. 트리거된 규칙 로그는 세션의 `feature: "QUESTIONNAIRE"` 아래에 기록되며 Console 검토 화면에 표시됩니다([기업 확인(KYB) 경고 목록](https://docs.didit.me/ko/business-verification/warnings.md#설문지) 참고, 동일한 코드가 KYC 세션에도 적용됨).

## 예시 — 자금 출처 설문지

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

## 예시 — 미완료

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

사용자가 설문지 단계에 도달했지만 아직 답변을 제출하지 않은 경우, 응답은 `status: "Not Finished"` 및 표시된 모든 항목에 대해 `"answer": null`로 반환됩니다. 해당 단계에 도달하지 않은 세션은 항목을 전혀 생성하지 않으며, 인스턴스가 존재하지 않는 경우 `questionnaire_responses`는 `null`로 유지됩니다.

## 참고 사항

* **파일 URL은 만료됩니다.** `answer.files`의 항목은 사전 서명된 URL입니다(기본 유효 기간 4시간). 최신 URL이 필요한 경우 결정 endpoint를 다시 호출하십시오.
* **현지화.** 항목의 `title`, `description`, `placeholder`, 선택지의 `label`, 섹션의 `title`/`description`은 설문지가 지원하는 경우 영어로 반환되며, 그렇지 않은 경우 설문지의 `default_language`로 반환됩니다. 선택지의 `value`는 언어와 관계없이 동일하게 유지되므로 이를 기반으로 비즈니스 로직을 안전하게 처리할 수 있습니다.
* **항목의 `description`은 요소의 도움말 텍스트입니다.** 질문을 포함한 모든 항목에 포함될 수 있으며, 설정되지 않은 경우 `null`입니다. `SEPARATOR`에는 절대 포함되지 않습니다.

## 관련 항목

> [card] [설문지 개요](https://docs.didit.me/ko/core-technology/questionnaires/overview.md)
>
> 설문지를 구성하고, 버전을 관리하며, 워크플로에 연결하는 방법입니다.

> [card] [데이터 모델 — 설문지 응답](https://docs.didit.me/ko/reference/data-models.md#설문지-응답)
>
> 이 객체에 대한 표준 필드별 스키마입니다.

> [card] [세션 조회](https://docs.didit.me/ko/sessions-api/retrieve-session.md)
>
> V3 결정 payload에 대한 endpoint 레퍼런스입니다.


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