Skip to content

Form Template Specification

Form Templates are the basis by which most documents get and validate their payloads.

Form Templates are generic, and not customized per document type. All Specific Document Form Templates have the same capabilities.

JSON Schema

Form Templates are based on JSON Schema version 2020-12. However, JSON Schema is only a validation specification and does not include any details about how such a form should be displayed for data entry.

Form Templates, take standard JSON Schema and extend it in a backwards compatible way so that the Form Template can be interpreted with hints to aid in rendering a form for data capture.

Basic Structure

The Base Form Template has the following format.

Form Template Base Schema
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "maintainers": [
        {
            "name": "Catalyst Team",
            "url": "https://projectcatalyst.io/"
        }
    ],
    "title": "Form Template",
    "description": "Generic Template Schema.",
    "$defs": {
        "dropDownSingleSelect": {
            "contentMediaType": "text/plain",
            "pattern": "^[^\\n]*$",
            "type": "string"
        },
        "multiLineTextEntry": {
            "contentMediaType": "text/plain",
            "pattern": "^[\\S\\s]*$",
            "type": "string"
        },
        "multiLineTextEntryMarkdown": {
            "contentMediaType": "text/markdown",
            "pattern": "^[\\S\\s]*$",
            "type": "string"
        },
        "multiLineTextEntryMarkdownList": {
            "items": {
                "$ref": "#/$defs/multiLineTextEntryMarkdown"
            },
            "type": "array",
            "uniqueItems": true
        },
        "multiSelect": {
            "items": {
                "$ref": "#/$defs/singleSelect"
            },
            "type": "array",
            "uniqueItems": true
        },
        "radioButtonSelect": {
            "contentMediaType": "text/plain",
            "pattern": "^[^\\n]*$",
            "type": "string"
        },
        "section": {
            "additionalProperties": false,
            "type": "object"
        },
        "singleGroupedTagSelector": {
            "additionalProperties": false,
            "required": [
                "group",
                "tag"
            ],
            "type": "object"
        },
        "singleLineHttpsUrlEntry": {
            "contentMediaType": "text/plain",
            "format": "uri",
            "pattern": "^https://[^\\s]+$",
            "type": "string"
        },
        "singleLineHttpsUrlEntryList": {
            "items": {
                "$ref": "#/$defs/singleLineHttpsUrlEntry"
            },
            "type": "array",
            "uniqueItems": true
        },
        "singleLineTextEntry": {
            "contentMediaType": "text/plain",
            "pattern": "^[^\\n]*$",
            "type": "string"
        },
        "singleLineTextEntryList": {
            "items": {
                "$ref": "#/$defs/singleLineTextEntry"
            },
            "type": "array",
            "uniqueItems": true
        },
        "singleSelect": {
            "contentMediaType": "text/plain",
            "pattern": "^[^\\n]*$",
            "type": "string"
        }
    },
    "type": "object",
    "properties": {},
    "additionalProperties": false
}

"$schema"

This defines that the template is a standard JSON Schema version 2020-12 document. Any document derived from the template is only valid if it validates according to JSON Schema validation rules against the template.

"maintainers"

Is a list of the entities who have made or updated the template. It is optional, but if it is included, it MUST be an array of objects. Each object must have two fields:

  • "name" : The name of the individual maintainer or group responsible for the template.
  • "url" : A link where more information about the maintainer or group can be found. If there is no link, the field is still present, but an empty string ("").

"title"

This is a name for the template. It is not used by consumers of the template, but could be used by template builders to help identify the template.

"description"

This is a long multi line description about the template itself. It is not used by consumers of the template, but could be used by template builders to help identify and define the purpose of the template.

There is expected to be a number of templates used in the system, and both "title" and "description" help template builders organize templates.

"$defs"

In JSON Schema the $defs defines reusable definitions. We extend the definition of $defs. Every possible Form Element is defined in $defs. All fields MUST use a pre-defined Form Element from the $defs and it is impermissible for a Form Element to not use a reference to its definition, nor for a definition to be created which does not follow this specification.

In any single Form Template, the $defs section of the Schema MAY only include definitions of Form Elements used by the template itself.

The definitions within the Base Form Template above serve as the dictionary of all available defined Form Elements.

