Skip to main content

Overview

The Custom Form Component enables the creation of interactive and dynamic forms within a QR Code landing page.
Each form consists of a title, description, and a configurable array of questions.
Questions support various input types — from short text to file uploads — allowing developers to capture structured user responses.
This schema also includes optional formatting references for customizing the visual presentation of form elements.

Properties

PropertyTypeRequiredDescription
titlestringNoTitle of the form. Shown at the top of the form interface.
descriptionstringNoA short description or subtitle to explain the form purpose.
questionsarray<object>✅ YesArray of question objects. Each defines the question, type, and validation rules. Maximum 40 questions.
formattingobjectNoDefines style and layout formatting for form elements.

Formatting Object

Sub-propertyTypeReferenceDescription
textStyleobjectText StyleControls font size, weight, and color of form text.
cardStyleobjectCard StyleDefines container style for each question card.
iconStyleobjectIcon StyleManages icon appearance for interactive form elements.

Question Structure

Each item inside the questions array represents a single question block with the following structure:
PropertyTypeRequiredDescription
questionstring✅ YesThe question text (3–200 characters).
questionDescriptionstringNoOptional helper text below the question (max 300 characters).
privacyNotestringNoPrivacy or consent note related to the question (max 300 characters).
answerobject✅ YesDefines the input type and configuration for the answer.
isRequiredbooleanNoIndicates if the question must be answered before submission (default: false).

Answer Object

FieldTypeRequiredDescription
typestring✅ YesDefines the input type (e.g., shortAnswer, multipleChoice, uploadFile).
dataobject / array / stringConditionalProvides configuration data for the selected input type. Reference to form_input.json.
Supported type values:
shortAnswer, paragraph, multipleChoice, checkbox, dropdown,
linearScale, dateFormat, timeFormat, email, phoneNumber,
starRating, emoji, likeDislike, uploadFile, signature

Conditional References (by Input Type)

Input TypeData Schema Reference
multipleChoice, checkboxform_input.json#/properties/multipleOptions
linearScaleform_input.json#/properties/linearScale
dateFormatform_input.json#/properties/dateFormat
timeFormatform_input.json#/properties/timeFormat
starRating, emoji, likeDislikeform_input.json#/properties/feedback
uploadFileform_input.json#/properties/uploadFile
signatureform_input.json#/properties/signature

Validation Rules

FieldConstraintExample
title0–100 characters"title": "Customer Feedback Form"
description2–500 characters"description": "Please share your experience with us."
questionsMax 40 items"questions": [ { ... } ]
question3–200 characters"question": "What is your name?"
answer.typeMust be a supported type"type": "shortAnswer"

Example Schema

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {},
  "title": "Custom Form Component",
  "type": "object",
  "required": [
    "questions"
  ],
  "properties": {
    "title": {
      "type": "string",
      "minLength": 0,
      "maxLength": 100,
      "description": "Form title"
    },
    "description": {
      "type": "string",
      "minLength": 2,
      "maxLength": 500,
      "description": "Form description"
    },
    "questions": {
      "type": "array",
      "maxItems": 40,
      "additionalProperties": false,
      "description": "Question block component",
      "$comment": "Allow upto 20 questions.",
      "items": {
        "type": "object",
        "required": [
          "question",
          "answer"
        ],
        "additionalProperties": false,
        "minProperties": 1,
        "properties": {
          "question": {
            "type": "string",
            "maxLength": 200,
            "minLength": 3
          },
          "questionDescription": {
            "type": "string",
            "maxLength": 300
          },
          "privacyNote": {
            "type": "string",
            "maxLength": 300
          },
          "answer": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "type"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "shortAnswer",
                  "paragraph",
                  "multipleChoice",
                  "checkbox",
                  "dropdown",
                  "linearScale",
                  "dateFormat",
                  "timeFormat",
                  "email",
                  "phoneNumber",
                  "starRating",
                  "emoji",
                  "likeDislike",
                  "uploadFile",
                  "signature"
                ]
              },
              "data": {
                "type": [
                  "string",
                  "object",
                  "array"
                ]
              }
            },
            "allOf": [
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "multipleChoice"
                    }
                  }
                },
                "then": {
                  "properties": {
                    "data": {
                      "$ref": "form_input.json#/properties/multipleOptions"
                    }
                  }
                }
              },
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "checkbox"
                    }
                  }
                },
                "then": {
                  "properties": {
                    "data": {
                      "$ref": "form_input.json#/properties/multipleOptions"
                    }
                  }
                }
              },
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "linearScale"
                    }
                  }
                },
                "then": {
                  "properties": {
                    "data": {
                      "$ref": "form_input.json#/properties/linearScale"
                    }
                  }
                }
              },
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "dateFormat"
                    }
                  }
                },
                "then": {
                  "properties": {
                    "data": {
                      "$ref": "form_input.json#/properties/dateFormat"
                    }
                  }
                }
              },
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "timeFormat"
                    }
                  }
                },
                "then": {
                  "properties": {
                    "data": {
                      "$ref": "form_input.json#/properties/timeFormat"
                    }
                  }
                }
              },
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "starRating"
                    }
                  }
                },
                "then": {
                  "properties": {
                    "data": {
                      "$ref": "form_input.json#/properties/feedback"
                    }
                  }
                }
              },
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "emoji"
                    }
                  }
                },
                "then": {
                  "properties": {
                    "data": {
                      "$ref": "form_input.json#/properties/feedback"
                    }
                  }
                }
              },
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "likeDislike"
                    }
                  }
                },
                "then": {
                  "properties": {
                    "data": {
                      "$ref": "form_input.json#/properties/feedback"
                    }
                  }
                }
              },
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "uploadFile"
                    }
                  }
                },
                "then": {
                  "properties": {
                    "data": {
                      "$ref": "form_input.json#/properties/uploadFile"
                    }
                  }
                }
              },
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "signature"
                    }
                  }
                },
                "then": {
                  "properties": {
                    "data": {
                      "$ref": "form_input.json#/properties/signature"
                    }
                  }
                }
              }
            ]
          },
          "isRequired": {
            "type": "boolean",
            "default": false
          }
        }
      }
    },
    "formatting": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "textStyle": {
          "$ref": "style/text.json"
        },
        "cardStyle": {
          "$ref": "style/card.json"
        },
        "iconStyle": {
          "$ref": "style/icon.json"
        }
      }
    }
  }
}

Notes

  • Each form can contain up to 40 questions.
  • Each question must have both a question text and an answer object.
  • Conditional schemas ensure validation consistency depending on answer.type.
  • Formatting components reference the shared style library, ensuring consistent design across forms.