# Forms and Data Entry

The Forms and Data Entry module presents one or more custom form screens to collect information from a user. Responses are stored in the Session and can be retrieved via API.

Use this module when identity documents alone don't capture everything you need. Common use cases include collecting information not present on the user's ID (such as a residential address or a Brazilian CPF number), routing users to different verification paths based on citizenship or residency status, and gathering more information for enhanced due diligence.

## Integrations

:white_check_mark: Web | :white_check_mark: iOS | :white_check_mark: Android

## How It Works

When the Forms and Data Entry module runs, the user is presented with one or more pages of questions you configure. The module displays a title, if configured. It shows one question at a time or a set of questions per page, depending on how you set up the form.

By default, the module:

- Displays questions in the order they were configured, across one or multiple pages.
- Enforces required fields before allowing the user to proceed. **Continue** is disabled until all required inputs on the current page contain valid responses.
- Validates input in real time, showing inline errors for invalid entries: for example, an invalid email address or an out-of-range date.
- Stores all responses in the Session, where they can be reviewed on the [Other tab in single Session view](https://developer.incode.com/docs/single-session-view#other) and retrieved via the [Fetch Form Answers](https://developer.incode.com/reference/fetchformanswers) API.

{/* When Design creates a page for the Forms and Data Entry module, link to that instead and delete the below accordion with 2 images */}

<Accordion title="View an example form">
  <Image src="https://files.readme.io/472ef0a-Screenshot_2024-04-24_at_13.06.41.png" alt="The title asks the users to answer the following questions. Fields for email address, name, and date of birth appear." align="center" />
  <Image src="https://files.readme.io/3a9a2cc-Screenshot_2024-04-24_at_13.06.33.png" alt="Example form asking for country of residence, nationality, and any other nationality." align="center" />
</Accordion>

The module can also be configured to:

- Display a custom title at the top of the form or hide the title entirely.
- Spread questions across multiple pages, with **Continue** advancing the user between pages and **Done** completing the form on the final page.
- Mix pre-defined questions, which come with question text and input type already set, with custom questions, where you write the question text and select the input type.
- Mark individual questions as required or optional.

In Workflows, form responses can be used as [conditions](https://developer.incode.com/docs/configure-workflow-conditions). This allows you to route users to different verification paths based on their answers. For example, you can request additional documents from non-citizens or collect more information from users flagged for enhanced due diligence.

## Use Forms and Data Entry

For instructions on implementing and configuring Forms and Data Entry on each supported platform, use the following pages:

- [Forms and Data Entry (Dashboard)](https://developer.incode.com/docs/forms-and-data-entry-dashboard)
- Forms and Data Entry (iOS)
- Forms and Data Entry (Android)
- [Forms and Data Entry (Web SDK)](https://developer.incode.com/docs/forms-and-data-entry-web-sdk)

{/*
## End User Experience

The user experience (UX) for end-users utilizing the form module appears straightforward and intuitive based on the provided screenshots.

1. **Question and Answer Interface**:

   - Users are presented with a series of questions specified in the Forms Module Configuration. Each question has a dedicated input field that suggests the type of answer expected.
   - For text responses, such as "What is your email address?" or "What is your name?", users can type their information into text boxes.
   - The date of birth requires a specific format (DD/MM/YYYY), guiding users to enter their birthdate correctly.

2. **Selection Menus**:

   - For questions regarding the country of residence or nationality, users are given selection menus where they can choose from a list, indicated by dropdown arrows. This likely includes a search feature to find the correct country quickly.
   - Flags next to the country options provide a visual cue, aiding users in finding and selecting their country faster.
*/}

{/*
## Results API

Form responses collected during a session can be retrieved through the Results API. The endpoint returns all questions and answers a user provided during a given session, regardless of which form modules were used in their workflow, consolidated into a single response.<br />For the full endpoint specification, including parameters, headers, response structure, and example payloads, see <Anchor target="_blank" href="https://developer.incode.com/update/reference/fetchformanswers">Fetch Form Answers</Anchor> in the API reference.

- ### Endpoint Overview
  This API endpoint retrieves all questions and answers that a user has responded to during a specified session, regardless of the form module configurations used. It consolidates all the user's responses into one accessible API.
  #### URL
  `GET /omni/form/answers?interviewId=<interviewId>`
  #### Parameters
  - **interviewId**: This is a unique identifier for the session during which the user has provided responses. It is provided at the start of the session or forwarded via a redirect link when the user completes the session.
  #### Headers
  - **X-Api-Key**: Your unique API key.
  - **X-Incode-Hardware-Id**: A JWT token of ACCESS type. Note: Only Admin tokens are supported; Session tokens cannot be used to retrieve data.
  - **api-version**: 1.0
  ### Response Structure
  The response is structured as a JSON object containing an array of answers. Each object in the array represents a question and its corresponding response(s).
  - **answers**: Array of objects containing:
    - **question**: String. The question presented to the user.
    - **answerDetails**: Object containing:
      - **singleAnswer**: String. The user's answer to the question.
      - **selectedAnswers**: Array. List of selected answers (Note: This is currently unsupported and will always return an empty list).
    - **inputType**: String. Indicates the type of input used for the answer (e.g., EMAIL, TEXT, DATE, NUMBER, COUNTRY, YESNO).
  #### Note on `selectedAnswers`
  The `selectedAnswers` field is intended to support multiple selected answers for applicable questions. Currently, this functionality is not supported and will always return as an empty list.
  ### Date Format
  Dates in responses are returned as milliseconds since the Unix epoch (UTC). For example, the date "March 1, 1990" would be represented as `631152000000` milliseconds.
  #### Date Conversion Example
  To convert the millisecond timestamp to a human-readable date format in JavaScript:
```javascript
  function convertToDate(milliseconds) {
    const date = new Date(parseInt(milliseconds));
    return date.toISOString();  // Returns date in YYYY-MM-DDTHH:mm:ss.sssZ format
  }
```
  ### Country Code Format
  Country codes in responses are returned using ISO 3166-1 alpha-3 format. For example, "USA" for the United States of America, "GBR" for Great Britain.
  ### Example Response
```json
  {
      "answers": [
          {
              "question": "What is your email address?",
              "answerDetails": {
                  "singleAnswer": "John.smith@gmail.com",
                  "selectedAnswers": []
              },
              "inputType": "EMAIL"
          },
           {
              "question": "What is your name?",
              "answerDetails": {
                  "singleAnswer": "John Smith",
                  "selectedAnswers": []
              },
              "inputType": "TEXT"
          },
          {
              "question": "What is your date of birth?",
              "answerDetails": {
                  "singleAnswer": "631152000000",
                  "selectedAnswers": []
              },
              "inputType": "DATE"
          },
          {
              "question": "What is your ID number?",
              "answerDetails": {
                  "singleAnswer": "7389108462",
                  "selectedAnswers": []
              },
              "inputType": "NUMBER"
          },
          {
              "question": "What is your country of residence?",
              "answerDetails": {
                  "singleAnswer": "USA",
                  "selectedAnswers": []
              },
              "inputType": "COUNTRY"
          },
          {
              "question": "What is your nationality?",
              "answerDetails": {
                  "singleAnswer": "USA",
                  "selectedAnswers": []
              },
              "inputType": "COUNTRY"
          },
          {
              "question": "Do you have any other nationality?",
              "answerDetails": {
                  "singleAnswer": "YES",
                  "selectedAnswers": []
              },
              "inputType": "YESNO"
          },
          {
              "question": "What is the other nationality you have?",
              "answerDetails": {
                  "singleAnswer": "GBR",
                  "selectedAnswers": []
              },
              "inputType": "COUNTRY"
          }
      ]
  }
```
  ### Usage Considerations
  - Ensure that the API key and hardware ID are correctly provided to authenticate and authorize the API request.
  - The endpoint only retrieves data for a specific session as identified by the `interviewId`.
*/}

{/*
# Practical Use Cases

Forms is most useful when identity documents alone don't capture everything you need from a user. A few common scenarios:

1. **Collecting an address when the ID doesn't include one:**
   - **Scenario**: Not all identity documents carry a residential address, but you need one for compliance or downstream processing.
   - **Implementation**: After the ID capture module, use a workflow condition to detect when the extracted ID has no address, and trigger a Form that asks the user to enter it manually.

2. **Collecting a CPF number in Brazil:**
   - **Scenario**: Some Brazilian identity documents don't include the CPF (Cadastro de Pessoas Físicas), which is required for most financial and legal transactions.
   - **Implementation**: When a captured document lacks a CPF, trigger a Form that asks the user to enter it. The value can then be verified against official sources. Learn more about verification with Brazilian system of record [here](https://developer.incode.com/docs/system-of-record-brazil).

3. **Routing users based on citizenship or residency:**
   - **Scenario**: Different countries require different verification documents, and what's needed often depends on whether the user is a citizen or a resident.
   - **Implementation**: Use a Form to ask the user to declare their citizenship and residency status, then add workflow conditions on the response to request the appropriate documents, for example, requiring a residency permit for non-citizens.

4. **Gathering additional information for high-risk users**:
   - **Scenario**: Users flagged as higher-risk through initial checks or external screening often require enhanced due diligence under AML regulations.
   - **Implementation**: When a workflow condition detects a high-risk flag, trigger a Form to collect supplementary information like source of funds or employment details.
*/}

<br />