"type": "object"

The Template ONLY supports a json type of Object at the root of the template. It is not permissible to create templates which are bare strings, or numbers, etc.

"properties"

The "properties" section of the form template contains all of the fields to be captured by the form, and each field is defined by its element type.

Form Elements MAY and typically do have Parameters, the possible parameters per Form Element are documented with each Form Elements individual documentation. Parameters are typically standard JSON Schema properties on a type. As not all parameters required are defined by JSON Schema, extended parameters may exist that are prefixed by x-.

Extended Parameters are intended to provide more information related to each Form element, to assist with presentation or using any particular Field. They are not currently associated with validation.

"additionalProperties": false

All Templates must be exhaustively defined. It is not permissible to add fields to a document derived from a Form Template, that are not present in the Form Template itself.

"additionalProperties": false

Example Form Template

This is an Example Form Template which has a property shown for every possible Form Element.

Form Template Example Schema
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "Example",
    "description": "An example of all Elements",
    "$defs": {
        "dropDownSingleSelect": {
            "contentMediaType": "text/plain",
            "pattern": "^[^\\n]*$",
            "type": "string"
        },
        "multiLineTextEntry": {
            "contentMediaType": "text/plain",
            "pattern": "^[\\S\\s]*$",
            "type": "string"
        },
        "multiLineTextEntryMarkdown": {
            "contentMediaType": "text/markdown",
            "pattern": "^[\\S\\s]*$",
            "type": "string"
        },
        "multiLineTextEntryMarkdownList": {
            "items": {
                "$ref": "#/$defs/multiLineTextEntryMarkdown"
            },
            "type": "array",
            "uniqueItems": true
        },
        "multiSelect": {
            "items": {
                "$ref": "#/$defs/singleSelect"
            },
            "type": "array",
            "uniqueItems": true
        },
        "radioButtonSelect": {
            "contentMediaType": "text/plain",
            "pattern": "^[^\\n]*$",
            "type": "string"
        },
        "section": {
            "additionalProperties": false,
            "type": "object"
        },
        "singleGroupedTagSelector": {
            "additionalProperties": false,
            "required": [
                "group",
                "tag"
            ],
            "type": "object"
        },
        "singleLineHttpsUrlEntry": {
            "contentMediaType": "text/plain",
            "format": "uri",
            "pattern": "^https://[^\\s]+$",
            "type": "string"
        },
        "singleLineHttpsUrlEntryList": {
            "items": {
                "$ref": "#/$defs/singleLineHttpsUrlEntry"
            },
            "type": "array",
            "uniqueItems": true
        },
        "singleLineTextEntry": {
            "contentMediaType": "text/plain",
            "pattern": "^[^\\n]*$",
            "type": "string"
        },
        "singleLineTextEntryList": {
            "items": {
                "$ref": "#/$defs/singleLineTextEntry"
            },
            "type": "array",
            "uniqueItems": true
        },
        "singleSelect": {
            "contentMediaType": "text/plain",
            "pattern": "^[^\\n]*$",
            "type": "string"
        }
    },
    "type": "object",
    "properties": {
        "exampleSection": {
            "$ref": "#/$defs/section",
            "properties": {
                "exampleDropDownSingleSelect": {
                    "$ref": "#/$defs/dropDownSingleSelect",
                    "default": "option 1",
                    "description": "Drop Down Single Selector.\nChoose a value from the options presented.",
                    "enum": [
                        "option 1",
                        "option 2",
                        "option 3"
                    ],
                    "title": "Selector",
                    "x-guidance": "It is recommended that a good choice be made.\nA bad choice could effect prospects of success.\nA good choice could improve them.\nSo make a good choice.",
                    "x-icon": "emoji-happy"
                },
                "exampleMultiLineTextEntry": {
                    "$ref": "#/$defs/multiLineTextEntry",
                    "default": "This explanation has not been given.\nIgnore it.",
                    "description": "Explain what it is you want to achieve.",
                    "maxLength": 5000,
                    "minLength": 20,
                    "title": "Explanation",
                    "x-guidance": "It's useful to explain things here.",
                    "x-icon": "academic-cap",
                    "x-placeholder": "What's your explanation?"
                },
                "exampleMultiLineTextEntryMarkdown": {
                    "$ref": "#/$defs/multiLineTextEntryMarkdown",
                    "default": "# My Story\n\nOnce **upon** a *time*...",
                    "description": "Tell a story to the reader.",
                    "maxLength": 5000,
                    "minLength": 20,
                    "title": "Story",
                    "x-guidance": "Engaging stories are better than boring ones.\nTry to be engaging.",
                    "x-icon": "book-open",
                    "x-placeholder": "# ..."
                },
                "exampleMultiLineTextEntryMarkdownList": {
                    "$ref": "#/$defs/multiLineTextEntryMarkdownList",
                    "default": [
                        "# Chapter 1\n\n## The beginning.\n\nOnce upon a time.",
                        "...",
                        "# Chapter 93\n\n## The exciting finale.\n\nMaybe the real treasure was the friends we made along the way.\n\n***The End***\n\n(or is it...)"
                    ],
                    "description": "A set of chapters used to tell your story.",
                    "items": {
                        "default": "# My Story\n\nOnce **upon** a *time*...",
                        "description": "Tell a story to the reader.",
                        "maxLength": 5000,
                        "minLength": 20,
                        "title": "Story",
                        "x-guidance": "Engaging stories are better than boring ones.\nTry to be engaging.",
                        "x-icon": "book-open",
                        "x-placeholder": "# ..."
                    },
                    "maxItems": 100,
                    "minItems": 1,
                    "title": "Chapters",
                    "x-guidance": "Tell us your never-ending story.",
                    "x-icon": "collection",
                    "x-placeholder": "There is a default, so this placeholder won't show."
                },
                "exampleMultiSelect": {
                    "$ref": "#/$defs/multiSelect",
                    "default": [
                        "option1",
                        "option3"
                    ],
                    "description": "Select a few items you prefer.",
                    "items": {
                        "default": "option 1",
                        "description": "Single Selector.\nChoose a value from the options presented.",
                        "enum": [
                            "option 1",
                            "option 2",
                            "option 3"
                        ],
                        "title": "Single Selector",
                        "x-guidance": "It is recommended that a good choice be made.\nA bad choice could effect prospects of success.\nA good choice could improve them.\nSo make a good choice.",
                        "x-icon": "emoji-happy"
                    },
                    "maxItems": 2,
                    "minItems": 2,
                    "title": "Select Items",
                    "x-guidance": "Select two items only, no more, no less.",
                    "x-icon": "cursor-click"
                },
                "exampleRadioButtonSelect": {
                    "$ref": "#/$defs/radioButtonSelect",
                    "default": "Silence",
                    "description": "Choose your favorite radio station.",
                    "enum": [
                        "Hot FM",
                        "AM Stereo (but not really)",
                        "Silence"
                    ],
                    "title": "Radio Selector",
                    "x-guidance": "Video killed the radio star.",
                    "x-icon": "bottom-rail-toggle"
                },
                "exampleSection": {
                    "$ref": "#/$defs/section",
                    "properties": {
                        "exampleDropDownSingleSelect": {
                            "$ref": "#/$defs/dropDownSingleSelect",
                            "default": "option 1",
                            "description": "Drop Down Single Selector.\nChoose a value from the options presented.",
                            "enum": [
                                "option 1",
                                "option 2",
                                "option 3"
                            ],
                            "title": "Selector",
                            "x-guidance": "It is recommended that a good choice be made.\nA bad choice could effect prospects of success.\nA good choice could improve them.\nSo make a good choice.",
                            "x-icon": "emoji-happy"
                        },
                        "exampleMultiLineTextEntry": {
                            "$ref": "#/$defs/multiLineTextEntry",
                            "default": "This explanation has not been given.\nIgnore it.",
                            "description": "Explain what it is you want to achieve.",
                            "maxLength": 5000,
                            "minLength": 20,
                            "title": "Explanation",
                            "x-guidance": "It's useful to explain things here.",
                            "x-icon": "academic-cap",
                            "x-placeholder": "What's your explanation?"
                        },
                        "exampleMultiLineTextEntryMarkdown": {
                            "$ref": "#/$defs/multiLineTextEntryMarkdown",
                            "default": "# My Story\n\nOnce **upon** a *time*...",
                            "description": "Tell a story to the reader.",
                            "maxLength": 5000,
                            "minLength": 20,
                            "title": "Story",
                            "x-guidance": "Engaging stories are better than boring ones.\nTry to be engaging.",
                            "x-icon": "book-open",
                            "x-placeholder": "# ..."
                        },
                        "exampleMultiLineTextEntryMarkdownList": {
                            "$ref": "#/$defs/multiLineTextEntryMarkdownList",
                            "default": [
                                "# Chapter 1\n\n## The beginning.\n\nOnce upon a time.",
                                "...",
                                "# Chapter 93\n\n## The exciting finale.\n\nMaybe the real treasure was the friends we made along the way.\n\n***The End***\n\n(or is it...)"
                            ],
                            "description": "A set of chapters used to tell your story.",
                            "items": {
                                "default": "# My Story\n\nOnce **upon** a *time*...",
                                "description": "Tell a story to the reader.",
                                "maxLength": 5000,
                                "minLength": 20,
                                "title": "Story",
                                "x-guidance": "Engaging stories are better than boring ones.\nTry to be engaging.",
                                "x-icon": "book-open",
                                "x-placeholder": "# ..."
                            },
                            "maxItems": 100,
                            "minItems": 1,
                            "title": "Chapters",
                            "x-guidance": "Tell us your never-ending story.",
                            "x-icon": "collection",
                            "x-placeholder": "There is a default, so this placeholder won't show."
                        },
                        "exampleMultiSelect": {
                            "$ref": "#/$defs/multiSelect",
                            "default": [
                                "option1",
                                "option3"
                            ],
                            "description": "Select a few items you prefer.",
                            "items": {
                                "default": "option 1",
                                "description": "Single Selector.\nChoose a value from the options presented.",
                                "enum": [
                                    "option 1",
                                    "option 2",
                                    "option 3"
                                ],
                                "title": "Single Selector",
                                "x-guidance": "It is recommended that a good choice be made.\nA bad choice could effect prospects of success.\nA good choice could improve them.\nSo make a good choice.",
                                "x-icon": "emoji-happy"
                            },
                            "maxItems": 2,
                            "minItems": 2,
                            "title": "Select Items",
                            "x-guidance": "Select two items only, no more, no less.",
                            "x-icon": "cursor-click"
                        },
                        "exampleRadioButtonSelect": {
                            "$ref": "#/$defs/radioButtonSelect",
                            "default": "Silence",
                            "description": "Choose your favorite radio station.",
                            "enum": [
                                "Hot FM",
                                "AM Stereo (but not really)",
                                "Silence"
                            ],
                            "title": "Radio Selector",
                            "x-guidance": "Video killed the radio star.",
                            "x-icon": "bottom-rail-toggle"
                        },
                        "exampleSingleGroupedTagSelector": {
                            "$ref": "#/$defs/singleGroupedTagSelector",
                            "properties": {}
                        },
                        "exampleSingleLineHttpsUrlEntry": {
                            "$ref": "#/$defs/singleLineHttpsUrlEntry",
                            "description": "Whats your companies primary URL.",
                            "maxLength": 1024,
                            "minLength": 12,
                            "title": "Website",
                            "x-guidance": "Its where people find your company online.",
                            "x-icon": "globe-alt",
                            "x-placeholder": "https://<your website>"
                        },
                        "exampleSingleLineHttpsUrlEntryList": {
                            "$ref": "#/$defs/singleLineHttpsUrlEntryList",
                            "description": "All the development domains used by your project.",
                            "maxItems": 10,
                            "minItems": 0,
                            "title": "Development Domains",
                            "x-guidance": "Don't list production domains.",
                            "x-icon": "dots-vertical",
                            "x-placeholder": [
                                "Url 1",
                                "Url 2",
                                "Url 3"
                            ]
                        },
                        "exampleSingleLineTextEntry": {
                            "$ref": "#/$defs/singleLineTextEntry",
                            "default": "Rocket",
                            "description": "Whats your first name.",
                            "maxLength": 300,
                            "minLength": 2,
                            "title": "First Name",
                            "x-guidance": "Its the thing your parents called you.",
                            "x-icon": "user",
                            "x-placeholder": "???"
                        },
                        "exampleSingleLineTextEntryList": {
                            "$ref": "#/$defs/singleLineTextEntryList",
                            "default": [
                                "Me",
                                "You",
                                "Hey"
                            ],
                            "description": "All your nicknames.",
                            "maxItems": 17,
                            "minItems": 2,
                            "title": "Nicknames",
                            "x-guidance": "All the nicknames people have used to refer to you.\nMake some up if you have less than 2.",
                            "x-icon": "clipboard-list",
                            "x-placeholder": [
                                "nickname1",
                                "nickname2"
                            ]
                        },
                        "exampleSingleSelect": {
                            "$ref": "#/$defs/singleSelect",
                            "default": "option 1",
                            "description": "Single Selector.\nChoose a value from the options presented.",
                            "enum": [
                                "option 1",
                                "option 2",
                                "option 3"
                            ],
                            "title": "Single Selector",
                            "x-guidance": "It is recommended that a good choice be made.\nA bad choice could effect prospects of success.\nA good choice could improve them.\nSo make a good choice.",
                            "x-icon": "emoji-happy"
                        }
                    },
                    "x-flatten": false,
                    "x-icon": "bookmark"
                },
                "exampleSingleGroupedTagSelector": {
                    "$ref": "#/$defs/singleGroupedTagSelector",
                    "properties": {}
                },
                "exampleSingleLineHttpsUrlEntry": {
                    "$ref": "#/$defs/singleLineHttpsUrlEntry",
                    "description": "Whats your companies primary URL.",
                    "maxLength": 1024,
                    "minLength": 12,
                    "title": "Website",
                    "x-guidance": "Its where people find your company online.",
                    "x-icon": "globe-alt",
                    "x-placeholder": "https://<your website>"
                },
                "exampleSingleLineHttpsUrlEntryList": {
                    "$ref": "#/$defs/singleLineHttpsUrlEntryList",
                    "description": "All the development domains used by your project.",
                    "maxItems": 10,
                    "minItems": 0,
                    "title": "Development Domains",
                    "x-guidance": "Don't list production domains.",
                    "x-icon": "dots-vertical",
                    "x-placeholder": [
                        "Url 1",
                        "Url 2",
                        "Url 3"
                    ]
                },
                "exampleSingleLineTextEntry": {
                    "$ref": "#/$defs/singleLineTextEntry",
                    "default": "Rocket",
                    "description": "Whats your first name.",
                    "maxLength": 300,
                    "minLength": 2,
                    "title": "First Name",
                    "x-guidance": "Its the thing your parents called you.",
                    "x-icon": "user",
                    "x-placeholder": "???"
                },
                "exampleSingleLineTextEntryList": {
                    "$ref": "#/$defs/singleLineTextEntryList",
                    "default": [
                        "Me",
                        "You",
                        "Hey"
                    ],
                    "description": "All your nicknames.",
                    "maxItems": 17,
                    "minItems": 2,
                    "title": "Nicknames",
                    "x-guidance": "All the nicknames people have used to refer to you.\nMake some up if you have less than 2.",
                    "x-icon": "clipboard-list",
                    "x-placeholder": [
                        "nickname1",
                        "nickname2"
                    ]
                },
                "exampleSingleSelect": {
                    "$ref": "#/$defs/singleSelect",
                    "default": "option 1",
                    "description": "Single Selector.\nChoose a value from the options presented.",
                    "enum": [
                        "option 1",
                        "option 2",
                        "option 3"
                    ],
                    "title": "Single Selector",
                    "x-guidance": "It is recommended that a good choice be made.\nA bad choice could effect prospects of success.\nA good choice could improve them.\nSo make a good choice.",
                    "x-icon": "emoji-happy"
                }
            },
            "x-flatten": false,
            "x-icon": "bookmark"
        }
    },
    "additionalProperties": false
}

