Developers
Form definition reference
The JSON format for sections, subsections, questions, conditions and approval rules.
A form definition has two parts: the schema (what respondents see) and approval (how responses are scored).
{
"schema": {
"sections": [
{
"id": "about",
"title": "About you",
"required": true,
"elements": [
{ "kind": "item", "id": "email", "type": "email", "label": "Email", "required": true },
{ "kind": "item", "id": "age", "type": "number", "label": "Age", "integer": true, "min": 16 },
{
"kind": "subsection", "id": "refs", "title": "References", "required": false,
"repeat": { "min": 1, "max": 3, "add_label": "Add a reference" },
"items": [
{ "kind": "item", "id": "ref_name", "type": "short_text", "label": "Name", "required": true }
]
}
]
}
]
},
"approval": {
"enabled": true,
"threshold_type": "percent",
"threshold": 60,
"show_result": true,
"show_score": false,
"criteria": [
{ "id": "adult", "item_id": "age", "op": "gte", "value": 18, "points": 1, "required": true }
]
}
}
Sections
| Field | Type | Notes |
|---|---|---|
id | string | Unique in the form. ^[A-Za-z][A-Za-z0-9_]{0,63}$ |
title, description | string | Optional |
required | bool | Default true |
repeat | object | { "min": 1, "max": 10, "add_label": "…" } |
condition | object | See below |
elements | array | Items ("kind": "item") and subsections ("kind": "subsection") |
Subsections
Same fields as sections, with items instead of elements.
Items (questions)
Common fields: id, type, label, description, placeholder, required, repeat, condition.
type | Extra fields |
|---|---|
short_text, long_text | min_length, max_length, pattern, pattern_message |
email, url, phone | — |
number | min, max, step, integer |
rating | max (3–10) |
scale | min (0–1), max (2–10), min_label, max_label |
date, time, datetime | min_date, max_date |
single_choice, dropdown | options: [{ "value", "label" }], allow_other |
multi_choice | options, allow_other, min_selections, max_selections |
yes_no, consent | — |
file | accept (extensions or groups), max_files (1–20), max_file_size_mb |
hidden | default_value |
statement | display only |
Fields that don’t apply to a type are removed when saved.
Conditions
{ "logic": "all", "rules": [{ "field": "authorized", "op": "equals", "value": false }] }
logic:all(AND) orany(OR).op:equals,not_equals,contains,not_contains,gt,gte,lt,lte,between([min, max]),in/not_in(list),is_empty,is_not_empty.fieldmust be an earlier question in the same or an enclosing repeat scope.
Approval
| Field | Notes |
|---|---|
enabled | Pro plan |
criteria[] | id, item_id, op, value, points (0–1000, default 1), required (must-have), match_mode (any/all for repeated answers), label |
threshold_type | percent or points |
threshold | Minimum to approve |
show_result, show_score | What respondents see after submitting |
approved_message, rejected_message | Custom messages |
Answer format
Answers are keyed by question id. Repeatable sections/subsections become arrays of objects, repeatable questions arrays of values. See Repeatable sections.
| Type | Value |
|---|---|
| text, email, url, phone, date, time, datetime, single choice, dropdown, hidden | string |
| number, rating, scale | number |
| yes_no, consent | boolean |
| multi_choice | array of strings |
| file | array of upload references (see Public forms) |