Dictionary of all defined Form Elements

Name Element
Drop Down Single Select dropDownSingleSelect
Multi Line Text Entry multiLineTextEntry
Multi Line Text Entry Markdown multiLineTextEntryMarkdown
Multi Line Text Entry Markdown List multiLineTextEntryMarkdownList
Multi Select multiSelect
Radio Button Select radioButtonSelect
Section section
Single Grouped Tag Selector singleGroupedTagSelector
Single Line Https Url Entry singleLineHttpsUrlEntry
Single Line Https Url Entry List singleLineHttpsUrlEntryList
Single Line Text Entry singleLineTextEntry
Single Line Text Entry List singleLineTextEntryList
Single Select singleSelect

Assets

Form Templates may make use of the following sets of known assets.

Icons

Defined Icons
All icon Names that may be referenced by Form Elements.
Name Icon Image
academic-cap
ada
adjustments
all-spaces-menu
all-spaces-menu-1
annotation
archive
arrow-down
arrow-left
arrow-right
arrow-up
arrow-circle-down
arrow-circle-left
arrow-circle-right
arrow-circle-up
arrow-narrow-down
arrow-narrow-left
arrow-narrow-right
arrow-narrow-up
arrow-triangle-down
arrow-triangle-up
arrows-expand
at-symbol
avatar-placeholder
backspace
badge-check
ban
beaker
bell
book-open
bookmark
bookmark-alt
bottom-main-content
bottom-rail-toggle
briefcase
cake
calculator
calendar
camera
cash
chart-bar
chart-pie
chart-square-bar
chat
chat-alt
chat-alt-2
check
check-circle
chevron-down
chevron-left
chevron-right
chevron-up
chevron-double-down
chevron-double-left
chevron-double-right
chevron-double-up
chip
clipboard
clipboard-check
clipboard-copy
clipboard-list
clock
cloud
cloud-download
cloud-upload
code
cog-gear
collection
color-swatch
credit-card
cube
cube-transparent
currency-bangladeshi
currency-dollar
currency-euro
currency-pound
currency-rupee
currency-yen
cursor-click
curved-arrow-right
database
desktop-computer
device-mobile
device-tablet
document
document-add
document-remove
document-report
document-search
document-text
dots-horizontal
dots-vertical
dots-circle-horizontal
double-check
download
duplicate
emoji-happy
emoji-sad
exclamation
exclamation-circle
external-link
eye
eye-off
facebook
fast-forward
film
filter
finger-print
fire
flag
folder
folder-add
folder-download
folder-open
folder-remove
fund
gift
globe
globe-alt
hand
hashtag
heart
home
icon-user-remove
identification
inbox
inbox-in
information-circle
key
left-rail-toggle
library
light-bulb
lightning-bolt
link
linkedin
location-marker
lock-closed
lock-open
login
logout
mail
mail-open
map
maximize-toggle
menu
menu-alt-1
menu-alt-2
menu-alt-3
menu-alt-4
microphone
minimize-toggle
minus
minus-circle
moon
move-item
music-note
newspaper
node-closed
node-line
node-open
node-line-end
office-building
paper-airplane
paper-clip
pause
pencil
pencil-alt
phone
phone-incoming
phone-outgoing
phone-missed-call
photograph
play
plus
plus-circle-filled
plus-circle-outlined
presentation-chart-bar
presentation-chart-line
printer
progress-track-warning
puzzle
qrcode
question-mark-circle
receipt-refund
receipt-tax
reddit
refresh
reply
rewind
right-rail-toggle
rss
rt-bold
rt-heading
rt-italic
rt-decrease-indent
rt-increase-indent
rt-ordered-list
rt-unordered-list
save
save-as
scale
scissors
search
search-circle
selector
send-airplane
server
share
shield-check
shield-exclamation
shopping-bag
shopping-cart
sm-view-grid-add
sort-ascending
sort-descending
sparkles
speakerphone
star-filled
star-outlined
status-offline
status-online
stop
summary
sun
support
switch-horizontal
switch-vertical
table
tag
template
terminal
thumb-down
thumb-up
ticket
top-bar
top-bar-filled
translate
trash
trending-down
trending-up
truck
unlink
upload
user
user-add
user-circle
user-group
users
variable
video-camera
view-boards
view-grid
view-list
volume-off
volume-up
vote
wallet
wifi
x
x-circle
x-twitter
zoom-in
zoom-out
Icon images are representative and may be customized by implementations.